opengl_fragment.glsl 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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 vec3 eyeVec;
  10. varying vec3 lightVec;
  11. bool normalTexturePresent = false;
  12. bool texTileableHorizontal = false;
  13. bool texTileableVertical = false;
  14. bool texSeamless = 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. void get_texture_flags()
  20. {
  21. vec4 flags = texture2D(textureFlags, vec2(0.0, 0.0));
  22. if (flags.r > 0.5) {
  23. normalTexturePresent = true;
  24. }
  25. if (flags.g > 0.5) {
  26. texTileableHorizontal = true;
  27. }
  28. if (flags.b > 0.5) {
  29. texTileableVertical = true;
  30. }
  31. if (texTileableHorizontal && texTileableVertical) {
  32. texSeamless = true;
  33. }
  34. }
  35. float intensity(vec3 color)
  36. {
  37. return (color.r + color.g + color.b) / 3.0;
  38. }
  39. float get_rgb_height(vec2 uv)
  40. {
  41. if (texSeamless) {
  42. return intensity(texture2D(baseTexture, uv).rgb);
  43. } else {
  44. return intensity(texture2D(baseTexture, clamp(uv, 0.0, 0.999)).rgb);
  45. }
  46. }
  47. vec4 get_normal_map(vec2 uv)
  48. {
  49. vec4 bump = texture2D(normalTexture, uv).rgba;
  50. bump.xyz = normalize(bump.xyz * 2.0 - 1.0);
  51. return bump;
  52. }
  53. void main(void)
  54. {
  55. vec3 color;
  56. vec4 bump;
  57. vec2 uv = gl_TexCoord[0].st;
  58. bool use_normalmap = false;
  59. get_texture_flags();
  60. #if USE_NORMALMAPS == 1
  61. if (normalTexturePresent) {
  62. bump = get_normal_map(uv);
  63. use_normalmap = true;
  64. }
  65. #endif
  66. #if GENERATE_NORMALMAPS == 1
  67. if (normalTexturePresent == false) {
  68. float tl = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y + SAMPLE_STEP));
  69. float t = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y - SAMPLE_STEP));
  70. float tr = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y + SAMPLE_STEP));
  71. float r = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y));
  72. float br = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y - SAMPLE_STEP));
  73. float b = get_rgb_height(vec2(uv.x, uv.y - SAMPLE_STEP));
  74. float bl = get_rgb_height(vec2(uv.x -SAMPLE_STEP, uv.y - SAMPLE_STEP));
  75. float l = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y));
  76. float dX = (tr + 2.0 * r + br) - (tl + 2.0 * l + bl);
  77. float dY = (bl + 2.0 * b + br) - (tl + 2.0 * t + tr);
  78. bump = vec4(normalize(vec3 (dX, dY, NORMALMAPS_STRENGTH)), 1.0);
  79. use_normalmap = true;
  80. }
  81. #endif
  82. vec4 base = texture2D(baseTexture, uv).rgba;
  83. #ifdef ENABLE_BUMPMAPPING
  84. if (use_normalmap) {
  85. vec3 L = normalize(lightVec);
  86. vec3 E = normalize(eyeVec);
  87. float specular = pow(clamp(dot(reflect(L, bump.xyz), E), 0.0, 1.0), 1.0);
  88. float diffuse = dot(-E,bump.xyz);
  89. color = (diffuse + 0.1 * specular) * base.rgb;
  90. } else {
  91. color = base.rgb;
  92. }
  93. #else
  94. color = base.rgb;
  95. #endif
  96. vec4 col = vec4(color.rgb, base.a);
  97. col *= gl_Color;
  98. // Due to a bug in some (older ?) graphics stacks (possibly in the glsl compiler ?),
  99. // the fog will only be rendered correctly if the last operation before the
  100. // clamp() is an addition. Else, the clamp() seems to be ignored.
  101. // E.g. the following won't work:
  102. // float clarity = clamp(fogShadingParameter
  103. // * (fogDistance - length(eyeVec)) / fogDistance), 0.0, 1.0);
  104. // As additions usually come for free following a multiplication, the new formula
  105. // should be more efficient as well.
  106. // Note: clarity = (1 - fogginess)
  107. float clarity = clamp(fogShadingParameter
  108. - fogShadingParameter * length(eyeVec) / fogDistance, 0.0, 1.0);
  109. col = mix(skyBgColor, col, clarity);
  110. gl_FragColor = vec4(col.rgb, base.a);
  111. }