opengl_fragment.glsl 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. uniform sampler2D baseTexture;
  2. uniform sampler2D normalTexture;
  3. uniform sampler2D textureFlags;
  4. uniform vec4 skyBgColor;
  5. uniform float fogDistance;
  6. uniform vec3 eyePosition;
  7. varying vec3 vPosition;
  8. varying vec3 worldPosition;
  9. varying float area_enable_parallax;
  10. varying vec3 eyeVec;
  11. varying vec3 tsEyeVec;
  12. varying vec3 lightVec;
  13. varying vec3 tsLightVec;
  14. bool normalTexturePresent = false;
  15. const float e = 2.718281828459;
  16. const float BS = 10.0;
  17. const float fogStart = FOG_START;
  18. const float fogShadingParameter = 1 / ( 1 - fogStart);
  19. #ifdef ENABLE_TONE_MAPPING
  20. /* Hable's UC2 Tone mapping parameters
  21. A = 0.22;
  22. B = 0.30;
  23. C = 0.10;
  24. D = 0.20;
  25. E = 0.01;
  26. F = 0.30;
  27. W = 11.2;
  28. equation used: ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F
  29. */
  30. vec3 uncharted2Tonemap(vec3 x)
  31. {
  32. return ((x * (0.22 * x + 0.03) + 0.002) / (x * (0.22 * x + 0.3) + 0.06)) - 0.03333;
  33. }
  34. vec4 applyToneMapping(vec4 color)
  35. {
  36. color = vec4(pow(color.rgb, vec3(2.2)), color.a);
  37. const float gamma = 1.6;
  38. const float exposureBias = 5.5;
  39. color.rgb = uncharted2Tonemap(exposureBias * color.rgb);
  40. // Precalculated white_scale from
  41. //vec3 whiteScale = 1.0 / uncharted2Tonemap(vec3(W));
  42. vec3 whiteScale = vec3(1.036015346);
  43. color.rgb *= whiteScale;
  44. return vec4(pow(color.rgb, vec3(1.0 / gamma)), color.a);
  45. }
  46. #endif
  47. void get_texture_flags()
  48. {
  49. vec4 flags = texture2D(textureFlags, vec2(0.0, 0.0));
  50. if (flags.r > 0.5) {
  51. normalTexturePresent = true;
  52. }
  53. }
  54. float intensity(vec3 color)
  55. {
  56. return (color.r + color.g + color.b) / 3.0;
  57. }
  58. float get_rgb_height(vec2 uv)
  59. {
  60. return intensity(texture2D(baseTexture, uv).rgb);
  61. }
  62. vec4 get_normal_map(vec2 uv)
  63. {
  64. vec4 bump = texture2D(normalTexture, uv).rgba;
  65. bump.xyz = normalize(bump.xyz * 2.0 - 1.0);
  66. return bump;
  67. }
  68. float find_intersection(vec2 dp, vec2 ds)
  69. {
  70. float depth = 1.0;
  71. float best_depth = 0.0;
  72. float size = 0.0625;
  73. for (int i = 0; i < 15; i++) {
  74. depth -= size;
  75. float h = texture2D(normalTexture, dp + ds * depth).a;
  76. if (depth <= h) {
  77. best_depth = depth;
  78. break;
  79. }
  80. }
  81. depth = best_depth;
  82. for (int i = 0; i < 4; i++) {
  83. size *= 0.5;
  84. float h = texture2D(normalTexture,dp + ds * depth).a;
  85. if (depth <= h) {
  86. best_depth = depth;
  87. depth += size;
  88. } else {
  89. depth -= size;
  90. }
  91. }
  92. return best_depth;
  93. }
  94. float find_intersectionRGB(vec2 dp, vec2 ds)
  95. {
  96. const float depth_step = 1.0 / 24.0;
  97. float depth = 1.0;
  98. for (int i = 0 ; i < 24 ; i++) {
  99. float h = get_rgb_height(dp + ds * depth);
  100. if (h >= depth)
  101. break;
  102. depth -= depth_step;
  103. }
  104. return depth;
  105. }
  106. void main(void)
  107. {
  108. vec3 color;
  109. vec4 bump;
  110. vec2 uv = gl_TexCoord[0].st;
  111. bool use_normalmap = false;
  112. get_texture_flags();
  113. #ifdef ENABLE_PARALLAX_OCCLUSION
  114. vec2 eyeRay = vec2 (tsEyeVec.x, -tsEyeVec.y);
  115. const float scale = PARALLAX_OCCLUSION_SCALE / PARALLAX_OCCLUSION_ITERATIONS;
  116. const float bias = PARALLAX_OCCLUSION_BIAS / PARALLAX_OCCLUSION_ITERATIONS;
  117. #if PARALLAX_OCCLUSION_MODE == 0
  118. // Parallax occlusion with slope information
  119. if (normalTexturePresent && area_enable_parallax > 0.0) {
  120. for (int i = 0; i < PARALLAX_OCCLUSION_ITERATIONS; i++) {
  121. vec4 normal = texture2D(normalTexture, uv.xy);
  122. float h = normal.a * scale - bias;
  123. uv += h * normal.z * eyeRay;
  124. }
  125. #endif
  126. #if PARALLAX_OCCLUSION_MODE == 1
  127. // Relief mapping
  128. if (normalTexturePresent && area_enable_parallax > 0.0) {
  129. vec2 ds = eyeRay * PARALLAX_OCCLUSION_SCALE;
  130. float dist = find_intersection(uv, ds);
  131. uv += dist * ds;
  132. #endif
  133. } else if (GENERATE_NORMALMAPS == 1 && area_enable_parallax > 0.0) {
  134. vec2 ds = eyeRay * PARALLAX_OCCLUSION_SCALE;
  135. float dist = find_intersectionRGB(uv, ds);
  136. uv += dist * ds;
  137. }
  138. #endif
  139. #if USE_NORMALMAPS == 1
  140. if (normalTexturePresent) {
  141. bump = get_normal_map(uv);
  142. use_normalmap = true;
  143. }
  144. #endif
  145. #if GENERATE_NORMALMAPS == 1
  146. if (normalTexturePresent == false) {
  147. float tl = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y + SAMPLE_STEP));
  148. float t = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y - SAMPLE_STEP));
  149. float tr = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y + SAMPLE_STEP));
  150. float r = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y));
  151. float br = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y - SAMPLE_STEP));
  152. float b = get_rgb_height(vec2(uv.x, uv.y - SAMPLE_STEP));
  153. float bl = get_rgb_height(vec2(uv.x -SAMPLE_STEP, uv.y - SAMPLE_STEP));
  154. float l = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y));
  155. float dX = (tr + 2.0 * r + br) - (tl + 2.0 * l + bl);
  156. float dY = (bl + 2.0 * b + br) - (tl + 2.0 * t + tr);
  157. bump = vec4(normalize(vec3 (dX, dY, NORMALMAPS_STRENGTH)), 1.0);
  158. use_normalmap = true;
  159. }
  160. #endif
  161. vec4 base = texture2D(baseTexture, uv).rgba;
  162. #ifdef ENABLE_BUMPMAPPING
  163. if (use_normalmap) {
  164. vec3 L = normalize(lightVec);
  165. vec3 E = normalize(eyeVec);
  166. float specular = pow(clamp(dot(reflect(L, bump.xyz), E), 0.0, 1.0), 1.0);
  167. float diffuse = dot(-E,bump.xyz);
  168. color = (diffuse + 0.1 * specular) * base.rgb;
  169. } else {
  170. color = base.rgb;
  171. }
  172. #else
  173. color = base.rgb;
  174. #endif
  175. vec4 col = vec4(color.rgb * gl_Color.rgb, 1.0);
  176. #ifdef ENABLE_TONE_MAPPING
  177. col = applyToneMapping(col);
  178. #endif
  179. // Due to a bug in some (older ?) graphics stacks (possibly in the glsl compiler ?),
  180. // the fog will only be rendered correctly if the last operation before the
  181. // clamp() is an addition. Else, the clamp() seems to be ignored.
  182. // E.g. the following won't work:
  183. // float clarity = clamp(fogShadingParameter
  184. // * (fogDistance - length(eyeVec)) / fogDistance), 0.0, 1.0);
  185. // As additions usually come for free following a multiplication, the new formula
  186. // should be more efficient as well.
  187. // Note: clarity = (1 - fogginess)
  188. float clarity = clamp(fogShadingParameter
  189. - fogShadingParameter * length(eyeVec) / fogDistance, 0.0, 1.0);
  190. col = mix(skyBgColor, col, clarity);
  191. col = vec4(col.rgb, base.a);
  192. gl_FragColor = col;
  193. }