common.glsl 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. #define PI 3.14159
  2. #define PI2 6.28318
  3. #define RECIPROCAL_PI 0.31830988618
  4. #define RECIPROCAL_PI2 0.15915494
  5. #define LOG2 1.442695
  6. #define EPSILON 1e-6
  7. #define PHYSICALLY_BASED_RENDERING
  8. #define saturate(a) clamp( a, 0.0, 1.0 )
  9. #define whiteCompliment(a) ( 1.0 - saturate( a ) )
  10. vec3 transformDirection( in vec3 normal, in mat4 matrix ) {
  11. return normalize( ( matrix * vec4( normal, 0.0 ) ).xyz );
  12. }
  13. // http://en.wikibooks.org/wiki/GLSL_Programming/Applying_Matrix_Transformations
  14. vec3 inverseTransformDirection( in vec3 normal, in mat4 matrix ) {
  15. return normalize( ( vec4( normal, 0.0 ) * matrix ).xyz );
  16. }
  17. vec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {
  18. float distance = dot( planeNormal, point - pointOnPlane );
  19. return - distance * planeNormal + point;
  20. }
  21. float sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {
  22. return sign( dot( point - pointOnPlane, planeNormal ) );
  23. }
  24. vec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {
  25. return lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;
  26. }
  27. float calcLightAttenuation( float lightDistance, float cutoffDistance, float decayExponent ) {
  28. if ( decayExponent > 0.0 ) {
  29. return pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );
  30. }
  31. return 1.0;
  32. }
  33. vec3 inputToLinear( in vec3 a ) {
  34. #ifdef GAMMA_INPUT
  35. return pow( a, vec3( float( GAMMA_FACTOR ) ) );
  36. #else
  37. return a;
  38. #endif
  39. }
  40. vec3 linearToOutput( in vec3 a ) {
  41. #ifdef GAMMA_OUTPUT
  42. return pow( a, vec3( 1.0 / float( GAMMA_FACTOR ) ) );
  43. #else
  44. return a;
  45. #endif
  46. }
  47. struct IncidentLight {
  48. vec3 color;
  49. vec3 direction;
  50. };
  51. struct ReflectedLight {
  52. vec3 specular;
  53. vec3 diffuse;
  54. };
  55. void BRDF_Lambert( const in IncidentLight incidentLight, const in vec3 normal, const in vec3 diffuseColor, inout ReflectedLight reflectedLight ) {
  56. reflectedLight.diffuse += incidentLight.color * diffuseColor * ( saturate( dot( normal, incidentLight.direction ) ) );
  57. // the above should be scaled by '' * RECIPROCAL_PI'
  58. }
  59. vec3 F_Schlick( const in vec3 F0, const in float dotLH ) {
  60. // Original approximation by Christophe Schlick '94
  61. //;float fresnel = pow( 1.0 - dotLH, 5.0 );
  62. // Optimized variant (presented by Epic at SIGGRAPH '13)
  63. float fresnel = exp2( ( -5.55437 * dotLH - 6.98316 ) * dotLH );
  64. return F0 + ( 1.0 - F0 ) * fresnel;
  65. }
  66. float G_BlinnPhong_Implicit( /* in float dotNL, in float dotNV */ ) {
  67. // geometry term is (n dot l)(n dot v) / 4(n dot l)(n dot v)
  68. return 0.25;
  69. }
  70. float D_BlinnPhong( const in float shininess, const in float dotNH ) {
  71. // factor of 1/PI in distribution term omitted
  72. return ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );
  73. }
  74. void BRDF_BlinnPhong( const in IncidentLight incidentLight, const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float shininess, inout ReflectedLight reflectedLight ) {
  75. vec3 halfDir = normalize( incidentLight.direction + viewDir );
  76. float dotNH = saturate( dot( normal, halfDir ) );
  77. float dotLH = saturate( dot( incidentLight.direction, halfDir ) );
  78. vec3 F = F_Schlick( specularColor, dotLH );
  79. float G = G_BlinnPhong_Implicit( /* dotNL, dotNV */ );
  80. float D = D_BlinnPhong( shininess, dotNH );
  81. reflectedLight.specular += incidentLight.color * F * ( G * D );
  82. }
  83. #if MAX_DIR_LIGHTS > 0
  84. struct DirectionalLight {
  85. vec3 direction;
  86. vec3 color;
  87. };
  88. uniform DirectionalLight directionalLights[ MAX_DIR_LIGHTS ];
  89. void getDirIncidentLight( const in DirectionalLight directionalLight, out IncidentLight incidentLight ) {
  90. incidentLight.color = directionalLight.color;
  91. incidentLight.direction = directionalLight.direction;
  92. }
  93. #endif
  94. #if MAX_POINT_LIGHTS > 0
  95. struct PointLight {
  96. vec3 position;
  97. vec3 color;
  98. float distance;
  99. float decay;
  100. };
  101. uniform PointLight pointLights[ MAX_POINT_LIGHTS ];
  102. void getPointIncidentLight( const in PointLight pointLight, const in vec3 position, out IncidentLight incidentLight ) {
  103. vec3 lightPosition = pointLight.position;
  104. vec3 lVector = lightPosition - position;
  105. incidentLight.direction = normalize( lVector );
  106. incidentLight.color = pointLight.color;
  107. incidentLight.color *= calcLightAttenuation( length( lVector ), pointLight.distance, pointLight.decay );
  108. }
  109. #endif
  110. #if MAX_SPOT_LIGHTS > 0
  111. struct SpotLight {
  112. vec3 position;
  113. vec3 direction;
  114. vec3 color;
  115. float distance;
  116. float decay;
  117. float angleCos;
  118. float exponent;
  119. };
  120. uniform SpotLight spotLights[ MAX_SPOT_LIGHTS ];
  121. void getSpotIncidentLight( const in SpotLight spotLight, const in vec3 position, out IncidentLight incidentLight ) {
  122. vec3 lightPosition = spotLight.position;
  123. vec3 lVector = lightPosition - position;
  124. incidentLight.direction = normalize( lVector );
  125. float spotEffect = dot( spotLight.direction, incidentLight.direction );
  126. spotEffect = saturate( pow( saturate( spotEffect ), spotLight.exponent ) );
  127. incidentLight.color = spotLight.color;
  128. incidentLight.color *= ( spotEffect * calcLightAttenuation( length( lVector ), spotLight.distance, spotLight.decay ) );
  129. }
  130. #endif
  131. #if MAX_HEMI_LIGHTS > 0
  132. struct HemisphereLight {
  133. vec3 direction;
  134. vec3 skyColor;
  135. vec3 groundColor;
  136. };
  137. layout(packed)uniform HemisphereLight hemisphereLights[ MAX_HEMI_LIGHTS ];
  138. void getHemisphereIncidentLight( const in HemisphereLight hemiLight, const in vec3 normal, out IncidentLight incidentLight ) {
  139. float dotNL = dot( normal, hemiLight.direction );
  140. float hemiDiffuseWeight = 0.5 * dotNL + 0.5;
  141. incidentLight.color = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );
  142. incidentLight.direction = normal;
  143. }
  144. #endif