Fix relief mapping issues
[oweals/minetest.git] / client / shaders / water_surface_shader / opengl_fragment.glsl
1 uniform sampler2D baseTexture;
2 uniform sampler2D normalTexture;
3 uniform sampler2D textureFlags;
4
5 uniform vec4 skyBgColor;
6 uniform float fogDistance;
7 uniform vec3 eyePosition;
8
9 varying vec3 vPosition;
10 varying vec3 worldPosition;
11
12 varying vec3 eyeVec;
13 varying vec3 tsEyeVec;
14 varying vec3 lightVec;
15 varying vec3 tsLightVec;
16
17 bool normalTexturePresent = false;
18 bool texTileableHorizontal = false;
19 bool texTileableVertical = false;
20 bool texSeamless = false;
21
22 const float e = 2.718281828459;
23 const float BS = 10.0;
24
25 void get_texture_flags()
26 {
27         vec4 flags = texture2D(textureFlags, vec2(0.0, 0.0));
28         if (flags.r > 0.5) {
29                 normalTexturePresent = true;
30         }
31         if (flags.g > 0.5) {
32                 texTileableHorizontal = true;
33         }
34         if (flags.b > 0.5) {
35                 texTileableVertical = true;
36         }
37         if (texTileableHorizontal && texTileableVertical) {
38                 texSeamless = true;
39         }
40 }
41
42 float intensity(vec3 color)
43 {
44         return (color.r + color.g + color.b) / 3.0;
45 }
46
47 float get_rgb_height(vec2 uv)
48 {
49         return intensity(texture2D(baseTexture,uv).rgb);
50 }
51
52 vec4 get_normal_map(vec2 uv)
53 {
54         vec4 bump = texture2D(normalTexture, uv).rgba;
55         bump.xyz = normalize(bump.xyz * 2.0 -1.0);
56         bump.y = -bump.y;
57         return bump;
58 }
59
60 void main(void)
61 {
62         vec3 color;
63         vec4 bump;
64         vec2 uv = gl_TexCoord[0].st;
65         bool use_normalmap = false;
66         get_texture_flags();
67
68 #ifdef ENABLE_PARALLAX_OCCLUSION
69         if (normalTexturePresent) {
70                 vec3 tsEye = normalize(tsEyeVec);
71                 float height = PARALLAX_OCCLUSION_SCALE * texture2D(normalTexture, uv).a - PARALLAX_OCCLUSION_BIAS;
72                 uv = uv + texture2D(normalTexture, uv).z * height * vec2(tsEye.x,-tsEye.y);
73         }
74 #endif
75
76 #ifdef USE_NORMALMAPS
77         if (normalTexturePresent) {
78                 bump = get_normal_map(uv);
79                 use_normalmap = true;
80         } 
81 #endif
82
83         if (GENERATE_NORMALMAPS == 1 && use_normalmap == false) {
84                 float tl = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y+SAMPLE_STEP));
85                 float t  = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y-SAMPLE_STEP));
86                 float tr = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y+SAMPLE_STEP));
87                 float r  = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y));
88                 float br = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y-SAMPLE_STEP));
89                 float b  = get_rgb_height (vec2(uv.x,uv.y-SAMPLE_STEP));
90                 float bl = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y-SAMPLE_STEP));
91                 float l  = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y));
92                 float dX = (tr + 2.0 * r + br) - (tl + 2.0 * l + bl);
93                 float dY = (bl + 2.0 * b + br) - (tl + 2.0 * t + tr);
94                 bump = vec4 (normalize(vec3 (dX, -dY, NORMALMAPS_STRENGTH)),1.0);
95                 use_normalmap = true;
96         }
97
98 vec4 base = texture2D(baseTexture, uv).rgba;
99
100 #ifdef ENABLE_BUMPMAPPING
101         if (use_normalmap) {
102                 vec3 L = normalize(lightVec);
103                 vec3 E = normalize(eyeVec);
104                 float specular = pow(clamp(dot(reflect(L, bump.xyz), E), 0.0, 1.0),0.5);
105                 float diffuse = dot(E,bump.xyz);
106                 /* Mathematic optimization
107                 * Original: color = 0.05*base.rgb + diffuse*base.rgb + 0.2*specular*base.rgb;
108                 * This optimization save 2 multiplications (orig: 4 multiplications + 3 additions
109                 * end: 2 multiplications + 3 additions)
110                 */
111                 color = (0.05 + diffuse + 0.2 * specular) * base.rgb;
112         } else {
113                 color = base.rgb;
114         }
115 #else
116         color = base.rgb;
117 #endif
118
119 #if MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_LIQUID_OPAQUE
120         float alpha = gl_Color.a;
121         vec4 col = vec4(color.rgb, alpha);
122         col *= gl_Color;
123         if(fogDistance != 0.0){
124                 float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0));
125                 alpha = mix(alpha, 0.0, d);
126         }
127         gl_FragColor = vec4(col.rgb, alpha);
128 #else
129         vec4 col = vec4(color.rgb, base.a);
130         col *= gl_Color;
131         if(fogDistance != 0.0){
132                 float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0));
133                 col = mix(col, skyBgColor, d);
134         }
135         gl_FragColor = vec4(col.rgb, base.a);
136 #endif
137 }