]> git.lizzy.rs Git - minetest.git/blob - client/shaders/nodes_shader/opengl_vertex.glsl
Make faces shading correct for all possible modes.
[minetest.git] / client / shaders / nodes_shader / opengl_vertex.glsl
1 uniform mat4 mWorldViewProj;\r
2 uniform mat4 mInvWorld;\r
3 uniform mat4 mTransWorld;\r
4 uniform mat4 mWorld;\r
5 \r
6 uniform float dayNightRatio;\r
7 uniform vec3 eyePosition;\r
8 uniform float animationTimer;\r
9 \r
10 varying vec3 vPosition;\r
11 varying vec3 worldPosition;\r
12 \r
13 varying vec3 eyeVec;\r
14 varying vec3 lightVec;\r
15 varying vec3 tsEyeVec;\r
16 varying vec3 tsLightVec;\r
17 \r
18 const float e = 2.718281828459;\r
19 const float BS = 10.0;\r
20 \r
21 float smoothCurve( float x ) {\r
22   return x * x *( 3.0 - 2.0 * x );\r
23 }\r
24 float triangleWave( float x ) {\r
25   return abs( fract( x + 0.5 ) * 2.0 - 1.0 );\r
26 }\r
27 float smoothTriangleWave( float x ) {\r
28   return smoothCurve( triangleWave( x ) ) * 2.0 - 1.0;\r
29 }\r
30 \r
31 void main(void)\r
32 {\r
33         gl_TexCoord[0] = gl_MultiTexCoord0;\r
34         \r
35 #if (MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_LIQUID_OPAQUE) && ENABLE_WAVING_WATER\r
36         vec4 pos = gl_Vertex;\r
37         pos.y -= 2.0;\r
38         pos.y -= sin (pos.z/WATER_WAVE_LENGTH + animationTimer * WATER_WAVE_SPEED * WATER_WAVE_LENGTH) * WATER_WAVE_HEIGHT\r
39                 + sin ((pos.z/WATER_WAVE_LENGTH + animationTimer * WATER_WAVE_SPEED * WATER_WAVE_LENGTH) / 7.0) * WATER_WAVE_HEIGHT;\r
40         gl_Position = mWorldViewProj * pos;\r
41 #elif MATERIAL_TYPE == TILE_MATERIAL_WAVING_LEAVES && ENABLE_WAVING_LEAVES\r
42         vec4 pos = gl_Vertex;\r
43         vec4 pos2 = mWorld * gl_Vertex;\r
44         pos.x += (smoothTriangleWave(animationTimer*10.0 + pos2.x * 0.01 + pos2.z * 0.01) * 2.0 - 1.0) * 0.4;\r
45         pos.y += (smoothTriangleWave(animationTimer*15.0 + pos2.x * -0.01 + pos2.z * -0.01) * 2.0 - 1.0) * 0.2;\r
46         pos.z += (smoothTriangleWave(animationTimer*10.0 + pos2.x * -0.01 + pos2.z * -0.01) * 2.0 - 1.0) * 0.4;\r
47         gl_Position = mWorldViewProj * pos;\r
48 #elif MATERIAL_TYPE == TILE_MATERIAL_WAVING_PLANTS && ENABLE_WAVING_PLANTS\r
49         vec4 pos = gl_Vertex;\r
50         vec4 pos2 = mWorld * gl_Vertex;\r
51         if (gl_TexCoord[0].y < 0.05) {\r
52         pos.x += (smoothTriangleWave(animationTimer * 20.0 + pos2.x * 0.1 + pos2.z * 0.1) * 2.0 - 1.0) * 0.8;\r
53                         pos.y -= (smoothTriangleWave(animationTimer * 10.0 + pos2.x * -0.5 + pos2.z * -0.5) * 2.0 - 1.0) * 0.4;\r
54         }\r
55         gl_Position = mWorldViewProj * pos;\r
56 #else\r
57         gl_Position = mWorldViewProj * gl_Vertex;\r
58 #endif\r
59 \r
60         vPosition = gl_Position.xyz;\r
61         worldPosition = (mWorld * gl_Vertex).xyz;\r
62         vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0);\r
63 \r
64         vec3 normal, tangent, binormal;\r
65         normal = normalize(gl_NormalMatrix * gl_Normal);\r
66         if (gl_Normal.x > 0.5) {\r
67                 //  1.0,  0.0,  0.0\r
68                 tangent  = normalize(gl_NormalMatrix * vec3( 0.0,  0.0, -1.0));\r
69                 binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0,  0.0));\r
70         } else if (gl_Normal.x < -0.5) {\r
71                 // -1.0,  0.0,  0.0\r
72                 tangent  = normalize(gl_NormalMatrix * vec3( 0.0,  0.0,  1.0));\r
73                 binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0,  0.0));\r
74         } else if (gl_Normal.y > 0.5) {\r
75                 //  0.0,  1.0,  0.0\r
76                 tangent  = normalize(gl_NormalMatrix * vec3( 1.0,  0.0,  0.0));\r
77                 binormal = normalize(gl_NormalMatrix * vec3( 0.0,  0.0,  1.0));\r
78         } else if (gl_Normal.y < -0.5) {\r
79                 //  0.0, -1.0,  0.0\r
80                 tangent  = normalize(gl_NormalMatrix * vec3( 1.0,  0.0,  0.0));\r
81                 binormal = normalize(gl_NormalMatrix * vec3( 0.0,  0.0,  1.0));\r
82         } else if (gl_Normal.z > 0.5) {\r
83                 //  0.0,  0.0,  1.0\r
84                 tangent  = normalize(gl_NormalMatrix * vec3( 1.0,  0.0,  0.0));\r
85                 binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0,  0.0));\r
86         } else if (gl_Normal.z < -0.5) {\r
87                 //  0.0,  0.0, -1.0\r
88                 tangent  = normalize(gl_NormalMatrix * vec3(-1.0,  0.0,  0.0));\r
89                 binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0,  0.0));\r
90         }\r
91         mat3 tbnMatrix = mat3(  tangent.x, binormal.x, normal.x,\r
92                                                         tangent.y, binormal.y, normal.y,\r
93                                                         tangent.z, binormal.z, normal.z);\r
94 \r
95         lightVec = sunPosition - worldPosition;\r
96         tsLightVec = lightVec * tbnMatrix;\r
97         eyeVec = (gl_ModelViewMatrix * gl_Vertex).xyz;\r
98         tsEyeVec = eyeVec * tbnMatrix;\r
99 \r
100         vec4 color;\r
101         float day = gl_Color.r;\r
102         float night = gl_Color.g;\r
103         float light_source = gl_Color.b;\r
104 \r
105         float rg = mix(night, day, dayNightRatio);\r
106         rg += light_source * 2.5; // Make light sources brighter\r
107         float b = rg;\r
108 \r
109         // Moonlight is blue\r
110         b += (day - night) / 13.0;\r
111         rg -= (day - night) / 23.0;\r
112 \r
113         // Emphase blue a bit in darker places\r
114         // See C++ implementation in mapblock_mesh.cpp finalColorBlend()\r
115         b += max(0.0, (1.0 - abs(b - 0.13)/0.17) * 0.025);\r
116 \r
117         // Artificial light is yellow-ish\r
118         // See C++ implementation in mapblock_mesh.cpp finalColorBlend()\r
119         rg += max(0.0, (1.0 - abs(rg - 0.85)/0.15) * 0.065);\r
120 \r
121         color.r = rg;\r
122         color.g = rg;\r
123         color.b = b;\r
124 \r
125         color.a = gl_Color.a;\r
126         gl_FrontColor = gl_BackColor = clamp(color,0.0,1.0);\r
127 }\r