BRDF_Sheen.js 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. import { transformedNormalView } from '../../accessors/NormalNode.js';
  2. import { positionViewDirection } from '../../accessors/PositionNode.js';
  3. import { sheen, sheenRoughness } from '../../core/PropertyNode.js';
  4. import { tslFn, float } from '../../shadernode/ShaderNode.js';
  5. // https://github.com/google/filament/blob/master/shaders/src/brdf.fs
  6. const D_Charlie = tslFn( ( { roughness, dotNH } ) => {
  7. const alpha = roughness.pow2();
  8. // Estevez and Kulla 2017, "Production Friendly Microfacet Sheen BRDF"
  9. const invAlpha = float( 1.0 ).div( alpha );
  10. const cos2h = dotNH.pow2();
  11. const sin2h = cos2h.oneMinus().max( 0.0078125 ); // 2^(-14/2), so sin2h^2 > 0 in fp16
  12. return float( 2.0 ).add( invAlpha ).mul( sin2h.pow( invAlpha.mul( 0.5 ) ) ).div( 2.0 * Math.PI );
  13. } ).setLayout( {
  14. name: 'D_Charlie',
  15. type: 'float',
  16. inputs: [
  17. { name: 'roughness', type: 'float' },
  18. { name: 'dotNH', type: 'float' }
  19. ]
  20. } );
  21. // https://github.com/google/filament/blob/master/shaders/src/brdf.fs
  22. const V_Neubelt = tslFn( ( { dotNV, dotNL } ) => {
  23. // Neubelt and Pettineo 2013, "Crafting a Next-gen Material Pipeline for The Order: 1886"
  24. return float( 1.0 ).div( float( 4.0 ).mul( dotNL.add( dotNV ).sub( dotNL.mul( dotNV ) ) ) );
  25. } ).setLayout( {
  26. name: 'V_Neubelt',
  27. type: 'float',
  28. inputs: [
  29. { name: 'dotNV', type: 'float' },
  30. { name: 'dotNL', type: 'float' }
  31. ]
  32. } );
  33. const BRDF_Sheen = tslFn( ( { lightDirection } ) => {
  34. const halfDir = lightDirection.add( positionViewDirection ).normalize();
  35. const dotNL = transformedNormalView.dot( lightDirection ).clamp();
  36. const dotNV = transformedNormalView.dot( positionViewDirection ).clamp();
  37. const dotNH = transformedNormalView.dot( halfDir ).clamp();
  38. const D = D_Charlie( { roughness: sheenRoughness, dotNH } );
  39. const V = V_Neubelt( { dotNV, dotNL } );
  40. return sheen.mul( D ).mul( V );
  41. } );
  42. export default BRDF_Sheen;