MeshSSSNodeMaterial.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. import MeshPhysicalNodeMaterial from './MeshPhysicalNodeMaterial.js';
  2. import PhysicalLightingModel from '../../nodes/functions/PhysicalLightingModel.js';
  3. import { transformedNormalView } from '../../nodes/accessors/Normal.js';
  4. import { positionViewDirection } from '../../nodes/accessors/Position.js';
  5. import { float, vec3 } from '../../nodes/tsl/TSLBase.js';
  6. /**
  7. * Represents the lighting model for {@link MeshSSSNodeMaterial}.
  8. *
  9. * @augments PhysicalLightingModel
  10. */
  11. class SSSLightingModel extends PhysicalLightingModel {
  12. /**
  13. * Constructs a new physical lighting model.
  14. *
  15. * @param {boolean} [clearcoat=false] - Whether clearcoat is supported or not.
  16. * @param {boolean} [sheen=false] - Whether sheen is supported or not.
  17. * @param {boolean} [iridescence=false] - Whether iridescence is supported or not.
  18. * @param {boolean} [anisotropy=false] - Whether anisotropy is supported or not.
  19. * @param {boolean} [transmission=false] - Whether transmission is supported or not.
  20. * @param {boolean} [dispersion=false] - Whether dispersion is supported or not.
  21. * @param {boolean} [sss=false] - Whether SSS is supported or not.
  22. */
  23. constructor( clearcoat = false, sheen = false, iridescence = false, anisotropy = false, transmission = false, dispersion = false, sss = false ) {
  24. super( clearcoat, sheen, iridescence, anisotropy, transmission, dispersion );
  25. /**
  26. * Whether the lighting model should use SSS or not.
  27. *
  28. * @type {boolean}
  29. * @default false
  30. */
  31. this.useSSS = sss;
  32. }
  33. /**
  34. * Extends the default implementation with a SSS term.
  35. *
  36. * Reference: [Approximating Translucency for a Fast, Cheap and Convincing Subsurface Scattering Look]{@link https://colinbarrebrisebois.com/2011/03/07/gdc-2011-approximating-translucency-for-a-fast-cheap-and-convincing-subsurface-scattering-look/}
  37. *
  38. * @param {Object} input - The input data.
  39. * @param {NodeBuilder} builder - The current node builder.
  40. */
  41. direct( { lightDirection, lightColor, reflectedLight }, builder ) {
  42. if ( this.useSSS === true ) {
  43. const material = builder.material;
  44. const { thicknessColorNode, thicknessDistortionNode, thicknessAmbientNode, thicknessAttenuationNode, thicknessPowerNode, thicknessScaleNode } = material;
  45. const scatteringHalf = lightDirection.add( transformedNormalView.mul( thicknessDistortionNode ) ).normalize();
  46. const scatteringDot = float( positionViewDirection.dot( scatteringHalf.negate() ).saturate().pow( thicknessPowerNode ).mul( thicknessScaleNode ) );
  47. const scatteringIllu = vec3( scatteringDot.add( thicknessAmbientNode ).mul( thicknessColorNode ) );
  48. reflectedLight.directDiffuse.addAssign( scatteringIllu.mul( thicknessAttenuationNode.mul( lightColor ) ) );
  49. }
  50. super.direct( { lightDirection, lightColor, reflectedLight }, builder );
  51. }
  52. }
  53. /**
  54. * This node material is an experimental extension of {@link MeshPhysicalNodeMaterial}
  55. * that implements a Subsurface scattering (SSS) term.
  56. *
  57. * @augments MeshPhysicalNodeMaterial
  58. */
  59. class MeshSSSNodeMaterial extends MeshPhysicalNodeMaterial {
  60. static get type() {
  61. return 'MeshSSSNodeMaterial';
  62. }
  63. /**
  64. * Constructs a new mesh SSS node material.
  65. *
  66. * @param {Object} [parameters] - The configuration parameter.
  67. */
  68. constructor( parameters ) {
  69. super( parameters );
  70. /**
  71. * Represents the thickness color.
  72. *
  73. * @type {?Node<vec3>}
  74. * @default null
  75. */
  76. this.thicknessColorNode = null;
  77. /**
  78. * Represents the distortion factor.
  79. *
  80. * @type {?Node<float>}
  81. */
  82. this.thicknessDistortionNode = float( 0.1 );
  83. /**
  84. * Represents the thickness ambient factor.
  85. *
  86. * @type {?Node<float>}
  87. */
  88. this.thicknessAmbientNode = float( 0.0 );
  89. /**
  90. * Represents the thickness attenuation.
  91. *
  92. * @type {?Node<float>}
  93. */
  94. this.thicknessAttenuationNode = float( .1 );
  95. /**
  96. * Represents the thickness power.
  97. *
  98. * @type {?Node<float>}
  99. */
  100. this.thicknessPowerNode = float( 2.0 );
  101. /**
  102. * Represents the thickness scale.
  103. *
  104. * @type {?Node<float>}
  105. */
  106. this.thicknessScaleNode = float( 10.0 );
  107. }
  108. /**
  109. * Whether the lighting model should use SSS or not.
  110. *
  111. * @type {boolean}
  112. * @default true
  113. */
  114. get useSSS() {
  115. return this.thicknessColorNode !== null;
  116. }
  117. /**
  118. * Setups the lighting model.
  119. *
  120. * @return {SSSLightingModel} The lighting model.
  121. */
  122. setupLightingModel( /*builder*/ ) {
  123. return new SSSLightingModel( this.useClearcoat, this.useSheen, this.useIridescence, this.useAnisotropy, this.useTransmission, this.useDispersion, this.useSSS );
  124. }
  125. copy( source ) {
  126. this.thicknessColorNode = source.thicknessColorNode;
  127. this.thicknessDistortionNode = source.thicknessDistortionNode;
  128. this.thicknessAmbientNode = source.thicknessAmbientNode;
  129. this.thicknessAttenuationNode = source.thicknessAttenuationNode;
  130. this.thicknessPowerNode = source.thicknessPowerNode;
  131. this.thicknessScaleNode = source.thicknessScaleNode;
  132. return super.copy( source );
  133. }
  134. }
  135. export default MeshSSSNodeMaterial;
粤ICP备19079148号