From b4f226c092d40746ca7624fead021e52513e602d Mon Sep 17 00:00:00 2001 From: Vivian Meazza Date: Sun, 1 Aug 2010 22:54:35 +0100 Subject: [PATCH] Add persistent contrail Shaders/contrail.frag Shaders/contrail.vert Signed-off-by: Vivian Meazza --- Shaders/contrail.frag | 15 +++++++ Shaders/contrail.vert | 99 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 Shaders/contrail.frag create mode 100644 Shaders/contrail.vert diff --git a/Shaders/contrail.frag b/Shaders/contrail.frag new file mode 100644 index 000000000..2a9636cfd --- /dev/null +++ b/Shaders/contrail.frag @@ -0,0 +1,15 @@ +uniform sampler2D baseTexture; + +varying float fogFactor; +varying float distanceFactor; +varying vec2 texCoord; + + +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 = mix(0.0, finalColor.a, distanceFactor); +} + diff --git a/Shaders/contrail.vert b/Shaders/contrail.vert new file mode 100644 index 000000000..7f4e86439 --- /dev/null +++ b/Shaders/contrail.vert @@ -0,0 +1,99 @@ +// -*-C++-*- +#version 120 + +varying float fogFactor; +varying float distanceFactor; + +uniform sampler3D Noise; + +uniform float scale_x; +uniform float scale_y; +uniform float scale_z; + +uniform float offset_x; +uniform float offset_y; +uniform float offset_z; + +uniform float fade_max; +uniform float fade_min; + +void main(void) +{ + vec4 rawpos = gl_Vertex; + + float shade = 0.9; + float cloud_height = 30000.0; + + // map noise vectors + vec4 noisevec = texture3D(Noise, rawpos.xyz); + float noise0 = (noisevec.r * 2) - 1; + float noise1 =(noisevec.g * 2) - 1; + vec2 noise2 = noisevec.xy; + + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + //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]. Scale + // the x component first + gl_Position = vec4(gl_Vertex.x * scale_x, 0.0, 0.0, 1.0); + gl_Position.xyz += gl_Vertex.x * u; + gl_Position.xyz += gl_Vertex.y * r * scale_y; + gl_Position.xyz += gl_Vertex.z * w * scale_z; + + // Adjust the position post-rotation and scaling + gl_Position.yz -= 3/2; + + // Offset in y and z directions using a random noise factor + float offset_Y = (noise0 * offset_y) + offset_y/2; + float offset_Z = (noise0 * offset_z) + offset_z/2; + + distanceFactor = 1.0 - clamp(abs(noise0), fade_min, fade_max); +// distanceFactor = 0.5; + + gl_Position.y += offset_Y; + gl_Position.z += offset_Z; + + 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 = dot(normalize(-gl_LightSource[0].position.xyz), + normalize(mat3x3(gl_ModelViewMatrix) * (- gl_Position.xyz)));; + + // 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; + + // Calculate the total offset distance in the yx plane, normalised + /*float distance = normalize(sqrt(pow(gl_Position.y, 2) + pow(gl_Position.z, 2))); + distanceFactor = 1.0 - clamp(distance, 0.5, 1.0);*/ + // Determine the shading of the sprite based on its vertical position and position relative to the sun. + n = min(smoothstep(-0.5, 0.0, n), fract); + + // Determine the shading based on a mixture from the backlight to the front + vec4 backlight = gl_LightSource[0].diffuse * shade; + + 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(30000.0, 40000.0, fogCoord)); + gl_BackColor = gl_FrontColor; + + // Fog doesn't affect clouds as much as other objects. + fogFactor = exp( -gl_Fog.density * fogCoord); + fogFactor = clamp(fogFactor, 0.0, 1.0); +}