Jump to content

Ocean shader


Josh
 Share

Recommended Posts

Just something I copied from ShaderToy. Use it as a post-processing shader:

 

vert:

#version 400

 

uniform mat4 projectionmatrix;

uniform mat4 drawmatrix;

uniform vec2 offset;

uniform vec2 position[4];

 

in vec3 vertex_position;

 

void main(void)

{

gl_Position = projectionmatrix * (drawmatrix * vec4(position[gl_VertexID]+offset, 0.0, 1.0));

}

 

frag

// "Seascape" by Alexander Alekseev aka TDM - 2014

// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.

 

#version 400

 

uniform vec2 buffersize;

uniform float currenttime;

uniform bool isbackbuffer;

 

const int NUM_STEPS = 8;

const float PI = 3.1415;

const float EPSILON = 1e-3;

float EPSILON_NRM = 0.1 / buffersize.x;

 

// sea

const int ITER_GEOMETRY = 3;

const int ITER_FRAGMENT = 5;

const float SEA_HEIGHT = 0.6;

const float SEA_CHOPPY = 4.0;

const float SEA_SPEED = 0.8;

const float SEA_FREQ = 0.16;

const vec3 SEA_BASE = vec3(0.1,0.19,0.22);

const vec3 SEA_WATER_COLOR = vec3(0.8,0.9,0.6);

float SEA_TIME = currenttime/1000.0 * SEA_SPEED;

mat2 octave_m = mat2(1.6,1.2,-1.2,1.6);

 

out vec4 fragData0;

 

// math

mat3 fromEuler(vec3 ang) {

vec2 a1 = vec2(sin(ang.x),cos(ang.x));

vec2 a2 = vec2(sin(ang.y),cos(ang.y));

vec2 a3 = vec2(sin(ang.z),cos(ang.z));

mat3 m;

m[0] = vec3(a1.y*a3.y+a1.x*a2.x*a3.x,a1.y*a2.x*a3.x+a3.y*a1.x,-a2.y*a3.x);

m[1] = vec3(-a2.y*a1.x,a1.y*a2.y,a2.x);

m[2] = vec3(a3.y*a1.x*a2.x+a1.y*a3.x,a1.x*a3.x-a1.y*a3.y*a2.x,a2.y*a3.y);

return m;

}

float hash( vec2 p ) {

float h = dot(p,vec2(127.1,311.7));

return fract(sin(h)*43758.5453123);

}

float noise( in vec2 p ) {

vec2 i = floor( p );

vec2 f = fract( p );

vec2 u = f*f*(3.0-2.0*f);

return -1.0+2.0*mix( mix( hash( i + vec2(0.0,0.0) ),

hash( i + vec2(1.0,0.0) ), u.x),

mix( hash( i + vec2(0.0,1.0) ),

hash( i + vec2(1.0,1.0) ), u.x), u.y);

}

 

// lighting

float diffuse(vec3 n,vec3 l,float p) {

return pow(dot(n,l) * 0.4 + 0.6,p);

}

float specular(vec3 n,vec3 l,vec3 e,float s) {

float nrm = (s + 8.0) / (3.1415 * 8.0);

return pow(max(dot(reflect(e,n),l),0.0),s) * nrm;

}

 

// sky

vec3 getSkyColor(vec3 e) {

e.y = max(e.y,0.0);

vec3 ret;

ret.x = pow(1.0-e.y,2.0);

ret.y = 1.0-e.y;

ret.z = 0.6+(1.0-e.y)*0.4;

return ret;

}

 

// sea

float sea_octave(vec2 uv, float choppy) {

uv += noise(uv);

vec2 wv = 1.0-abs(sin(uv));

vec2 swv = abs(cos(uv));

wv = mix(wv,swv,wv);

return pow(1.0-pow(wv.x * wv.y,0.65),choppy);

}

 

float map(vec3 p) {

float freq = SEA_FREQ;

float amp = SEA_HEIGHT;

float choppy = SEA_CHOPPY;

vec2 uv = p.xz; uv.x *= 0.75;

 

float d, h = 0.0;

for(int i = 0; i < ITER_GEOMETRY; i++) {

d = sea_octave((uv+SEA_TIME)*freq,choppy);

d += sea_octave((uv-SEA_TIME)*freq,choppy);

h += d * amp;

uv *= octave_m; freq *= 1.9; amp *= 0.22;

choppy = mix(choppy,1.0,0.2);

}

return p.y - h;

}

 

float map_detailed(vec3 p) {

float freq = SEA_FREQ;

float amp = SEA_HEIGHT;

float choppy = SEA_CHOPPY;

vec2 uv = p.xz; uv.x *= 0.75;

 

float d, h = 0.0;

for(int i = 0; i < ITER_FRAGMENT; i++) {

d = sea_octave((uv+SEA_TIME)*freq,choppy);

d += sea_octave((uv-SEA_TIME)*freq,choppy);

h += d * amp;

uv *= octave_m; freq *= 1.9; amp *= 0.22;

choppy = mix(choppy,1.0,0.2);

}

return p.y - h;

}

 

vec3 getSeaColor(vec3 p, vec3 n, vec3 l, vec3 eye, vec3 dist) {

float fresnel = 1.0 - max(dot(n,-eye),0.0);

fresnel = pow(fresnel,3.0) * 0.65;

 

vec3 reflected = getSkyColor(reflect(eye,n));

vec3 refracted = SEA_BASE + diffuse(n,l,80.0) * SEA_WATER_COLOR * 0.12;

 

vec3 color = mix(refracted,reflected,fresnel);

 

float atten = max(1.0 - dot(dist,dist) * 0.001, 0.0);

color += SEA_WATER_COLOR * (p.y - SEA_HEIGHT) * 0.18 * atten;

 

color += vec3(specular(n,l,eye,60.0));

 

return color;

}

 

// tracing

vec3 getNormal(vec3 p, float eps) {

vec3 n;

n.y = map_detailed(p);

n.x = map_detailed(vec3(p.x+eps,p.y,p.z)) - n.y;

n.z = map_detailed(vec3(p.x,p.y,p.z+eps)) - n.y;

n.y = eps;

return normalize(n);

}

 

float heightMapTracing(vec3 ori, vec3 dir, out vec3 p) {

float tm = 0.0;

float tx = 1000.0;

float hx = map(ori + dir * tx);

if(hx > 0.0) return tx;

float hm = map(ori + dir * tm);

float tmid = 0.0;

for(int i = 0; i < NUM_STEPS; i++) {

tmid = mix(tm,tx, hm/(hm-hx));

p = ori + dir * tmid;

float hmid = map(p);

if(hmid < 0.0) {

tx = tmid;

hx = hmid;

} else {

tm = tmid;

hm = hmid;

}

}

return tmid;

}

 

// main

void main(void)

{

vec2 uv = gl_FragCoord.xy / buffersize.xy;

 

if (!isbackbuffer) uv.y = 1.0f - uv.y;

 

uv = uv * 2.0 - 1.0;

uv.x *= buffersize.x / buffersize.y;

float time = currenttime/1000.0 * 0.3;// + iMouse.x*0.01;

 

// ray

vec3 ang = vec3(0);//sin(time*3.0)*0.1,sin(time)*0.2+0.3,time);

vec3 ori = vec3(0.0,3.5,time*5.0);

vec3 dir = normalize(vec3(uv.xy,-2.0)); dir.z += length(uv) * 0.15;

dir = normalize(dir) * fromEuler(ang);

 

// tracing

vec3 p;

heightMapTracing(ori,dir,p);

vec3 dist = p - ori;

vec3 n = getNormal(p, dot(dist,dist) * EPSILON_NRM);

vec3 light = normalize(vec3(0.0,1.0,0.8));

 

// color

vec3 color = mix(

getSkyColor(dir),

getSeaColor(p,n,light,dir,dist),

pow(smoothstep(0.0,-0.05,dir.y),0.3));

 

// post

fragData0 = vec4(pow(color,vec3(0.75)), 1.0);

}

post-1-0-78872200-1436477475_thumb.jpg

  • Upvote 5

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

I took a leaf out of this book and tried a flame shader and to my surprise I managed to get it in...

 

https://www.shadertoy.com/view/XsXSWS

 

post-5086-0-62460900-1436568706_thumb.png

 

I created a material using that shader and assigned it to a billboard which works great. Only thing is the flame is pointing upside down and can't work out why? Any Ideas?

 

 

Vert

#version 400
#define MAX_INSTANCES 256
//Uniforms
//uniform mat4 entitymatrix;
uniform vec4 materialcolordiffuse;
uniform mat4 projectioncameramatrix;
uniform mat4 camerainversematrix;
uniform instancematrices { mat4 matrix[MAX_INSTANCES];} entity;
uniform vec4 clipplane0 = vec4(0.0);
//Attributes
in vec3 vertex_position;
in vec4 vertex_color;
in vec2 vertex_texcoords0;
in vec3 vertex_normal;
in vec3 vertex_binormal;
in vec3 vertex_tangent;
//Outputs
out vec4 ex_color;
out vec2 ex_texcoords0;
out float ex_selectionstate;
out vec3 ex_VertexCameraPosition;
out vec3 ex_normal;
out vec3 ex_tangent;
out vec3 ex_binormal;
out float clipdistance0;
void main()
{
mat4 entitymatrix = entity.matrix[gl_InstanceID];
mat4 entitymatrix_=entitymatrix;
entitymatrix_[0][3]=0.0;
entitymatrix_[1][3]=0.0;
entitymatrix_[2][3]=0.0;
entitymatrix_[3][3]=1.0;

vec4 modelvertexposition = entitymatrix_ * vec4(vertex_position,1.0);

//Clip planes
if (length(clipplane0.xyz)>0.0001)
{
clipdistance0 = modelvertexposition.x*clipplane0.x + modelvertexposition.y*clipplane0.y + modelvertexposition.z*clipplane0.z + clipplane0.w;
}
else
{
clipdistance0 = 0.0;
}

ex_VertexCameraPosition = vec3(camerainversematrix * modelvertexposition);
gl_Position = projectioncameramatrix * modelvertexposition;
mat3 nmat = mat3(camerainversematrix);//[0].xyz,camerainversematrix[1].xyz,camerainversematrix[2].xyz);//39
nmat = nmat * mat3(entitymatrix[0].xyz,entitymatrix[1].xyz,entitymatrix[2].xyz);//40
ex_normal = normalize(nmat * vertex_normal);
ex_tangent = normalize(nmat * vertex_tangent);
ex_binormal = normalize(nmat * vertex_binormal);

ex_texcoords0 = vertex_texcoords0;

ex_color = vec4(entitymatrix[0][3],entitymatrix[1][3],entitymatrix[2][3],entitymatrix[3][3]);

//If an object is selected, 10 is subtracted from the alpha color.
//This is a bit of a hack that packs a per-object boolean into the alpha value.
ex_selectionstate = 0.0;
if (ex_color.a<-5.0)
{
ex_color.a += 10.0;
ex_selectionstate = 1.0;
}

ex_color *= vec4(1.0-vertex_color.r,1.0-vertex_color.g,1.0-vertex_color.b,vertex_color.a) * materialcolordiffuse;
}

 

 

Frag

#version 400
#define BFN_ENABLED 1
uniform vec2 buffersize;
uniform float currenttime;
//Uniforms
uniform sampler2D texture0;//diffuse map
uniform samplerCube texture15;//BFN map
uniform vec4 materialcolorspecular;
uniform vec4 lighting_ambient;
uniform float FLAME_SPEED = 2.0;
uniform float flame_strength = 1.0;
uniform float flame_length = .75;
//Lighting
uniform vec3 lightdirection[4];
uniform vec4 lightcolor[4];
uniform vec4 lightposition[4];
uniform float lightrange[4];
uniform vec3 lightingcenter[4];
uniform vec2 lightingconeanglescos[4];
uniform vec4 lightspecular[4];
uniform vec4 clipplane0 = vec4(0.0);
//Inputs
in vec2 ex_texcoords0;
in vec4 ex_color;
in float ex_selectionstate;
in vec3 ex_VertexCameraPosition;
in vec3 ex_normal;
in vec3 ex_tangent;
in vec3 ex_binormal;
in float clipdistance0;
out vec4 fragData0;
out vec4 fragData1;
out vec4 fragData2;
out vec4 fragData3;

// procedural noise from IQ
vec2 hash( vec2 p )
{
p = vec2( dot(p,vec2(127.1,311.7)),
dot(p,vec2(269.5,183.3)) );
return -1.0 + 2.0*fract(sin(p)*43758.5453123);
}
float noise( in vec2 p )
{
const float K1 = (sqrt(3)-1)/2;
const float K2 = (3-sqrt(3))/6;

vec2 i = floor( p + (p.x+p.y)*K1 );

vec2 a = p - i + (i.x+i.y)*K2;
vec2 o = (a.x>a.y) ? vec2(1.0,0.0) : vec2(0.0,1.0);
vec2 b = a - o + K2;
vec2 c = a - 1.0 + 2.0*K2;

vec3 h = max( 0.5-vec3(dot(a,a), dot(b,b), dot(c,c) ), 0.0 );

vec3 n = h*h*h*h*vec3( dot(a,hash(i+0.0)), dot(b,hash(i+o)), dot(c,hash(i+1.0)));

return dot( n, vec3(70.0) );
}
float fbm(vec2 uv)
{
float f;
mat2 m = mat2( 1.6, 1.2, -1.2, 1.6 );
f = 0.5000*noise( uv ); uv = m*uv;
f += 0.2500*noise( uv ); uv = m*uv;
f += 0.1250*noise( uv ); uv = m*uv;
f += 0.0625*noise( uv ); uv = m*uv;
f = 0.5 + 0.5*f;
return f;
}
// no defines, standard redish flames
//#define BLUE_FLAME
//#define GREEN_FLAME
void main(void)
{
//Clip plane discard
if (clipdistance0>0.0) discard;

vec4 outcolor = ex_color;
vec4 color_specular = materialcolorspecular;
vec3 normal = ex_normal;
vec2 uv = ex_texcoords0;

vec2 q = uv;
q.x *= 5.;
q.y *= 2.;
float strength = floor(q.x+1.3);
float T3 = currenttime/1000.0 * FLAME_SPEED;
q.x = mod(q.x,1.)-0.5;
q.y -= 0.25;
float n = fbm(strength*q - vec2(0,T3));
float c = 1. - 16. * pow( max( 0., length(q*vec2(1.8+q.y*1.5,.75) ) - n * max( 0., q.y+.25 ) ),1.2 );
// float c1 = n * c * (1.5-pow(1.25*uv.y,4.));
float c1 = n * c * (1.5-pow(2.50*uv.y,4.));
c1=clamp(c1,0.,1.);
vec3 col = vec3(1.5*c1, 1.5*c1*c1*c1, c1*c1*c1*c1*c1*c1);
#ifdef BLUE_FLAME
col = col.zyx;
#endif
#ifdef GREEN_FLAME
col = 0.85*col.yxz;
#endif

float a = c * (1.-pow(uv.y,0.9));
//fragColor = vec4( mix(vec3(0.),col,a), 1.0);

if (a < 0.4) discard;
//Modulate blend with diffuse map
outcolor *= vec4( mix(vec3(0.0, 0.0, 0.0),col,a), a);

//Blend with selection color if selected
fragData0 = outcolor;// * (1.0-ex_selectionstate) + ex_selectionstate * (outcolor*0.5+vec4(0.5,0.0,0.0,0.0));


#if BFN_ENABLED==1
//Best-fit normals
fragData1 = texture(texture15,normalize(vec3(normal.x,-normal.y,normal.z)));
fragData1.a = fragData0.a;
#else
//Low-res normals
fragData1 = vec4(normalize(normal)*0.5+0.5,fragData0.a);
#endif
fragData1.a = materialcolorspecular.r * 0.299 + materialcolorspecular.g * 0.587 + materialcolorspecular.b * 0.114;
int materialflags=1;
if (ex_selectionstate>0.0) materialflags += 2;


fragData2 = vec4(0.0,0.0,0.0,materialflags/255.0);
}

 

You can get a single flame by playing with these values:

q.x *= 5.;

q.y *= 2.;

  • Upvote 1
trindieprod.png?dl=0spacer.png?dl=0steam-icon.png?dl=0twitter-icon.png?dl=0spacer.png?dl=0
Link to comment
Share on other sites

  • 1 year later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...