| Next entry » Browse > Images
Skip to comments (2)
Pixelshader water
Posted by Erik on Oct 15 2005 @ 16:26 :: 4220 unique visits

- It looks so much better in movement.
- The water + terrain use 4 different shaders to render.
- 2 render textures are used, one for the reflection and one for the refraction.
- the reflection and refraction are dependent on the view angle on the water.
- The nice flow from water to land is done with alpha blending
- Some clipping optimizations are used to speed it all up.
- Refraction can be turned off and render texture sizes are easy to adjust.
The terrain shader:
CODE: C
varying float ln;
varying float slope;
varying float hight;
uniform sampler2D texture0;
uniform sampler2D texture1;
uniform vec3 lightPosition;
[vertex]
void main(void) {
hight = gl_Vertex.y;
vec3 up = normalize(gl_NormalMatrix * vec3(0, 1, 0));
vec3 vector = vec3(gl_ModelViewMatrix * gl_Vertex);
vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
// vector pointing to the light position
vec3 l = normalize(lightPosition - vector);
// take the dot product between the vector to the light and the normal
ln = max(dot(normal, l), 0.5);
// calculate the slope of the terrain
slope = min(max(dot(normal, up), 0.0) * 2.0, 1.0);
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}
[fragment]
void main(void) {
// 2d texture coordinates
vec2 texcoord = vec2(gl_TexCoord[0]);
vec3 color;
float alpha = 1.0;
float slp = slope;
vec3 dirt = vec3(texture2D(texture1, texcoord));
vec3 gras = vec3(texture2D(texture0, texcoord));
if (hight < 1.0) { // just above the water level
// let the texture flow from gras to dirt
slp = min(hight, slope);
if (hight < 0.5)
alpha = hight * 2.0;
}
// calculate the final color
color = (gras * slp) + (dirt * (1.0 - slp));
// write the final color + alpha component
gl_FragColor = vec4(color * ln, alpha);
}
varying float slope;
varying float hight;
uniform sampler2D texture0;
uniform sampler2D texture1;
uniform vec3 lightPosition;
[vertex]
void main(void) {
hight = gl_Vertex.y;
vec3 up = normalize(gl_NormalMatrix * vec3(0, 1, 0));
vec3 vector = vec3(gl_ModelViewMatrix * gl_Vertex);
vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
// vector pointing to the light position
vec3 l = normalize(lightPosition - vector);
// take the dot product between the vector to the light and the normal
ln = max(dot(normal, l), 0.5);
// calculate the slope of the terrain
slope = min(max(dot(normal, up), 0.0) * 2.0, 1.0);
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}
[fragment]
void main(void) {
// 2d texture coordinates
vec2 texcoord = vec2(gl_TexCoord[0]);
vec3 color;
float alpha = 1.0;
float slp = slope;
vec3 dirt = vec3(texture2D(texture1, texcoord));
vec3 gras = vec3(texture2D(texture0, texcoord));
if (hight < 1.0) { // just above the water level
// let the texture flow from gras to dirt
slp = min(hight, slope);
if (hight < 0.5)
alpha = hight * 2.0;
}
// calculate the final color
color = (gras * slp) + (dirt * (1.0 - slp));
// write the final color + alpha component
gl_FragColor = vec4(color * ln, alpha);
}
1. On Oct 17 2005 @ 19:46 Chrizz wrote:
Yeah, like you said Erik, it looks much nicer in movement! :-)