1
0
Fork 0
fgdata/Shaders/3dcloud.vert
jmt 1531446fb2 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.
2009-09-29 07:41:11 +00:00

64 lines
2.5 KiB
GLSL

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