chunkPhongModel.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. // Copyright 2016 The G3N Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package shader
  5. func init() {
  6. AddChunk("phong_model", chunkPhongModel)
  7. }
  8. const chunkPhongModel = `
  9. /***
  10. phong lighting model
  11. Parameters:
  12. position: input vertex position in camera coordinates
  13. normal: input vertex normal in camera coordinates
  14. camDir: input camera directions
  15. matAmbient: input material ambient color
  16. matDiffuse: input material diffuse color
  17. ambdiff: output ambient+diffuse color
  18. spec: output specular color
  19. Uniforms:
  20. AmbientLightColor[]
  21. DiffuseLightColor[]
  22. DiffuseLightPosition[]
  23. PointLightColor[]
  24. PointLightPosition[];
  25. PointLightLinearDecay[];
  26. PointLightQuadraticDecay[];
  27. MatSpecularColor
  28. MatShininess
  29. */
  30. void phongModel(vec4 position, vec3 normal, vec3 camDir, vec3 matAmbient, vec3 matDiffuse, out vec3 ambdiff, out vec3 spec) {
  31. vec3 ambientTotal = vec3(0.0);
  32. vec3 diffuseTotal = vec3(0.0);
  33. vec3 specularTotal = vec3(0.0);
  34. {{ range loop .AmbientLightsMax }}
  35. ambientTotal += AmbientLightColor[{{.}}] * matAmbient;
  36. {{ end }}
  37. {{ range loop .DirLightsMax }}
  38. {
  39. // Diffuse reflection
  40. // DirLightPosition is the direction of the current light
  41. vec3 lightDirection = normalize(DirLightPosition({{.}}));
  42. // Calculates the dot product between the light direction and this vertex normal.
  43. float dotNormal = max(dot(lightDirection, normal), 0.0);
  44. diffuseTotal += DirLightColor({{.}}) * matDiffuse * dotNormal;
  45. // Specular reflection
  46. // Calculates the light reflection vector
  47. vec3 ref = reflect(-lightDirection, normal);
  48. if (dotNormal > 0.0) {
  49. specularTotal += DirLightColor({{.}}) * MatSpecularColor * pow(max(dot(ref, camDir), 0.0), MatShininess);
  50. }
  51. }
  52. {{ end }}
  53. {{ range loop .PointLightsMax }}
  54. {
  55. // Calculates the direction and distance from the current vertex to this point light.
  56. vec3 lightDirection = PointLightPosition({{.}}) - vec3(position);
  57. float lightDistance = length(lightDirection);
  58. // Normalizes the lightDirection
  59. lightDirection = lightDirection / lightDistance;
  60. // Calculates the attenuation due to the distance of the light
  61. float attenuation = 1.0 / (1.0 + PointLightLinearDecay({{.}}) * lightDistance +
  62. PointLightQuadraticDecay({{.}}) * lightDistance * lightDistance);
  63. // Diffuse reflection
  64. float dotNormal = max(dot(lightDirection, normal), 0.0);
  65. diffuseTotal += PointLightColor({{.}}) * matDiffuse * dotNormal * attenuation;
  66. // Specular reflection
  67. // Calculates the light reflection vector
  68. vec3 ref = reflect(-lightDirection, normal);
  69. if (dotNormal > 0.0) {
  70. specularTotal += PointLightColor({{.}}) * MatSpecularColor *
  71. pow(max(dot(ref, camDir), 0.0), MatShininess) * attenuation;
  72. }
  73. }
  74. {{ end }}
  75. {{ range loop .SpotLightsMax }}
  76. {
  77. // Calculates the direction and distance from the current vertex to this spot light.
  78. vec3 lightDirection = SpotLightPosition({{.}}) - vec3(position);
  79. float lightDistance = length(lightDirection);
  80. lightDirection = lightDirection / lightDistance;
  81. // Calculates the attenuation due to the distance of the light
  82. float attenuation = 1.0 / (1.0 + SpotLightLinearDecay({{.}}) * lightDistance +
  83. SpotLightQuadraticDecay({{.}}) * lightDistance * lightDistance);
  84. // Calculates the angle between the vertex direction and spot direction
  85. // If this angle is greater than the cutoff the spotlight will not contribute
  86. // to the final color.
  87. float angle = acos(dot(-lightDirection, SpotLightDirection({{.}})));
  88. float cutoff = radians(clamp(SpotLightCutoffAngle({{.}}), 0.0, 90.0));
  89. if (angle < cutoff) {
  90. float spotFactor = pow(dot(-lightDirection, SpotLightDirection({{.}})), SpotLightAngularDecay({{.}}));
  91. // Diffuse reflection
  92. float dotNormal = max(dot(lightDirection, normal), 0.0);
  93. diffuseTotal += SpotLightColor({{.}}) * matDiffuse * dotNormal * attenuation * spotFactor;
  94. // Specular reflection
  95. vec3 ref = reflect(-lightDirection, normal);
  96. if (dotNormal > 0.0) {
  97. specularTotal += SpotLightColor({{.}}) * MatSpecularColor * pow(max(dot(ref, camDir), 0.0), MatShininess) * attenuation * spotFactor;
  98. }
  99. }
  100. }
  101. {{ end }}
  102. // Sets output colors
  103. ambdiff = ambientTotal + MatEmissiveColor + diffuseTotal;
  104. spec = specularTotal;
  105. }
  106. `