From 1531446fb2140905f174833ba9fa1cdcc84798fb Mon Sep 17 00:00:00 2001 From: jmt Date: Tue, 29 Sep 2009 07:41:11 +0000 Subject: [PATCH] From Lauri Peltonen (Zan): These two patches allow use of external shaders as the tree and 3d cloud shaders. The shaders are Shaders/3dcloud.{frag|vert} and Shaders/tree.{frag|vert}. If the shader files are not found, the original shaders included in the source are used. This makes testing modifications to the shaders easier and faster. End users should see no difference when using this. --- Shaders/3dcloud.frag | 11 ++++++++ Shaders/3dcloud.vert | 64 ++++++++++++++++++++++++++++++++++++++++++++ Shaders/tree.frag | 9 +++++++ Shaders/tree.vert | 31 +++++++++++++++++++++ 4 files changed, 115 insertions(+) create mode 100644 Shaders/3dcloud.frag create mode 100644 Shaders/3dcloud.vert create mode 100644 Shaders/tree.frag create mode 100644 Shaders/tree.vert diff --git a/Shaders/3dcloud.frag b/Shaders/3dcloud.frag new file mode 100644 index 000000000..a8d07665a --- /dev/null +++ b/Shaders/3dcloud.frag @@ -0,0 +1,11 @@ +uniform sampler2D baseTexture; +varying float fogFactor; + +void main(void) +{ + vec4 base = texture2D( baseTexture, gl_TexCoord[0].st); + vec4 finalColor = base * gl_Color; + gl_FragColor.rgb = mix(gl_Fog.color.rgb, finalColor.rgb, fogFactor ); + gl_FragColor.a = finalColor.a; +} + diff --git a/Shaders/3dcloud.vert b/Shaders/3dcloud.vert new file mode 100644 index 000000000..e199b0be6 --- /dev/null +++ b/Shaders/3dcloud.vert @@ -0,0 +1,64 @@ +#version 120 + +varying float fogFactor; + +attribute vec3 usrAttr1; +attribute vec3 usrAttr2; + +float textureIndexX = usrAttr1.r; +float textureIndexY = usrAttr1.g; +float wScale = usrAttr1.b; +float hScale = usrAttr2.r; +float shade = usrAttr2.g; +float cloud_height = usrAttr2.b; + +void main(void) +{ + gl_TexCoord[0] = gl_MultiTexCoord0 + vec4(textureIndexX, textureIndexY, 0.0, 0.0); + vec4 ep = gl_ModelViewMatrixInverse * vec4(0.0,0.0,0.0,1.0); + vec4 l = gl_ModelViewMatrixInverse * vec4(0.0,0.0,1.0,1.0); + vec3 u = normalize(ep.xyz - l.xyz); + + // Find a rotation matrix that rotates 1,0,0 into u. u, r and w are + // the columns of that matrix. + vec3 absu = abs(u); + vec3 r = normalize(vec3(-u.y, u.x, 0)); + vec3 w = cross(u, r); + + // Do the matrix multiplication by [ u r w pos]. Assume no + // scaling in the homogeneous component of pos. + gl_Position = vec4(0.0, 0.0, 0.0, 1.0); + gl_Position.xyz = gl_Vertex.x * u * wScale; + gl_Position.xyz += gl_Vertex.y * r * hScale; + gl_Position.xyz += gl_Vertex.z * w; + gl_Position.xyz += gl_Color.xyz; + + // Determine a lighting normal based on the vertex position from the + // center of the cloud, so that sprite on the opposite side of the cloud to the sun are darker. + float n = clamp(dot(normalize(gl_LightSource[0].position.xyz), normalize(mat3x3(gl_ModelViewMatrix) * gl_Position.xyz)), 0.0, 1.0); + + // Determine the position - used for fog and shading calculations + vec3 ecPosition = vec3(gl_ModelViewMatrix * gl_Position); + float fogCoord = abs(ecPosition.z); + float fract = smoothstep(0.0, cloud_height, gl_Position.z + cloud_height); + + // Final position of the sprite + gl_Position = gl_ModelViewProjectionMatrix * gl_Position; + + // Limit the normal range from [0,1.0], and apply the shading (vertical factor) + n = min(smoothstep(-0.8, 0.8, n), shade * (1.0 - fract) + fract); + + // This lighting normal is then used to mix between almost pure ambient (0) and diffuse (1.0) light + vec4 backlight = 0.9 * gl_LightSource[0].ambient + 0.1 * gl_LightSource[0].diffuse; + + gl_FrontColor = mix(backlight, gl_LightSource[0].diffuse, n); + gl_FrontColor += gl_FrontLightModelProduct.sceneColor; + + // As we get within 100m of the sprite, it is faded out. Equally at large distances it also fades out. + gl_FrontColor.a = min(smoothstep(10.0, 100.0, fogCoord), 1 - smoothstep(15000.0, 20000.0, fogCoord)); + gl_BackColor = gl_FrontColor; + + // Fog doesn't affect clouds as much as other objects. + fogFactor = exp( -gl_Fog.density * fogCoord * 0.5); + fogFactor = clamp(fogFactor, 0.0, 1.0); +} diff --git a/Shaders/tree.frag b/Shaders/tree.frag new file mode 100644 index 000000000..9dba6fccc --- /dev/null +++ b/Shaders/tree.frag @@ -0,0 +1,9 @@ +uniform sampler2D baseTexture; +varying float fogFactor; + +void main(void) +{ + vec4 base = texture2D( baseTexture, gl_TexCoord[0].st); + vec4 finalColor = base * gl_Color; + gl_FragColor = mix(gl_Fog.color, finalColor, fogFactor ); +} diff --git a/Shaders/tree.vert b/Shaders/tree.vert new file mode 100644 index 000000000..276b39649 --- /dev/null +++ b/Shaders/tree.vert @@ -0,0 +1,31 @@ +varying float fogFactor; + +void main(void) +{ + float numVarieties = gl_Normal.z; + float texFract = floor(fract(gl_MultiTexCoord0.x) * numVarieties) / numVarieties; + texFract += floor(gl_MultiTexCoord0.x) / numVarieties; + float sr = sin(gl_FogCoord); + float cr = cos(gl_FogCoord); + gl_TexCoord[0] = vec4(texFract, gl_MultiTexCoord0.y, 0.0, 0.0); + + // scaling + vec3 position = gl_Vertex.xyz * gl_Normal.xxy; + + // Rotation of the generic quad to specific one for the tree. + position.xy = vec2(dot(position.xy, vec2(cr, sr)), dot(position.xy, vec2(-sr, cr))); + position = position + gl_Color.xyz; + gl_Position = gl_ModelViewProjectionMatrix * vec4(position,1.0); + vec3 ecPosition = vec3(gl_ModelViewMatrix * vec4(position, 1.0)); + + float n = dot(normalize(gl_LightSource[0].position.xyz), normalize(-ecPosition)); + + vec3 diffuse = gl_FrontMaterial.diffuse.rgb * max(0.1, n); + vec4 ambientColor = gl_FrontLightModelProduct.sceneColor + gl_LightSource[0].ambient * gl_FrontMaterial.ambient; + gl_FrontColor = ambientColor + gl_LightSource[0].diffuse * vec4(diffuse, 1.0); + gl_BackColor = gl_FrontColor; + + float fogCoord = abs(ecPosition.z); + fogFactor = exp( -gl_Fog.density * gl_Fog.density * fogCoord * fogCoord); + fogFactor = clamp(fogFactor, 0.0, 1.0); +}