From db50149497f3b9fb969a187a721ff4f49c6243b9 Mon Sep 17 00:00:00 2001 From: "gral@who.net" Date: Fri, 3 Sep 2010 23:51:43 +0200 Subject: [PATCH] New water effect, first steps --- Effects/water.eff | 124 ++++++++++++++++++++++++++++++++++++-- Shaders/water.frag | 145 +++++++++++++++++++++++---------------------- Shaders/water.vert | 55 +++++++++++++---- 3 files changed, 237 insertions(+), 87 deletions(-) diff --git a/Effects/water.eff b/Effects/water.eff index 171ec5c3c..73d2600ac 100644 --- a/Effects/water.eff +++ b/Effects/water.eff @@ -2,6 +2,43 @@ Effects/water Effects/terrain-default + + + Textures/Water/water-reflection.png + linear-mipmap-linear + repeat + repeat + normalized + + + Textures/Water/water-refraction.png + linear-mipmap-linear + repeat + repeat + normalized + + + Textures/Water/water-normalmap.png + linear-mipmap-linear + repeat + repeat + normalized + + + Textures/Water/water-dudv.png + linear-mipmap-linear + repeat + repeat + normalized + + + Textures/Water/water-depth.png + linear-mipmap-linear + repeat + repeat + normalized + + @@ -14,7 +51,7 @@ GL_ARB_shader_objects - GL_ARB_shading_language_100 + GL_ARB_shading_language_120 GL_ARB_vertex_shader GL_ARB_fragment_shader @@ -37,18 +74,93 @@ render-bin/bin-number render-bin/bin-name - + 0 - noise + texture[0]/image + texture[0]/filter + texture[0]/wrap-s + texture[0]/wrap-t + + texture[0]/internal-format + + + + 1 + texture[1]/image + texture[1]/filter + texture[1]/wrap-s + texture[1]/wrap-t + + texture[1]/internal-format + + + + 2 + texture[2]/image + texture[2]/filter + texture[2]/wrap-s + texture[2]/wrap-t + + texture[2]/internal-format + + + + 3 + texture[3]/image + texture[3]/filter + texture[3]/wrap-s + texture[3]/wrap-t + + texture[3]/internal-format + + + + 4 + texture[4]/image + texture[4]/filter + texture[4]/wrap-s + texture[4]/wrap-t + + texture[4]/internal-format + Shaders/water.vert Shaders/water.frag - texture - sampler-3d - 0 + water_reflection + sampler-2d + 0 + + + water_refraction + sampler-2d + 1 + + + water_normalmap + sampler-2d + 2 + + + water_dudvmap + sampler-2d + 3 + + + water_depthmap + sampler-2d + 4 + + diff --git a/Shaders/water.frag b/Shaders/water.frag index 50ae098f8..c7b204967 100644 --- a/Shaders/water.frag +++ b/Shaders/water.frag @@ -1,86 +1,91 @@ -#version 120 -varying vec4 rawpos; -varying vec4 ecPosition; -varying vec3 VNormal; -varying vec3 Normal; -varying vec3 lightVec; +uniform sampler2D water_normalmap; +uniform sampler2D water_reflection; +uniform sampler2D water_refraction; +uniform sampler2D water_dudvmap; +uniform sampler2D water_depthmap; +//uniform vec4 waterColor, waterDepth; -uniform sampler3D NoiseTex; -uniform float osg_SimulationTime; +vec4 waterColor = vec4(0.0,0.2,1.0,1.0); +vec4 waterDepth = vec4(0.0,0.2,1.0,1.0); -//const float scale = 1.0; +varying vec4 waterTex0; //lightpos +varying vec4 waterTex1; //moving texcoords +varying vec4 waterTex2; //moving texcoords +varying vec4 waterTex3; //for projection +varying vec4 waterTex4; //viewts -void main (void) +//unit 0 = water_reflection +//unit 1 = water_refraction +//unit 2 = water_normalmap +//unit 3 = water_dudvmap +//unit 4 = water_depthmap + +void main(void) { - vec4 noisevecS = texture3D(NoiseTex, (rawpos.xyz)*0.0126); - vec4 nvLS = texture3D(NoiseTex, (rawpos.xyz)*-0.0003323417); +const vec4 sca = vec4(0.005, 0.005, 0.005, 0.005); +const vec4 sca2 = vec4(0.02, 0.02, 0.02, 0.02); +const vec4 tscale = vec4(0.25, 0.25, 0.25, 0.25); +const vec4 two = vec4(2.0, 2.0, 2.0, 1.0); +const vec4 mone = vec4(-1.0, -1.0, -1.0, 1.0); - vec4 noisevec = texture3D(NoiseTex, (rawpos.xyz)*0.00423+vec3(0.0,0.0,osg_SimulationTime*0.035217)); - vec4 nvL = texture3D(NoiseTex, (rawpos.xyz)*0.001223417+(0.0,0.0,osg_SimulationTime*-0.0212)); +const vec4 ofive = vec4(0.5,0.5,0.5,1.0); - float fogFactor; - if (gl_Fog.density == 1.0) - { - fogFactor=1.0; - } - else - { - float fogCoord = ecPosition.z; - const float LOG2 = 1.442695; - fogFactor = exp2(-gl_Fog.density * gl_Fog.density * fogCoord * fogCoord * LOG2); - fogFactor = clamp(fogFactor, 0.0, 1.0); - } +const float exponent = 64.0; - float a=1.0; - float n=0.00; - n += nvLS[0]*a; - a/=2.0; - n += nvLS[1]*a; - a/=2.0; - n += nvLS[2]*a; - a/=2.0; - n += nvLS[3]*a; +vec4 lightTS = normalize(waterTex0); +vec4 viewt = normalize(waterTex4); +vec4 disdis = texture2D(water_dudvmap, vec2(waterTex2 * tscale)); +vec4 dist = texture2D(water_dudvmap, vec2(waterTex1 + disdis*sca2)); +vec4 fdist = dist; +fdist = fdist * two + mone; +fdist = normalize(fdist); +fdist *= sca; - a=4.0; - float na=n; - na += nvL[0]*1.1; - a*=1.2; - na += nvL[1]*a; - a*=1.2; - na += nvL[2]*a; - a*=1.2; - na += nvL[3]*a; - a=2.0; - na += noisevec[0]*a*0.2; - a*=1.2; - na += noisevec[1]*a; - a*=1.2; - na += noisevec[2]*a; - a*=1.2; - na += noisevec[3]*a; +//load normalmap +vec4 nmap = texture2D(water_normalmap, vec2(waterTex1 + disdis*sca2)); +nmap = (nmap-ofive) * two; +vec4 vNorm = nmap; +vNorm = normalize(nmap); - vec4 c1; - c1 = asin(vec4(smoothstep(0.0, 2.2, n), smoothstep(-0.1, 2.10, n), smoothstep(-0.2, 2.0, n), 1.0)); +//get projective texcoords +vec4 tmp = vec4(1.0 / waterTex3.w); +vec4 temp = tmp; - vec3 Eye = normalize(-ecPosition.xyz); - vec3 Reflected = normalize(reflect(-normalize(lightVec), normalize(VNormal+vec3(0.0,0.0,na*0.10-0.24)))); +vec4 projCoord = waterTex3 * tmp; +projCoord += vec4(1.0); +projCoord *= vec4(0.5); +tmp = projCoord + fdist; +tmp = clamp(tmp, 0.001, 0.999); - vec3 bump = normalize(VNormal+vec3(0.0, 0.0, na)-0.9); - vec3 bumped = max(normalize(refract(lightVec, normalize(bump), 0.16)), 0.0); +//load reflection,refraction and depth texture +vec4 refTex = texture2D(water_reflection, vec2(tmp)); +vec4 refl = refTex; +vec4 refr = texture2D(water_refraction, vec2(tmp)); +vec4 wdepth = texture2D(water_depthmap, vec2(tmp)); - vec4 ambientColor = gl_LightSource[0].ambient; - vec4 light = ambientColor; - c1 *= light; +wdepth = vec4(pow(wdepth.x, 4.0)); +vec4 invdepth = 1.0 - wdepth; - float bumpFact = (bumped.r+bumped.g+bumped.b); - float ReflectedEye = max(dot(Reflected, Eye), 0.0); - float eyeFact = pow(ReflectedEye, 20.0); - c1 += 0.3 * gl_LightSource[0].diffuse * (1.0-eyeFact) * bumpFact*bumpFact; - c1 += 0.4 * gl_LightSource[0].diffuse * eyeFact * 3*bumpFact; - eyeFact = pow(eyeFact, 20.0); - c1 += gl_LightSource[0].specular * eyeFact * 4*bumpFact; +//calculate specular highlight +vec4 vRef = normalize(reflect(-lightTS, vNorm)); +float stemp =max(0.0, dot(viewt, vRef) ); +stemp = pow(stemp, exponent); +vec4 specular = vec4(stemp); - vec4 finalColor = c1; - gl_FragColor = mix(gl_Fog.color, finalColor, fogFactor); +//calculate fresnel and inverted fresnel +vec4 invfres = vec4( dot(vNorm, viewt) ); +vec4 fres = vec4(1.0) -invfres ; + +//calculate reflection and refraction +refr *= invfres; +refr *= invdepth; +temp = waterColor * wdepth * invfres; +refr += temp; +refl *= fres; + +//add reflection and refraction +tmp = refr + refl; + +gl_FragColor = tmp + specular; } diff --git a/Shaders/water.vert b/Shaders/water.vert index ca61aa33c..6b3c8e850 100644 --- a/Shaders/water.vert +++ b/Shaders/water.vert @@ -1,15 +1,48 @@ -varying vec4 rawpos; -varying vec4 ecPosition; -varying vec3 VNormal; -varying vec3 Normal; -varying vec3 lightVec; + +varying vec4 waterTex0; +varying vec4 waterTex1; +varying vec4 waterTex2; +varying vec4 waterTex3; +varying vec4 waterTex4; +uniform vec4 viewpos, lightpos; +uniform float time, time2; +//unit 0 = water_reflection +//unit 1 = water_refraction +//unit 2 = water_normalmap +//unit 3 = water_dudvmap +//unit 4 = water_depthmap void main(void) { - rawpos = gl_Vertex; - ecPosition = gl_ModelViewMatrix * gl_Vertex; - VNormal = normalize(gl_NormalMatrix * gl_Normal); - Normal = normalize(gl_Normal); - lightVec = normalize(gl_LightSource[0].position.xyz/* - ecPosition*/); - gl_Position = ftransform(); +vec4 mpos, temp; +vec4 tangent = vec4(1.0, 0.0, 0.0, 0.0); +vec4 norm = vec4(0.0, 1.0, 0.0, 0.0); +vec4 binormal = vec4(0.0, 0.0, 1.0, 0.0); + +mat4 mvp = gl_ModelViewProjectionMatrix; +mat4 mtx = gl_TextureMatrix[0]; + +temp = viewpos - gl_Vertex; +waterTex4.x = dot(temp, tangent); +waterTex4.y = dot(temp, binormal); +waterTex4.z = dot(temp, norm); +waterTex4.w = 0.0; + +temp = lightpos - gl_Vertex; +waterTex0.x = dot(temp, tangent); +waterTex0.y = dot(temp, binormal); +waterTex0.z = dot(temp, norm); +waterTex0.w = 0.0; + +mpos = mvp * gl_Vertex; + +vec4 t1 = vec4(0.0, -time, 0.0,0.0); +vec4 t2 = vec4(0.0, -time2, 0.0,0.0); + +waterTex1 = gl_MultiTexCoord0 + t1; +waterTex2 = gl_MultiTexCoord0 + t2; + +waterTex3 = mpos; + +gl_Position = ftransform(); }