BRDF_GGX.js 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. import F_Schlick from './F_Schlick.js';
  2. import V_GGX_SmithCorrelated from './V_GGX_SmithCorrelated.js';
  3. import D_GGX from './D_GGX.js';
  4. import { transformedNormalView } from '../../accessors/NormalNode.js';
  5. import { positionViewDirection } from '../../accessors/PositionNode.js';
  6. import { iridescence } from '../../core/PropertyNode.js';
  7. import { tslFn } from '../../shadernode/ShaderNode.js';
  8. // GGX Distribution, Schlick Fresnel, GGX_SmithCorrelated Visibility
  9. const BRDF_GGX = tslFn( ( inputs ) => {
  10. const { lightDirection, f0, f90, roughness, iridescenceFresnel } = inputs;
  11. const normalView = inputs.normalView || transformedNormalView;
  12. const alpha = roughness.pow2(); // UE4's roughness
  13. const halfDir = lightDirection.add( positionViewDirection ).normalize();
  14. const dotNL = normalView.dot( lightDirection ).clamp();
  15. const dotNV = normalView.dot( positionViewDirection ).clamp(); // @ TODO: Move to core dotNV
  16. const dotNH = normalView.dot( halfDir ).clamp();
  17. const dotVH = positionViewDirection.dot( halfDir ).clamp();
  18. let F = F_Schlick( { f0, f90, dotVH } );
  19. if ( iridescenceFresnel ) {
  20. F = iridescence.mix( F, iridescenceFresnel );
  21. }
  22. const V = V_GGX_SmithCorrelated( { alpha, dotNL, dotNV } );
  23. const D = D_GGX( { alpha, dotNH } );
  24. return F.mul( V ).mul( D );
  25. } ); // validated
  26. export default BRDF_GGX;