BSDFs.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. import FunctionNode from '../core/FunctionNode.js';
  2. export const F_Schlick = new FunctionNode( `
  3. vec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {
  4. // Original approximation by Christophe Schlick '94
  5. // float fresnel = pow( 1.0 - dotLH, 5.0 );
  6. // Optimized variant (presented by Epic at SIGGRAPH '13)
  7. // https://cdn2.unrealengine.com/Resources/files/2013SiggraphPresentationsNotes-26915738.pdf
  8. float fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );
  9. return ( 1.0 - specularColor ) * fresnel + specularColor;
  10. }` ); // validated
  11. export const G_BlinnPhong_Implicit = new FunctionNode( `
  12. float G_BlinnPhong_Implicit() {
  13. // ( const in float dotNL, const in float dotNV )
  14. // geometry term is (n dot l)(n dot v) / 4(n dot l)(n dot v)
  15. return 0.25;
  16. }` ); // validated
  17. export const D_BlinnPhong = new FunctionNode( `
  18. float D_BlinnPhong( const in float shininess, const in float dotNH ) {
  19. return RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );
  20. }` ); // validated
  21. export const BRDF_Diffuse_Lambert = new FunctionNode( `
  22. vec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {
  23. return RECIPROCAL_PI * diffuseColor;
  24. }` ); // validated
  25. export const BRDF_Specular_BlinnPhong = new FunctionNode( `
  26. vec3 BRDF_Specular_BlinnPhong( vec3 lightDirection, vec3 specularColor, float shininess ) {
  27. vec3 halfDir = normalize( lightDirection + PositionViewDirection );
  28. //float dotNL = saturate( dot( NormalView, lightDirection ) );
  29. //float dotNV = saturate( dot( NormalView, PositionViewDirection ) );
  30. float dotNH = saturate( dot( NormalView, halfDir ) );
  31. float dotLH = saturate( dot( lightDirection, halfDir ) );
  32. vec3 F = F_Schlick( specularColor, dotLH );
  33. float G = G_BlinnPhong_Implicit( /* dotNL, dotNV */ );
  34. float D = D_BlinnPhong( shininess, dotNH );
  35. return F * ( G * D );
  36. }` ).setIncludes( [ F_Schlick, G_BlinnPhong_Implicit, D_BlinnPhong ] ); // validated
  37. export const punctualLightIntensityToIrradianceFactor = new FunctionNode( `
  38. float punctualLightIntensityToIrradianceFactor( float lightDistance, float cutoffDistance, float decayExponent ) {
  39. #if defined ( PHYSICALLY_CORRECT_LIGHTS )
  40. // based upon Frostbite 3 Moving to Physically-based Rendering
  41. // page 32, equation 26: E[window1]
  42. // https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf
  43. // this is intended to be used on spot and point lights who are represented as luminous intensity
  44. // but who must be converted to luminous irradiance for surface lighting calculation
  45. float distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );
  46. if( cutoffDistance > 0.0 ) {
  47. distanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );
  48. }
  49. return distanceFalloff;
  50. #else
  51. if( cutoffDistance > 0.0 && decayExponent > 0.0 ) {
  52. return pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );
  53. }
  54. return 1.0;
  55. #endif
  56. }` );
  57. export const RE_Direct_BlinnPhong = new FunctionNode( `
  58. void RE_Direct_BlinnPhong( vec3 lightDirection, vec3 lightColor ) {
  59. float dotNL = saturate( dot( NormalView, lightDirection ) );
  60. vec3 irradiance = dotNL * lightColor;
  61. #ifndef PHYSICALLY_CORRECT_LIGHTS
  62. irradiance *= PI; // punctual light
  63. #endif
  64. ReflectedLightDirectDiffuse += irradiance * BRDF_Diffuse_Lambert( MaterialDiffuseColor.rgb );
  65. ReflectedLightDirectSpecular += irradiance * BRDF_Specular_BlinnPhong( lightDirection, MaterialSpecularColor, MaterialSpecularShininess );
  66. }` ).setIncludes( [ BRDF_Diffuse_Lambert, BRDF_Specular_BlinnPhong ] );
  67. export const RE_IndirectDiffuse_BlinnPhong = new FunctionNode( `
  68. void RE_IndirectDiffuse_BlinnPhong( ) {
  69. ReflectedLightIndirectDiffuse += Irradiance * BRDF_Diffuse_Lambert( MaterialDiffuseColor.rgb );
  70. }` ).setIncludes( [ BRDF_Diffuse_Lambert ] );