IsLpGeneric.glsl 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /// @file
  2. ///
  3. /// Illumination stage lighting pass general shader program
  4. #pragma anki vertShaderBegins
  5. #pragma anki include "shaders/SimpleVert.glsl"
  6. #pragma anki fragShaderBegins
  7. #pragma anki include "shaders/Pack.glsl"
  8. /// @name Uniforms
  9. /// @{
  10. uniform vec2 planes; ///< for the calculation of frag pos in view space
  11. uniform vec2 limitsOfNearPlane; ///< for the calculation of frag pos in view space
  12. uniform vec2 limitsOfNearPlane2; ///< This is an optimization see PpsSsao.glsl and r403 for the clean one
  13. uniform float zNear; ///< for the calculation of frag pos in view space
  14. uniform sampler2D msNormalFai, msDiffuseFai, msSpecularFai, msDepthFai;
  15. uniform vec3 lightPos; ///< Light pos in eye space
  16. uniform float lightRadius;
  17. uniform vec3 lightDiffuseCol;
  18. uniform vec3 lightSpecularCol;
  19. #if defined(SPOT_LIGHT_ENABLED)
  20. uniform sampler2D lightTex;
  21. uniform mat4 texProjectionMat;
  22. #if defined(SHADOW_ENABLED)
  23. uniform sampler2DShadow shadowMap;
  24. uniform float shadowMapSize;
  25. #endif
  26. #endif
  27. /// @}
  28. /// @name Varyings
  29. /// @{
  30. in vec2 vTexCoords;
  31. /// @}
  32. /// @name Output
  33. /// @{
  34. out vec3 fColor;
  35. /// @}
  36. const float MAX_SHININESS = 128.0;
  37. //======================================================================================================================
  38. // getFragPosVSpace =
  39. //======================================================================================================================
  40. /// @return frag pos in view space
  41. vec3 getFragPosVSpace()
  42. {
  43. float depth = texture2D(msDepthFai, vTexCoords).r;
  44. /*if(depth == 1.0)
  45. {
  46. discard;
  47. }*/
  48. vec3 fragPosVspace;
  49. fragPosVspace.z = -planes.y / (planes.x + depth);
  50. fragPosVspace.xy = (vTexCoords * limitsOfNearPlane2) - limitsOfNearPlane;
  51. float sc = -fragPosVspace.z / zNear;
  52. fragPosVspace.xy *= sc;
  53. return fragPosVspace;
  54. }
  55. //======================================================================================================================
  56. // getAttenuation =
  57. //======================================================================================================================
  58. /// @return The attenuation factor given the distance from the frag to the light source
  59. float getAttenuation(in float fragLightDist)
  60. {
  61. return clamp(1.0 - sqrt(fragLightDist) / lightRadius, 0.0, 1.0);
  62. //return 1.0 - fragLightDist * _inv_light_radius;
  63. }
  64. //======================================================================================================================
  65. // pcfLow =
  66. //======================================================================================================================
  67. #if defined(SPOT_LIGHT_ENABLED) && defined(SHADOW_ENABLED)
  68. /// @return The blurred shadow
  69. float pcfLow(in vec3 shadowUv)
  70. {
  71. float mapScale = 1.0 / shadowMapSize;
  72. const int KERNEL_SIZE = 8;
  73. const vec2 KERNEL[KERNEL_SIZE] = vec2[]
  74. (
  75. vec2(1.0, 1.0),
  76. vec2(1.0, -1.0),
  77. vec2(-1.0, 1.0),
  78. vec2(-1.0, -1.0),
  79. vec2(0.0, 1.0),
  80. vec2(0.0, -1.0),
  81. vec2(1.0, 0.0),
  82. vec2(-1.0, 0.0)
  83. );
  84. float shadowCol = shadow2D(shadowMap, shadowUv).r;
  85. for(int i = 0; i < KERNEL_SIZE; i++)
  86. {
  87. vec3 uv = vec3(shadowUv.xy + (KERNEL[i] * mapScale), shadowUv.z);
  88. shadowCol += shadow2D(shadowMap, uv).r;
  89. }
  90. shadowCol *= (1.0 / 9.0);
  91. return shadowCol;
  92. }
  93. #endif
  94. //======================================================================================================================
  95. // doPhong =
  96. //======================================================================================================================
  97. /// Performs phong lighting using the MS FAIs and a few other things
  98. /// @param fragPosVspace The fragment position in view space
  99. /// @param fragLightDist Output needed for the attenuation calculation
  100. /// @return The final color
  101. vec3 doPhong(in vec3 fragPosVspace, out float fragLightDist)
  102. {
  103. // get the vector from the frag to the light
  104. vec3 frag2LightVec = lightPos - fragPosVspace;
  105. // Instead of using normalize(frag2LightVec) we brake the operation because we want fragLightDist for the calc of
  106. // the attenuation
  107. fragLightDist = dot(frag2LightVec, frag2LightVec);
  108. vec3 lightDir = frag2LightVec * inversesqrt(fragLightDist);
  109. // Read the normal
  110. vec3 normal = unpackNormal(texture2D(msNormalFai, vTexCoords).rg);
  111. // Lambert term
  112. float lambertTerm = dot(normal, lightDir);
  113. /*if(lambertTerm < 0.0)
  114. {
  115. discard;
  116. }*/
  117. lambertTerm = max(0.0, lambertTerm);
  118. // Diffuce
  119. vec3 diffuse = texture2D(msDiffuseFai, vTexCoords).rgb;
  120. diffuse *= lightDiffuseCol;
  121. vec3 color = diffuse * lambertTerm;
  122. // Specular
  123. vec4 specularMix = texture2D(msSpecularFai, vTexCoords); // the MS specular FAI has the color and the shininess
  124. vec3 specular = specularMix.xyz;
  125. float shininess = specularMix.w * MAX_SHININESS;
  126. vec3 _eyeVec_ = normalize(-fragPosVspace);
  127. vec3 h = normalize(lightDir + _eyeVec_);
  128. float specIntensity = pow(max(0.0, dot(normal, h)), shininess);
  129. color += specular * lightSpecularCol * (specIntensity * lambertTerm);
  130. // end
  131. return color;
  132. }
  133. //======================================================================================================================
  134. // main =
  135. //======================================================================================================================
  136. void main()
  137. {
  138. // get frag pos in view space
  139. vec3 fragPosVspace = getFragPosVSpace();
  140. //
  141. // Point light
  142. //
  143. #if defined(POINT_LIGHT_ENABLED)
  144. // The func doPhong calculates the frag to light distance (fragLightDist) and be cause we need that distance
  145. // latter for other calculations we export it
  146. float fragLightDist;
  147. vec3 color = doPhong(fragPosVspace, fragLightDist);
  148. fColor = color * getAttenuation(fragLightDist);
  149. //
  150. // Spot light
  151. //
  152. #elif defined(SPOT_LIGHT_ENABLED)
  153. vec4 texCoords2 = texProjectionMat * vec4(fragPosVspace, 1.0);
  154. vec3 texCoords3 = texCoords2.xyz / texCoords2.w;
  155. if(texCoords2.w > 0.0 &&
  156. texCoords3.x > 0.0 &&
  157. texCoords3.x < 1.0 &&
  158. texCoords3.y > 0.0 &&
  159. texCoords3.y < 1.0 &&
  160. texCoords2.w < lightRadius)
  161. {
  162. // Get shadow
  163. #if defined(SHADOW_ENABLED)
  164. #if defined(PCF_ENABLED)
  165. float shadowCol = pcfLow(texCoords3);
  166. #else
  167. float shadowCol = shadow2D(shadowMap, texCoords3).r;
  168. #endif
  169. if(shadowCol == 0.0)
  170. {
  171. discard;
  172. }
  173. #endif
  174. float fragLightDist;
  175. vec3 color = doPhong(fragPosVspace, fragLightDist);
  176. vec3 lightTexCol = texture2DProj(lightTex, texCoords2.xyz).rgb;
  177. float att = getAttenuation(fragLightDist);
  178. #if defined(SHADOW_ENABLED)
  179. fColor = lightTexCol * color * (shadowCol * att);
  180. #else
  181. fColor = lightTexCol * color * att;
  182. #endif
  183. }
  184. else
  185. {
  186. discard;
  187. }
  188. #endif // spot light
  189. //fColor = fColor - fColor + vec3(1, 0, 1);
  190. //gl_FragData[0] = gl_FragData[0] - gl_FragData[0] + vec4(1, 0, 1, 1);
  191. /*#if defined(SPOT_LIGHT_ENABLED)
  192. fColor = fColor - fColor + vec3(1, 0, 1);
  193. //gl_FragData[0] = vec4(texture2D(msDepthFai, vTexCoords).rg), 1.0);
  194. #endif*/
  195. }