BRDF_GGX.js 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. import F_Schlick from './F_Schlick.js';
  2. import V_GGX_SmithCorrelated from './V_GGX_SmithCorrelated.js';
  3. import V_GGX_SmithCorrelated_Anisotropic from './V_GGX_SmithCorrelated_Anisotropic.js';
  4. import D_GGX from './D_GGX.js';
  5. import D_GGX_Anisotropic from './D_GGX_Anisotropic.js';
  6. import { transformedNormalView } from '../../accessors/NormalNode.js';
  7. import { positionViewDirection } from '../../accessors/PositionNode.js';
  8. import { iridescence, alphaT, anisotropyT, anisotropyB } from '../../core/PropertyNode.js';
  9. import { tslFn, defined } from '../../shadernode/ShaderNode.js';
  10. // GGX Distribution, Schlick Fresnel, GGX_SmithCorrelated Visibility
  11. const BRDF_GGX = tslFn( ( inputs ) => {
  12. const { lightDirection, f0, f90, roughness, f, USE_IRIDESCENCE, USE_ANISOTROPY } = inputs;
  13. const normalView = inputs.normalView || transformedNormalView;
  14. const alpha = roughness.pow2(); // UE4's roughness
  15. const halfDir = lightDirection.add( positionViewDirection ).normalize();
  16. const dotNL = normalView.dot( lightDirection ).clamp();
  17. const dotNV = normalView.dot( positionViewDirection ).clamp(); // @ TODO: Move to core dotNV
  18. const dotNH = normalView.dot( halfDir ).clamp();
  19. const dotVH = positionViewDirection.dot( halfDir ).clamp();
  20. let F = F_Schlick( { f0, f90, dotVH } );
  21. let V, D;
  22. if ( defined( USE_IRIDESCENCE ) ) {
  23. F = iridescence.mix( F, f );
  24. }
  25. if ( defined( USE_ANISOTROPY ) ) {
  26. const dotTL = anisotropyT.dot( lightDirection );
  27. const dotTV = anisotropyT.dot( positionViewDirection );
  28. const dotTH = anisotropyT.dot( halfDir );
  29. const dotBL = anisotropyB.dot( lightDirection );
  30. const dotBV = anisotropyB.dot( positionViewDirection );
  31. const dotBH = anisotropyB.dot( halfDir );
  32. V = V_GGX_SmithCorrelated_Anisotropic( { alphaT, alphaB: alpha, dotTV, dotBV, dotTL, dotBL, dotNV, dotNL } );
  33. D = D_GGX_Anisotropic( { alphaT, alphaB: alpha, dotNH, dotTH, dotBH } );
  34. } else {
  35. V = V_GGX_SmithCorrelated( { alpha, dotNL, dotNV } );
  36. D = D_GGX( { alpha, dotNH } );
  37. }
  38. return F.mul( V ).mul( D );
  39. } ); // validated
  40. export default BRDF_GGX;