phong_model.glsl 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /***
  2. phong lighting model
  3. Parameters:
  4. position: input vertex position in camera coordinates
  5. normal: input vertex normal in camera coordinates
  6. camDir: input camera directions
  7. matAmbient: input material ambient color
  8. matDiffuse: input material diffuse color
  9. ambdiff: output ambient+diffuse color
  10. spec: output specular color
  11. Uniforms:
  12. AmbientLightColor[]
  13. DiffuseLightColor[]
  14. DiffuseLightPosition[]
  15. PointLightColor[]
  16. PointLightPosition[]
  17. PointLightLinearDecay[]
  18. PointLightQuadraticDecay[]
  19. MatSpecularColor
  20. MatShininess
  21. *****/
  22. void phongModel(vec4 position, vec3 normal, vec3 camDir, vec3 matAmbient, vec3 matDiffuse, out vec3 ambdiff, out vec3 spec) {
  23. vec3 ambientTotal = vec3(0.0);
  24. vec3 diffuseTotal = vec3(0.0);
  25. vec3 specularTotal = vec3(0.0);
  26. #if AMB_LIGHTS>0
  27. // Ambient lights
  28. for (int i = 0; i < AMB_LIGHTS; i++) {
  29. ambientTotal += AmbientLightColor[i] * matAmbient;
  30. }
  31. #endif
  32. #if DIR_LIGHTS>0
  33. // Directional lights
  34. for (int i = 0; i < DIR_LIGHTS; i++) {
  35. // Diffuse reflection
  36. // DirLightPosition is the direction of the current light
  37. vec3 lightDirection = normalize(DirLightPosition(i));
  38. // Calculates the dot product between the light direction and this vertex normal.
  39. float dotNormal = max(dot(lightDirection, normal), 0.0);
  40. diffuseTotal += DirLightColor(i) * matDiffuse * dotNormal;
  41. // Specular reflection
  42. // Calculates the light reflection vector
  43. vec3 ref = reflect(-lightDirection, normal);
  44. if (dotNormal > 0.0) {
  45. specularTotal += DirLightColor(i) * MatSpecularColor * pow(max(dot(ref, camDir), 0.0), MatShininess);
  46. }
  47. }
  48. #endif
  49. #if POINT_LIGHTS>0
  50. // Point lights
  51. for (int i = 0; i < POINT_LIGHTS; i++) {
  52. // Common calculations
  53. // Calculates the direction and distance from the current vertex to this point light.
  54. vec3 lightDirection = PointLightPosition(i) - vec3(position);
  55. float lightDistance = length(lightDirection);
  56. // Normalizes the lightDirection
  57. lightDirection = lightDirection / lightDistance;
  58. // Calculates the attenuation due to the distance of the light
  59. float attenuation = 1.0 / (1.0 + PointLightLinearDecay(i) * lightDistance +
  60. PointLightQuadraticDecay(i) * lightDistance * lightDistance);
  61. // Diffuse reflection
  62. float dotNormal = max(dot(lightDirection, normal), 0.0);
  63. diffuseTotal += PointLightColor(i) * matDiffuse * dotNormal * attenuation;
  64. // Specular reflection
  65. // Calculates the light reflection vector
  66. vec3 ref = reflect(-lightDirection, normal);
  67. if (dotNormal > 0.0) {
  68. specularTotal += PointLightColor(i) * MatSpecularColor *
  69. pow(max(dot(ref, camDir), 0.0), MatShininess) * attenuation;
  70. }
  71. }
  72. #endif
  73. #if SPOT_LIGHTS>0
  74. for (int i = 0; i < SPOT_LIGHTS; i++) {
  75. // Calculates the direction and distance from the current vertex to this spot light.
  76. vec3 lightDirection = SpotLightPosition(i) - vec3(position);
  77. float lightDistance = length(lightDirection);
  78. lightDirection = lightDirection / lightDistance;
  79. // Calculates the attenuation due to the distance of the light
  80. float attenuation = 1.0 / (1.0 + SpotLightLinearDecay(i) * lightDistance +
  81. SpotLightQuadraticDecay(i) * lightDistance * lightDistance);
  82. // Calculates the angle between the vertex direction and spot direction
  83. // If this angle is greater than the cutoff the spotlight will not contribute
  84. // to the final color.
  85. float angle = acos(dot(-lightDirection, SpotLightDirection(i)));
  86. float cutoff = radians(clamp(SpotLightCutoffAngle(i), 0.0, 90.0));
  87. if (angle < cutoff) {
  88. float spotFactor = pow(dot(-lightDirection, SpotLightDirection(i)), SpotLightAngularDecay(i));
  89. // Diffuse reflection
  90. float dotNormal = max(dot(lightDirection, normal), 0.0);
  91. diffuseTotal += SpotLightColor(i) * matDiffuse * dotNormal * attenuation * spotFactor;
  92. // Specular reflection
  93. vec3 ref = reflect(-lightDirection, normal);
  94. if (dotNormal > 0.0) {
  95. specularTotal += SpotLightColor(i) * MatSpecularColor * pow(max(dot(ref, camDir), 0.0), MatShininess) * attenuation * spotFactor;
  96. }
  97. }
  98. }
  99. #endif
  100. // Sets output colors
  101. ambdiff = ambientTotal + MatEmissiveColor + diffuseTotal;
  102. spec = specularTotal;
  103. }