From 062594ff05e08ba13b102f93e387c86082b0c739 Mon Sep 17 00:00:00 2001 From: Vivian Meazza Date: Mon, 5 Sep 2011 16:02:06 +0100 Subject: [PATCH] Add new shaders in support of .dds textures Signed-off-by: Vivian Meazza --- Shaders/transition.frag | 124 ++++++++++++++++++++++++++++++++++++++ Shaders/transition.vert | 57 ++++++++++++++++++ Shaders/water-inland.frag | 99 ++++++++++++++++++++++++++++++ 3 files changed, 280 insertions(+) create mode 100644 Shaders/transition.frag create mode 100644 Shaders/transition.vert create mode 100644 Shaders/water-inland.frag diff --git a/Shaders/transition.frag b/Shaders/transition.frag new file mode 100644 index 000000000..c9237476b --- /dev/null +++ b/Shaders/transition.frag @@ -0,0 +1,124 @@ +// -*-C++-*- +// Texture switching based on face slope and snow level +// default.frag (c) 2010 ?? +// (c)2011 - Emilian Huminiuc, with ideas from crop.frag, forest.frag +// Ambient term comes in gl_Color.rgb. +varying vec4 diffuse_term, RawPos; +varying vec3 Vnormal, normal; +varying float fogCoord; + +uniform float SnowLevel, Transitions, InverseSlope, RainNorm; +uniform sampler2D BaseTex, SecondTex, ThirdTex, SnowTex; +uniform sampler3D NoiseTex; + +void main() +{ + float MixFactor, NdotL, NdotHV, fogFactor, slope, L1, L2, wetness; + + vec3 n, lightDir, halfVector; + vec4 texel, fragColor, color, specular, Noise; // GNoise; + + lightDir = gl_LightSource[0].position.xyz; + halfVector = gl_LightSource[0].halfVector.xyz; + + color = gl_Color; + specular = vec4(0.0); + + Noise = texture3D(NoiseTex, RawPos.xyz*0.0011); + //GNoise = texture3D(NoiseTex, RawPos.xyz*0.00011); + + MixFactor = Noise.r * Noise.g * Noise.b; //Mixing Factor to create a more organic looking boundary + //AddedNoise = GNoise.r * GNoise.g * GNoise.b; //Some added Noise to break the evenness on some textures + MixFactor *= 50.0; + L1 = 0.88 - 0.04 * MixFactor; //first transition slope + L2 = 0.80 + 0.04 * MixFactor; //Second transition slope + + // If gl_Color.a == 0, this is a back-facing polygon and the + // Vnormal should be reversed. + n = (2.0 * gl_Color.a - 1.0) * Vnormal; + n = normalize(n); + + NdotL = dot(n, lightDir); + if (NdotL > 0.0) { + color += diffuse_term * NdotL; + NdotHV = max(dot(n, halfVector), 0.0); + if (gl_FrontMaterial.shininess > 0.0) + specular.rgb = (gl_FrontMaterial.specular.rgb + * gl_LightSource[0].specular.rgb + * pow(NdotHV, gl_FrontMaterial.shininess)); + } + + color.a = diffuse_term.a; + // This shouldn't be necessary, but our lighting becomes very + // saturated. Clamping the color before modulating by the texture + // is closer to what the OpenGL fixed function pipeline does. + color = clamp(color, 0.0, 1.0); + + + //Select texture based on slope + slope = normalize(normal).z; + + //Normal transition. For more abrupt faces apply another texture (or 2). + if (InverseSlope == 0.0) { + //Do we do an intermediate transition + if (Transitions >= 1.5) { + if (slope > L1) { + texel = mix(texture2D(SecondTex, gl_TexCoord[0].st), texture2D(BaseTex, gl_TexCoord[0].st), smoothstep(L1, L1 + 0.003*MixFactor, slope)); + } + if (slope > L2 && slope <= L1){ + texel = mix(texture2D(SecondTex, gl_TexCoord[0].st), texture2D(BaseTex, gl_TexCoord[0].st), smoothstep(L2 + 0.01 * MixFactor, L1, slope)); + } + if (slope <= L2){ + texel = mix(texture2D(ThirdTex, gl_TexCoord[0].st), texture2D(SecondTex, gl_TexCoord[0].st), smoothstep(L2 - 0.1 * MixFactor, L2, slope)); + } + // Just one transition + } else if (Transitions < 1.5) { + if (slope > L1) { + texel = texture2D(BaseTex, gl_TexCoord[0].st); + } + if (slope <= L1) { + texel = mix(texture2D(ThirdTex, gl_TexCoord[0].st), texture2D(BaseTex, gl_TexCoord[0].st), smoothstep(L2 - 0.1 * MixFactor, L1, slope)); + } + } + + //Invert the transition: keep original texture on abrupt slopes and switch to another on flatter terrain + } else if (InverseSlope > 0.0) { + //Interemdiate transition ? + if (Transitions >= 1.5) { + if (slope > L1 + 0.16) { + texel = texture2D(ThirdTex, gl_TexCoord[0].st); + } + if (slope > L2 && slope <= L1 + 0.16){ + texel = mix(texture2D(SecondTex, gl_TexCoord[0].st), texture2D(ThirdTex, gl_TexCoord[0].st), smoothstep(L2 + 0.01 * MixFactor, L1, slope)); + } + if (slope <= L2){ + texel = mix(texture2D(BaseTex, gl_TexCoord[0].st), texture2D(SecondTex, gl_TexCoord[0].st), smoothstep(L2 - 0.05 * MixFactor, L2, slope)); + } + //just one + } else if (Transitions < 1.5) { + if (slope > L1 + 0.16) { + texel = texture2D(ThirdTex, gl_TexCoord[0].st); + } + if (slope <= L1 + 0.16){ + texel = mix(texture2D(BaseTex, gl_TexCoord[0].st), texture2D(ThirdTex, gl_TexCoord[0].st), smoothstep(L2 - 0.05 * MixFactor, L1 + 0.16, slope)); + } + } + } + + //darken textures with wetness + wetness = 1.0 - 0.3 * RainNorm; + texel.rgb = texel.rgb * wetness; + //texel.r = texel.r * wetness; + //texel.g = texel.g * wetness; + //texel.b = texel.b * wetness; + + //Snow texture for areas higher than SnowLevel + if (RawPos.z >= SnowLevel - 6000.0 * MixFactor && slope > L2 - 0.4) { + texel = mix(texel, mix(texel, texture2D(SnowTex, gl_TexCoord[0].st), smoothstep(L2 - 0.4 * MixFactor, L2, slope)), smoothstep(SnowLevel - 6000.0 * slope * MixFactor, SnowLevel - 1400.0 * slope * MixFactor, RawPos.z)); + } + + fragColor = color * texel + specular; + + fogFactor = exp(-gl_Fog.density * gl_Fog.density * fogCoord * fogCoord); + gl_FragColor = mix(gl_Fog.color, fragColor, fogFactor); +} \ No newline at end of file diff --git a/Shaders/transition.vert b/Shaders/transition.vert new file mode 100644 index 000000000..362f1ebf1 --- /dev/null +++ b/Shaders/transition.vert @@ -0,0 +1,57 @@ +// -*-C++-*- + +// Shader that uses OpenGL state values to do per-pixel lighting +// +// The only light used is gl_LightSource[0], which is assumed to be +// directional. +// +// Diffuse colors come from the gl_Color, ambient from the material. This is +// equivalent to osg::Material::DIFFUSE. + +#define MODE_OFF 0 +#define MODE_DIFFUSE 1 +#define MODE_AMBIENT_AND_DIFFUSE 2 + +// The constant term of the lighting equation that doesn't depend on +// the surface normal is passed in gl_{Front,Back}Color. The alpha +// component is set to 1 for front, 0 for back in order to work around +// bugs with gl_FrontFacing in the fragment shader. +varying vec4 diffuse_term, RawPos; +varying vec3 normal, Vnormal; +varying float fogCoord; +uniform int colorMode; + +void main() +{ + RawPos = gl_Vertex; + vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex; + gl_Position = ftransform(); + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + normal = normalize(gl_Normal); + Vnormal = gl_NormalMatrix * gl_Normal; + vec4 ambient_color, diffuse_color; + if (colorMode == MODE_DIFFUSE) { + diffuse_color = gl_Color; + ambient_color = gl_FrontMaterial.ambient; + } else if (colorMode == MODE_AMBIENT_AND_DIFFUSE) { + diffuse_color = gl_Color; + ambient_color = gl_Color; + } else { + diffuse_color = gl_FrontMaterial.diffuse; + ambient_color = gl_FrontMaterial.ambient; + } + diffuse_term = diffuse_color * gl_LightSource[0].diffuse; + vec4 constant_term = gl_FrontMaterial.emission + ambient_color * + (gl_LightModel.ambient + gl_LightSource[0].ambient); + // Super hack: if diffuse material alpha is less than 1, assume a + // transparency animation is at work + if (gl_FrontMaterial.diffuse.a < 1.0) + diffuse_term.a = gl_FrontMaterial.diffuse.a; + else + diffuse_term.a = gl_Color.a; + // Another hack for supporting two-sided lighting without using + // gl_FrontFacing in the fragment shader. + gl_FrontColor.rgb = constant_term.rgb; gl_FrontColor.a = 1.0; + gl_BackColor.rgb = constant_term.rgb; gl_BackColor.a = 0.0; + fogCoord = abs(ecPosition.z / ecPosition.w); +} diff --git a/Shaders/water-inland.frag b/Shaders/water-inland.frag new file mode 100644 index 000000000..198f910cf --- /dev/null +++ b/Shaders/water-inland.frag @@ -0,0 +1,99 @@ +// This shader is mostly an adaptation of the shader found at +// http://www.bonzaisoftware.com/water_tut.html and its glsl conversion +// available at http://forum.bonzaisoftware.com/viewthread.php?tid=10 +// © Michael Horsch - 2005 + +uniform sampler2D water_normalmap; +uniform sampler2D water_reflection; +uniform sampler2D water_dudvmap; +uniform float saturation; +uniform float RainNorm; + +varying vec4 waterTex1; //moving texcoords +varying vec4 waterTex2; //moving texcoords +varying vec4 waterTex4; //viewts +varying vec4 ecPosition; +varying vec3 viewerdir; +varying vec3 lightdir; +varying vec3 normal; + +void main(void) +{ +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); + +// compute direction to viewer +vec3 E = normalize(viewerdir); + +// compute direction to light source +vec3 L = normalize(lightdir); + +// half vector +vec3 H = normalize(L + E); + +const float water_shininess = 240.0; + +vec4 viewt = normalize(waterTex4); + +vec4 disdis = texture2D(water_dudvmap, vec2(waterTex2 * tscale)) * 2.0 - 1.0; +vec4 dist = texture2D(water_dudvmap, vec2(waterTex1 + disdis*sca2)) * 2.0 - 1.0; +vec4 fdist = normalize(dist); +fdist *= sca; + +//normalmap +vec4 nmap0 = texture2D(water_normalmap, vec2(waterTex1+ disdis*sca2)) * 2.0 - 1.0; +vec4 nmap2 = texture2D(water_normalmap, vec2(waterTex2 * tscale)) * 2.0 - 1.0; +vec4 vNorm = normalize(nmap0 + nmap2); + +//load reflection +vec4 tmp = vec4(lightdir, 0.0); +vec4 refTex = texture2D(water_reflection, vec2(tmp)); +vec4 refl = normalize(refTex); + +vec3 N0 = vec3(texture2D(water_normalmap, vec2(waterTex1+ disdis*sca2)) * 2.0 - 1.0); +vec3 N1 = vec3(texture2D(water_normalmap, vec2(waterTex2 * tscale)) * 2.0 - 1.0); +vec3 N = normalize(normal+N0+N1); + +vec3 specular_color = vec3(gl_LightSource[0].diffuse) + * pow(max(0.0, dot(N, H)), water_shininess) * 6.0; + +vec4 specular = vec4(specular_color,0.5); + +//calculate fresnel +vec4 invfres = vec4( dot(vNorm, viewt) ); +vec4 fres = vec4(1.0) + invfres; +refl *= fres; + +// take rain into account +float rain_factor = 0.7 - RainNorm; +rain_factor = clamp(rain_factor, 0, 1); + +if (RainNorm > 0) +{ + refl *= (0.9, 1.0, 0.6 * rain_factor, 1.0); +} +else +{ + refl *= (0.9, 1.0, 0.6, 1.0); +} + +specular = specular * 0.4 * rain_factor; + +vec4 finalColor = refl + specular; + +float fogFactor; +float fogCoord = ecPosition.z; +const float LOG2 = 1.442695; +fogFactor = exp2(-gl_Fog.density * gl_Fog.density * fogCoord * fogCoord * LOG2); + +vec4 ambient_light = gl_LightSource[0].diffuse; + + finalColor *= ambient_light; + + if(gl_Fog.density == 1.0) + fogFactor=1.0; + +gl_FragColor = mix(gl_Fog.color,finalColor, fogFactor); + +}