opengl_vertex.glsl 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. uniform mat4 mWorld;
  2. // Color of the light emitted by the sun.
  3. uniform vec3 dayLight;
  4. uniform vec3 eyePosition;
  5. // The cameraOffset is the current center of the visible world.
  6. uniform vec3 cameraOffset;
  7. uniform float animationTimer;
  8. varying vec3 vNormal;
  9. varying vec3 vPosition;
  10. // World position in the visible world (i.e. relative to the cameraOffset.)
  11. // This can be used for many shader effects without loss of precision.
  12. // If the absolute position is required it can be calculated with
  13. // cameraOffset + worldPosition (for large coordinates the limits of float
  14. // precision must be considered).
  15. varying vec3 worldPosition;
  16. varying lowp vec4 varColor;
  17. // The centroid keyword ensures that after interpolation the texture coordinates
  18. // lie within the same bounds when MSAA is en- and disabled.
  19. // This fixes the stripes problem with nearest-neighbor textures and MSAA.
  20. #ifdef GL_ES
  21. varying mediump vec2 varTexCoord;
  22. #else
  23. centroid varying vec2 varTexCoord;
  24. #endif
  25. #ifdef ENABLE_DYNAMIC_SHADOWS
  26. // shadow uniforms
  27. uniform vec3 v_LightDirection;
  28. uniform float f_textureresolution;
  29. uniform mat4 m_ShadowViewProj;
  30. uniform float f_shadowfar;
  31. uniform float f_shadow_strength;
  32. uniform float f_timeofday;
  33. uniform vec4 CameraPos;
  34. varying float cosLight;
  35. varying float normalOffsetScale;
  36. varying float adj_shadow_strength;
  37. varying float f_normal_length;
  38. varying vec3 shadow_position;
  39. varying float perspective_factor;
  40. #endif
  41. varying float area_enable_parallax;
  42. varying vec3 eyeVec;
  43. varying float nightRatio;
  44. // Color of the light emitted by the light sources.
  45. const vec3 artificialLight = vec3(1.04, 1.04, 1.04);
  46. const float e = 2.718281828459;
  47. const float BS = 10.0;
  48. uniform float xyPerspectiveBias0;
  49. uniform float xyPerspectiveBias1;
  50. uniform float zPerspectiveBias;
  51. #ifdef ENABLE_DYNAMIC_SHADOWS
  52. vec4 getRelativePosition(in vec4 position)
  53. {
  54. vec2 l = position.xy - CameraPos.xy;
  55. vec2 s = l / abs(l);
  56. s = (1.0 - s * CameraPos.xy);
  57. l /= s;
  58. return vec4(l, s);
  59. }
  60. float getPerspectiveFactor(in vec4 relativePosition)
  61. {
  62. float pDistance = length(relativePosition.xy);
  63. float pFactor = pDistance * xyPerspectiveBias0 + xyPerspectiveBias1;
  64. return pFactor;
  65. }
  66. vec4 applyPerspectiveDistortion(in vec4 position)
  67. {
  68. vec4 l = getRelativePosition(position);
  69. float pFactor = getPerspectiveFactor(l);
  70. l.xy /= pFactor;
  71. position.xy = l.xy * l.zw + CameraPos.xy;
  72. position.z *= zPerspectiveBias;
  73. return position;
  74. }
  75. // custom smoothstep implementation because it's not defined in glsl1.2
  76. // https://docs.gl/sl4/smoothstep
  77. float mtsmoothstep(in float edge0, in float edge1, in float x)
  78. {
  79. float t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
  80. return t * t * (3.0 - 2.0 * t);
  81. }
  82. #endif
  83. float smoothCurve(float x)
  84. {
  85. return x * x * (3.0 - 2.0 * x);
  86. }
  87. float triangleWave(float x)
  88. {
  89. return abs(fract(x + 0.5) * 2.0 - 1.0);
  90. }
  91. float smoothTriangleWave(float x)
  92. {
  93. return smoothCurve(triangleWave(x)) * 2.0 - 1.0;
  94. }
  95. // OpenGL < 4.3 does not support continued preprocessor lines
  96. #if (MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_OPAQUE || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_BASIC) && ENABLE_WAVING_WATER
  97. //
  98. // Simple, fast noise function.
  99. // See: https://gist.github.com/patriciogonzalezvivo/670c22f3966e662d2f83
  100. //
  101. vec4 perm(vec4 x)
  102. {
  103. return mod(((x * 34.0) + 1.0) * x, 289.0);
  104. }
  105. float snoise(vec3 p)
  106. {
  107. vec3 a = floor(p);
  108. vec3 d = p - a;
  109. d = d * d * (3.0 - 2.0 * d);
  110. vec4 b = a.xxyy + vec4(0.0, 1.0, 0.0, 1.0);
  111. vec4 k1 = perm(b.xyxy);
  112. vec4 k2 = perm(k1.xyxy + b.zzww);
  113. vec4 c = k2 + a.zzzz;
  114. vec4 k3 = perm(c);
  115. vec4 k4 = perm(c + 1.0);
  116. vec4 o1 = fract(k3 * (1.0 / 41.0));
  117. vec4 o2 = fract(k4 * (1.0 / 41.0));
  118. vec4 o3 = o2 * d.z + o1 * (1.0 - d.z);
  119. vec2 o4 = o3.yw * d.x + o3.xz * (1.0 - d.x);
  120. return o4.y * d.y + o4.x * (1.0 - d.y);
  121. }
  122. #endif
  123. void main(void)
  124. {
  125. varTexCoord = inTexCoord0.st;
  126. float disp_x;
  127. float disp_z;
  128. // OpenGL < 4.3 does not support continued preprocessor lines
  129. #if (MATERIAL_TYPE == TILE_MATERIAL_WAVING_LEAVES && ENABLE_WAVING_LEAVES) || (MATERIAL_TYPE == TILE_MATERIAL_WAVING_PLANTS && ENABLE_WAVING_PLANTS)
  130. vec4 pos2 = mWorld * inVertexPosition;
  131. float tOffset = (pos2.x + pos2.y) * 0.001 + pos2.z * 0.002;
  132. disp_x = (smoothTriangleWave(animationTimer * 23.0 + tOffset) +
  133. smoothTriangleWave(animationTimer * 11.0 + tOffset)) * 0.4;
  134. disp_z = (smoothTriangleWave(animationTimer * 31.0 + tOffset) +
  135. smoothTriangleWave(animationTimer * 29.0 + tOffset) +
  136. smoothTriangleWave(animationTimer * 13.0 + tOffset)) * 0.5;
  137. #endif
  138. vec4 pos = inVertexPosition;
  139. // OpenGL < 4.3 does not support continued preprocessor lines
  140. #if (MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_OPAQUE || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_BASIC) && ENABLE_WAVING_WATER
  141. // Generate waves with Perlin-type noise.
  142. // The constants are calibrated such that they roughly
  143. // correspond to the old sine waves.
  144. vec3 wavePos = (mWorld * pos).xyz + cameraOffset;
  145. // The waves are slightly compressed along the z-axis to get
  146. // wave-fronts along the x-axis.
  147. wavePos.x /= WATER_WAVE_LENGTH * 3.0;
  148. wavePos.z /= WATER_WAVE_LENGTH * 2.0;
  149. wavePos.z += animationTimer * WATER_WAVE_SPEED * 10.0;
  150. pos.y += (snoise(wavePos) - 1.0) * WATER_WAVE_HEIGHT * 5.0;
  151. #elif MATERIAL_TYPE == TILE_MATERIAL_WAVING_LEAVES && ENABLE_WAVING_LEAVES
  152. pos.x += disp_x;
  153. pos.y += disp_z * 0.1;
  154. pos.z += disp_z;
  155. #elif MATERIAL_TYPE == TILE_MATERIAL_WAVING_PLANTS && ENABLE_WAVING_PLANTS
  156. if (varTexCoord.y < 0.05) {
  157. pos.x += disp_x;
  158. pos.z += disp_z;
  159. }
  160. #endif
  161. worldPosition = (mWorld * pos).xyz;
  162. gl_Position = mWorldViewProj * pos;
  163. vPosition = gl_Position.xyz;
  164. eyeVec = -(mWorldView * pos).xyz;
  165. #ifdef SECONDSTAGE
  166. normalPass = normalize((inVertexNormal+1)/2);
  167. #endif
  168. vNormal = inVertexNormal;
  169. // Calculate color.
  170. // Red, green and blue components are pre-multiplied with
  171. // the brightness, so now we have to multiply these
  172. // colors with the color of the incoming light.
  173. // The pre-baked colors are halved to prevent overflow.
  174. #ifdef GL_ES
  175. vec4 color = inVertexColor.bgra;
  176. #else
  177. vec4 color = inVertexColor;
  178. #endif
  179. // The alpha gives the ratio of sunlight in the incoming light.
  180. nightRatio = 1.0 - color.a;
  181. color.rgb = color.rgb * (color.a * dayLight.rgb +
  182. nightRatio * artificialLight.rgb) * 2.0;
  183. color.a = 1.0;
  184. // Emphase blue a bit in darker places
  185. // See C++ implementation in mapblock_mesh.cpp final_color_blend()
  186. float brightness = (color.r + color.g + color.b) / 3.0;
  187. color.b += max(0.0, 0.021 - abs(0.2 * brightness - 0.021) +
  188. 0.07 * brightness);
  189. varColor = clamp(color, 0.0, 1.0);
  190. #ifdef ENABLE_DYNAMIC_SHADOWS
  191. if (f_shadow_strength > 0.0) {
  192. #if MATERIAL_TYPE == TILE_MATERIAL_WAVING_PLANTS && ENABLE_WAVING_PLANTS
  193. // The shadow shaders don't apply waving when creating the shadow-map.
  194. // We are using the not waved inVertexPosition to avoid ugly self-shadowing.
  195. vec4 shadow_pos = inVertexPosition;
  196. #else
  197. vec4 shadow_pos = pos;
  198. #endif
  199. vec3 nNormal;
  200. f_normal_length = length(vNormal);
  201. /* normalOffsetScale is in world coordinates (1/10th of a meter)
  202. z_bias is in light space coordinates */
  203. float normalOffsetScale, z_bias;
  204. float pFactor = getPerspectiveFactor(getRelativePosition(m_ShadowViewProj * mWorld * shadow_pos));
  205. if (f_normal_length > 0.0) {
  206. nNormal = normalize(vNormal);
  207. cosLight = max(1e-5, dot(nNormal, -v_LightDirection));
  208. float sinLight = pow(1 - pow(cosLight, 2.0), 0.5);
  209. normalOffsetScale = 2.0 * pFactor * pFactor * sinLight * min(f_shadowfar, 500.0) /
  210. xyPerspectiveBias1 / f_textureresolution;
  211. z_bias = 1.0 * sinLight / cosLight;
  212. }
  213. else {
  214. nNormal = vec3(0.0);
  215. cosLight = clamp(dot(v_LightDirection, normalize(vec3(v_LightDirection.x, 0.0, v_LightDirection.z))), 1e-2, 1.0);
  216. float sinLight = pow(1 - pow(cosLight, 2.0), 0.5);
  217. normalOffsetScale = 0.0;
  218. z_bias = 3.6e3 * sinLight / cosLight;
  219. }
  220. z_bias *= pFactor * pFactor / f_textureresolution / f_shadowfar;
  221. shadow_position = applyPerspectiveDistortion(m_ShadowViewProj * mWorld * (shadow_pos + vec4(normalOffsetScale * nNormal, 0.0))).xyz;
  222. shadow_position.z -= z_bias;
  223. perspective_factor = pFactor;
  224. if (f_timeofday < 0.2) {
  225. adj_shadow_strength = f_shadow_strength * 0.5 *
  226. (1.0 - mtsmoothstep(0.18, 0.2, f_timeofday));
  227. } else if (f_timeofday >= 0.8) {
  228. adj_shadow_strength = f_shadow_strength * 0.5 *
  229. mtsmoothstep(0.8, 0.83, f_timeofday);
  230. } else {
  231. adj_shadow_strength = f_shadow_strength *
  232. mtsmoothstep(0.20, 0.25, f_timeofday) *
  233. (1.0 - mtsmoothstep(0.7, 0.8, f_timeofday));
  234. }
  235. }
  236. #endif
  237. }