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); +}