opengl_vertex.glsl 8.5 KB

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