DefaultShaderShadows.frag 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #ifdef GL_ES
  2. precision mediump float;
  3. #endif
  4. varying vec2 texCoordVar;
  5. varying vec3 varNormal;
  6. varying vec4 varPosition;
  7. varying vec4 rawPosition;
  8. uniform sampler2D diffuse;
  9. uniform mat4 modelMatrix;
  10. uniform vec4 diffuse_color;
  11. uniform vec4 specular_color;
  12. uniform vec4 entityColor;
  13. uniform float shininess;
  14. uniform float shadowAmount;
  15. #define MAX_LIGHTS 8
  16. #define MAX_LIGHT_SHADOWS 2
  17. struct LightInfo {
  18. vec3 position;
  19. vec3 direction;
  20. vec4 specular;
  21. vec4 diffuse;
  22. float spotExponent;
  23. float spotCosCutoff;
  24. float constantAttenuation;
  25. float linearAttenuation;
  26. float quadraticAttenuation;
  27. float shadowEnabled;
  28. };
  29. struct LightShadowInfo {
  30. sampler2D shadowBuffer;
  31. mat4 shadowMatrix;
  32. };
  33. uniform LightInfo lights[MAX_LIGHTS];
  34. uniform LightShadowInfo lightsShadows[MAX_LIGHT_SHADOWS];
  35. float calculateAttenuation(in int i, in float dist)
  36. {
  37. return(1.0 / (lights[i].constantAttenuation +
  38. lights[i].linearAttenuation * dist +
  39. lights[i].quadraticAttenuation * dist * dist));
  40. }
  41. void pointLight(in int i, in vec3 normal, in vec4 pos, inout vec4 diffuse, inout vec4 specular) {
  42. vec4 color = diffuse_color;
  43. vec4 matspec = specular_color;
  44. float shininess = shininess;
  45. vec4 lightspec = lights[i].specular;
  46. vec4 lpos = vec4(lights[i].position, 1.0);
  47. vec4 s = pos-lpos;
  48. vec4 sn = -normalize(s);
  49. vec3 light = sn.xyz;
  50. vec3 n = normalize(normal);
  51. vec3 r = -reflect(light, n);
  52. r = normalize(r);
  53. vec3 v = -pos.xyz;
  54. v = normalize(v);
  55. float nDotL = dot(n, sn.xyz);
  56. if(nDotL > 0.0) {
  57. float dist = length(s);
  58. float attenuation = calculateAttenuation(i, dist);
  59. diffuse += color * max(0.0, nDotL) * lights[i].diffuse * attenuation;
  60. if (shininess != 0.0) {
  61. specular += lightspec * matspec * pow(max(0.0,dot(r, v)), shininess) * attenuation;
  62. }
  63. }
  64. }
  65. void spotLight(in int i, in vec3 normal, in vec4 pos, inout vec4 diffuse, inout vec4 specular, in float shadow) {
  66. vec4 color = diffuse_color;
  67. vec4 matspec = specular_color;
  68. float shininess = shininess;
  69. vec4 lightspec = lights[i].specular;
  70. vec4 lpos = vec4(lights[i].position, 1.0);
  71. vec4 s = pos-lpos;
  72. vec4 sn = -normalize(s);
  73. vec3 light = sn.xyz;
  74. vec3 n = normalize(normal);
  75. vec3 r = -reflect(light, n);
  76. r = normalize(r);
  77. vec3 v = -pos.xyz;
  78. v = normalize(v);
  79. float cos_outer_cone_angle = (1.0-lights[i].spotExponent) * lights[i].spotCosCutoff;
  80. float cos_cur_angle = dot(-normalize(lights[i].direction), sn.xyz);
  81. float cos_inner_cone_angle = lights[i].spotCosCutoff;
  82. float cos_inner_minus_outer_angle = cos_inner_cone_angle - cos_outer_cone_angle;
  83. float spot = 0.0;
  84. spot = clamp((cos_cur_angle - cos_outer_cone_angle) / cos_inner_minus_outer_angle, 0.0, 1.0);
  85. float nDotL = dot(n, sn.xyz);
  86. if(nDotL > 0.0) {
  87. float dist = length(s);
  88. float attenuation = calculateAttenuation(i, dist);
  89. diffuse += color * max(0.0, nDotL) * lights[i].diffuse * attenuation * spot * shadow;
  90. if (shininess != 0.0) {
  91. specular += lightspec * matspec * pow(max(0.0,dot(r, v)), shininess) * attenuation * spot * shadow;
  92. }
  93. }
  94. }
  95. void doSpotLightShadow(in int i, in vec3 normal, in vec4 pos, inout vec4 diffuse, inout vec4 specular, inout int shadowIndex) {
  96. if(lights[i].shadowEnabled == 1.0) {
  97. float shadow = 1.0;
  98. float bias = 0.00001;
  99. if(shadowIndex == 0) {
  100. vec4 shadowCoord = lightsShadows[0].shadowMatrix * modelMatrix * rawPosition;
  101. vec4 shadowCoordinateWdivide = shadowCoord / shadowCoord.w;
  102. float distanceFromLight = texture2D(lightsShadows[0].shadowBuffer, shadowCoordinateWdivide.st).z;
  103. if (shadowCoordinateWdivide.x > 0.001 && shadowCoordinateWdivide.y > 0.001 && shadowCoordinateWdivide.x < 0.999 && shadowCoordinateWdivide.y < 0.999) {
  104. shadow = step(shadowCoordinateWdivide.z, distanceFromLight+bias);
  105. }
  106. } else {
  107. vec4 shadowCoord = lightsShadows[1].shadowMatrix * modelMatrix * rawPosition;
  108. vec4 shadowCoordinateWdivide = shadowCoord / shadowCoord.w;
  109. float distanceFromLight = texture2D(lightsShadows[1].shadowBuffer, shadowCoordinateWdivide.st).z;
  110. if (shadowCoordinateWdivide.x > 0.001 && shadowCoordinateWdivide.y > 0.001 && shadowCoordinateWdivide.x < 0.999 && shadowCoordinateWdivide.y < 0.999) {
  111. shadow = step(shadowCoordinateWdivide.z, distanceFromLight+bias);
  112. }
  113. }
  114. shadowIndex++;
  115. spotLight(i, normal, pos, diffuse, specular, shadow);
  116. } else {
  117. spotLight(i, normal, pos, diffuse, specular, 1.0);
  118. }
  119. }
  120. void doLights(in int numLights, in vec3 normal, in vec4 pos, inout vec4 diffuse, inout vec4 specular) {
  121. int shadowIndex = 0;
  122. for (int i = 0; i < numLights; i++) {
  123. if (lights[i].spotCosCutoff == 180.0) {
  124. pointLight(i, normal, pos, diffuse, specular);
  125. } else {
  126. doSpotLightShadow(i, normal, pos, diffuse, specular, shadowIndex);
  127. }
  128. }
  129. }
  130. void main()
  131. {
  132. vec4 diffuse_val = vec4(0.0);
  133. vec4 specular_val = vec4(0.0);
  134. doLights(MAX_LIGHTS, varNormal, varPosition, diffuse_val, specular_val);
  135. vec4 texColor = texture2D(diffuse, texCoordVar);
  136. vec4 color = diffuse_val;
  137. color = clamp((color*entityColor*texColor) + specular_val, 0.0, 1.0);
  138. color.a = entityColor.a * texColor.a * diffuse_color.a;
  139. gl_FragColor = color;
  140. }