light.glsl 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. /* light.glsl -- Contains everything you need to manage lights
  2. *
  3. * Copyright (c) 2025-2026 Le Juez Victor
  4. *
  5. * This software is provided 'as-is', without any express or implied warranty.
  6. * For conditions of distribution and use, see accompanying LICENSE file.
  7. */
  8. /* === Includes === */
  9. #include "../math.glsl"
  10. #include "../pbr.glsl"
  11. /* === Defines === */
  12. // Should be defined in client side
  13. //#define NUM_FORWARD_LIGHTS 8
  14. #define LIGHT_DIR 0
  15. #define LIGHT_SPOT 1
  16. #define LIGHT_OMNI 2
  17. /* === Structures === */
  18. struct Light {
  19. mat4 viewProj;
  20. vec3 color;
  21. vec3 position;
  22. vec3 direction;
  23. float specular;
  24. float energy;
  25. float range;
  26. float near;
  27. float far;
  28. float attenuation;
  29. float innerCutOff;
  30. float outerCutOff;
  31. float shadowSoftness;
  32. float shadowDepthBias;
  33. float shadowSlopeBias;
  34. int shadowLayer; //< less than zero if no shadows
  35. int type;
  36. };
  37. /* === Uniform Block === */
  38. #ifdef NUM_FORWARD_LIGHTS
  39. layout(std140) uniform LightArrayBlock {
  40. Light uLights[NUM_FORWARD_LIGHTS];
  41. int uNumLights;
  42. };
  43. #else
  44. layout(std140) uniform LightBlock {
  45. Light uLight;
  46. };
  47. #endif
  48. /* === Functions === */
  49. vec3 L_Diffuse(float cLdotH, float cNdotV, float cNdotL, float roughness)
  50. {
  51. float FD90_minus_1 = 2.0 * cLdotH * cLdotH * roughness - 0.5;
  52. float FdV = 1.0 + FD90_minus_1 * PBR_SchlickFresnel(cNdotV);
  53. float FdL = 1.0 + FD90_minus_1 * PBR_SchlickFresnel(cNdotL);
  54. return vec3(M_INV_PI * (FdV * FdL * cNdotL)); // Diffuse BRDF (Burley)
  55. }
  56. vec3 L_Specular(vec3 F0, float cLdotH, float cNdotH, float cNdotV, float cNdotL, float roughness)
  57. {
  58. roughness = max(roughness, 0.02); // >0.01 to avoid FP16 overflow after GGX distribution
  59. float alphaGGX = roughness * roughness;
  60. float D = PBR_DistributionGGX(cNdotH, alphaGGX);
  61. float G = PBR_GeometryGGX(cNdotL, cNdotV, alphaGGX);
  62. float cLdotH5 = PBR_SchlickFresnel(cLdotH);
  63. float F90 = clamp(50.0 * F0.g, 0.0, 1.0);
  64. vec3 F = F0 + (F90 - F0) * cLdotH5;
  65. return cNdotL * D * F * G; // Specular BRDF (Schlick GGX)
  66. }