@needle-tools/three 0.153.0 → 0.154.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/build/three.cjs +112 -364
  2. package/build/three.js +112 -364
  3. package/build/three.min.js +1 -1
  4. package/build/three.module.js +113 -346
  5. package/build/three.module.min.js +1 -1
  6. package/examples/jsm/controls/ArcballControls.js +2 -1
  7. package/examples/jsm/controls/FlyControls.js +25 -9
  8. package/examples/jsm/controls/OrbitControls.js +7 -1
  9. package/examples/jsm/csm/CSM.js +1 -1
  10. package/examples/jsm/effects/AnaglyphEffect.js +1 -1
  11. package/examples/jsm/effects/OutlineEffect.js +1 -1
  12. package/examples/jsm/effects/ParallaxBarrierEffect.js +1 -1
  13. package/examples/jsm/environments/RoomEnvironment.js +6 -2
  14. package/examples/jsm/lines/LineMaterial.js +1 -1
  15. package/examples/jsm/loaders/3DMLoader.js +1 -1
  16. package/examples/jsm/loaders/3MFLoader.js +5 -1
  17. package/examples/jsm/loaders/AMFLoader.js +5 -1
  18. package/examples/jsm/loaders/ColladaLoader.js +4 -1
  19. package/examples/jsm/loaders/FBXLoader.js +9 -2
  20. package/examples/jsm/loaders/LDrawLoader.js +4 -7
  21. package/examples/jsm/loaders/PLYLoader.js +16 -6
  22. package/examples/jsm/loaders/VRMLLoader.js +16 -4
  23. package/examples/jsm/materials/MeshGouraudMaterial.js +2 -2
  24. package/examples/jsm/math/MeshSurfaceSampler.js +76 -35
  25. package/examples/jsm/nodes/Nodes.js +20 -15
  26. package/examples/jsm/nodes/accessors/BufferAttributeNode.js +21 -8
  27. package/examples/jsm/nodes/accessors/CameraNode.js +25 -4
  28. package/examples/jsm/nodes/accessors/ExtendedMaterialNode.js +7 -1
  29. package/examples/jsm/nodes/accessors/InstanceNode.js +2 -4
  30. package/examples/jsm/nodes/accessors/MaterialNode.js +55 -47
  31. package/examples/jsm/nodes/accessors/ModelNode.js +3 -1
  32. package/examples/jsm/nodes/accessors/MorphNode.js +70 -0
  33. package/examples/jsm/nodes/accessors/NormalNode.js +3 -2
  34. package/examples/jsm/nodes/accessors/Object3DNode.js +10 -2
  35. package/examples/jsm/nodes/accessors/SceneNode.js +46 -0
  36. package/examples/jsm/nodes/accessors/SkinningNode.js +43 -62
  37. package/examples/jsm/nodes/accessors/TangentNode.js +2 -2
  38. package/examples/jsm/nodes/accessors/TextureBicubicNode.js +94 -0
  39. package/examples/jsm/nodes/accessors/TextureNode.js +68 -6
  40. package/examples/jsm/nodes/accessors/TextureSizeNode.js +35 -0
  41. package/examples/jsm/nodes/accessors/UVNode.js +1 -1
  42. package/examples/jsm/nodes/code/CodeNode.js +3 -0
  43. package/examples/jsm/nodes/code/FunctionNode.js +25 -4
  44. package/examples/jsm/nodes/core/BypassNode.js +2 -2
  45. package/examples/jsm/nodes/core/ContextNode.js +2 -0
  46. package/examples/jsm/nodes/core/IndexNode.js +66 -0
  47. package/examples/jsm/nodes/core/LightingModel.js +2 -1
  48. package/examples/jsm/nodes/core/Node.js +12 -15
  49. package/examples/jsm/nodes/core/NodeBuilder.js +24 -5
  50. package/examples/jsm/nodes/core/PropertyNode.js +4 -0
  51. package/examples/jsm/nodes/core/StackNode.js +1 -1
  52. package/examples/jsm/nodes/core/UniformNode.js +1 -1
  53. package/examples/jsm/nodes/core/VarNode.js +1 -3
  54. package/examples/jsm/nodes/display/BlendModeNode.js +9 -9
  55. package/examples/jsm/nodes/display/ColorAdjustmentNode.js +7 -7
  56. package/examples/jsm/nodes/display/ColorSpaceNode.js +50 -49
  57. package/examples/jsm/nodes/display/NormalMapNode.js +3 -3
  58. package/examples/jsm/nodes/display/ToneMappingNode.js +8 -8
  59. package/examples/jsm/nodes/display/ViewportDepthNode.js +69 -0
  60. package/examples/jsm/nodes/display/ViewportDepthTextureNode.js +34 -0
  61. package/examples/jsm/nodes/display/ViewportSharedTextureNode.js +6 -5
  62. package/examples/jsm/nodes/display/ViewportTextureNode.js +23 -15
  63. package/examples/jsm/nodes/functions/BSDF/BRDF_BlinnPhong.js +5 -5
  64. package/examples/jsm/nodes/functions/BSDF/BRDF_GGX.js +10 -8
  65. package/examples/jsm/nodes/functions/BSDF/BRDF_Lambert.js +2 -2
  66. package/examples/jsm/nodes/functions/BSDF/BRDF_Sheen.js +43 -0
  67. package/examples/jsm/nodes/functions/BSDF/DFGApprox.js +4 -4
  68. package/examples/jsm/nodes/functions/BSDF/D_GGX.js +2 -2
  69. package/examples/jsm/nodes/functions/BSDF/EnvironmentBRDF.js +13 -0
  70. package/examples/jsm/nodes/functions/BSDF/F_Schlick.js +2 -4
  71. package/examples/jsm/nodes/functions/BSDF/V_GGX_SmithCorrelated.js +2 -2
  72. package/examples/jsm/nodes/functions/PhongLightingModel.js +7 -7
  73. package/examples/jsm/nodes/functions/PhysicalLightingModel.js +129 -18
  74. package/examples/jsm/nodes/functions/material/getGeometryRoughness.js +2 -2
  75. package/examples/jsm/nodes/functions/material/getRoughness.js +3 -3
  76. package/examples/jsm/nodes/geometry/RangeNode.js +1 -1
  77. package/examples/jsm/nodes/lighting/DirectionalLightNode.js +2 -2
  78. package/examples/jsm/nodes/lighting/EnvironmentNode.js +91 -62
  79. package/examples/jsm/nodes/lighting/LightUtils.js +2 -2
  80. package/examples/jsm/nodes/lighting/LightingContextNode.js +17 -15
  81. package/examples/jsm/nodes/lighting/PointLightNode.js +3 -3
  82. package/examples/jsm/nodes/lighting/SpotLightNode.js +3 -3
  83. package/examples/jsm/nodes/materials/LineBasicNodeMaterial.js +0 -15
  84. package/examples/jsm/nodes/materials/MeshBasicNodeMaterial.js +0 -15
  85. package/examples/jsm/nodes/materials/MeshNormalNodeMaterial.js +0 -10
  86. package/examples/jsm/nodes/materials/MeshPhongNodeMaterial.js +0 -9
  87. package/examples/jsm/nodes/materials/MeshPhysicalNodeMaterial.js +41 -0
  88. package/examples/jsm/nodes/materials/MeshStandardNodeMaterial.js +1 -14
  89. package/examples/jsm/nodes/materials/NodeMaterial.js +79 -28
  90. package/examples/jsm/nodes/materials/PointsNodeMaterial.js +0 -9
  91. package/examples/jsm/nodes/materials/SpriteNodeMaterial.js +0 -7
  92. package/examples/jsm/nodes/materialx/lib/mx_hsv.js +3 -3
  93. package/examples/jsm/nodes/materialx/lib/mx_noise.js +14 -14
  94. package/examples/jsm/nodes/materialx/lib/mx_transform_color.js +4 -4
  95. package/examples/jsm/nodes/math/MathNode.js +6 -0
  96. package/examples/jsm/nodes/math/OperatorNode.js +1 -1
  97. package/examples/jsm/nodes/procedural/CheckerNode.js +3 -3
  98. package/examples/jsm/nodes/shadernode/ShaderNode.js +24 -4
  99. package/examples/jsm/nodes/utils/LoopNode.js +1 -1
  100. package/examples/jsm/nodes/utils/TriplanarTexturesNode.js +1 -1
  101. package/examples/jsm/objects/GroundProjectedSkybox.js +1 -1
  102. package/examples/jsm/objects/Reflector.js +1 -1
  103. package/examples/jsm/objects/Refractor.js +1 -1
  104. package/examples/jsm/objects/Sky.js +1 -1
  105. package/examples/jsm/objects/Water.js +1 -1
  106. package/examples/jsm/objects/Water2.js +1 -1
  107. package/examples/jsm/offscreen/scene.js +1 -0
  108. package/examples/jsm/postprocessing/EffectComposer.js +2 -0
  109. package/examples/jsm/postprocessing/OutlinePass.js +1 -3
  110. package/examples/jsm/postprocessing/SSAARenderPass.js +3 -12
  111. package/examples/jsm/postprocessing/SavePass.js +3 -1
  112. package/examples/jsm/postprocessing/TAARenderPass.js +14 -2
  113. package/examples/jsm/postprocessing/TexturePass.js +2 -1
  114. package/examples/jsm/postprocessing/UnrealBloomPass.js +9 -10
  115. package/examples/jsm/renderers/common/Backend.js +2 -0
  116. package/examples/jsm/renderers/common/Background.js +7 -6
  117. package/examples/jsm/renderers/common/Pipelines.js +26 -14
  118. package/examples/jsm/renderers/common/RenderObject.js +18 -0
  119. package/examples/jsm/renderers/common/RenderObjects.js +29 -29
  120. package/examples/jsm/renderers/common/Renderer.js +48 -6
  121. package/examples/jsm/renderers/common/nodes/Nodes.js +1 -1
  122. package/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js +340 -0
  123. package/examples/jsm/renderers/webgl/nodes/WebGLNodeBuilder.js +23 -19
  124. package/examples/jsm/renderers/webgpu/WebGPUBackend.js +123 -41
  125. package/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js +29 -9
  126. package/examples/jsm/renderers/webgpu/utils/WebGPUAttributeUtils.js +4 -0
  127. package/examples/jsm/renderers/webgpu/utils/WebGPUPipelineUtils.js +8 -13
  128. package/examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js +85 -3
  129. package/examples/jsm/renderers/webgpu/utils/WebGPUUtils.js +5 -1
  130. package/examples/jsm/shaders/BlendShader.js +1 -2
  131. package/examples/jsm/shaders/BokehShader2.js +1 -1
  132. package/examples/jsm/shaders/CopyShader.js +2 -2
  133. package/examples/jsm/shaders/ToonShader.js +4 -4
  134. package/examples/jsm/shaders/WaterRefractionShader.js +1 -1
  135. package/examples/jsm/webxr/OculusHandPointerModel.js +34 -13
  136. package/package.json +2 -1
  137. package/src/Three.Legacy.js +0 -228
  138. package/src/animation/PropertyBinding.js +1 -1
  139. package/src/constants.js +1 -1
  140. package/src/core/BufferAttribute.js +0 -24
  141. package/src/core/BufferGeometry.js +0 -7
  142. package/src/loaders/Loader.js +2 -0
  143. package/src/loaders/MaterialLoader.js +1 -0
  144. package/src/materials/Material.js +3 -0
  145. package/src/objects/Skeleton.js +0 -2
  146. package/src/renderers/WebGLRenderer.js +9 -21
  147. package/src/renderers/shaders/ShaderChunk/alphahash_fragment.glsl.js +7 -0
  148. package/src/renderers/shaders/ShaderChunk/alphahash_pars_fragment.glsl.js +68 -0
  149. package/src/renderers/shaders/ShaderChunk/begin_vertex.glsl.js +6 -0
  150. package/src/renderers/shaders/ShaderChunk/common.glsl.js +6 -0
  151. package/src/renderers/shaders/ShaderChunk/normal_fragment_begin.glsl.js +9 -1
  152. package/src/renderers/shaders/ShaderChunk/uv_pars_fragment.glsl.js +1 -1
  153. package/src/renderers/shaders/ShaderChunk/uv_pars_vertex.glsl.js +1 -1
  154. package/src/renderers/shaders/ShaderChunk/uv_vertex.glsl.js +1 -1
  155. package/src/renderers/shaders/ShaderChunk.js +10 -6
  156. package/src/renderers/shaders/ShaderLib/background.glsl.js +1 -1
  157. package/src/renderers/shaders/ShaderLib/backgroundCube.glsl.js +1 -1
  158. package/src/renderers/shaders/ShaderLib/cube.glsl.js +1 -1
  159. package/src/renderers/shaders/ShaderLib/depth.glsl.js +2 -0
  160. package/src/renderers/shaders/ShaderLib/distanceRGBA.glsl.js +2 -0
  161. package/src/renderers/shaders/ShaderLib/equirect.glsl.js +1 -1
  162. package/src/renderers/shaders/ShaderLib/linedashed.glsl.js +2 -2
  163. package/src/renderers/shaders/ShaderLib/meshbasic.glsl.js +4 -2
  164. package/src/renderers/shaders/ShaderLib/meshlambert.glsl.js +4 -2
  165. package/src/renderers/shaders/ShaderLib/meshmatcap.glsl.js +4 -2
  166. package/src/renderers/shaders/ShaderLib/meshphong.glsl.js +4 -2
  167. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +4 -2
  168. package/src/renderers/shaders/ShaderLib/meshtoon.glsl.js +4 -2
  169. package/src/renderers/shaders/ShaderLib/points.glsl.js +4 -2
  170. package/src/renderers/shaders/ShaderLib/shadow.glsl.js +1 -1
  171. package/src/renderers/shaders/ShaderLib/sprite.glsl.js +4 -2
  172. package/src/renderers/webgl/WebGLObjects.js +23 -3
  173. package/src/renderers/webgl/WebGLProgram.js +24 -5
  174. package/src/renderers/webgl/WebGLPrograms.js +3 -0
  175. package/src/renderers/webxr/WebXRManager.js +11 -29
  176. package/src/scenes/Scene.js +0 -14
  177. package/examples/jsm/nodes/core/InstanceIndexNode.js +0 -45
  178. /package/src/renderers/shaders/ShaderChunk/{encodings_fragment.glsl.js → colorspace_fragment.glsl.js} +0 -0
  179. /package/src/renderers/shaders/ShaderChunk/{encodings_pars_fragment.glsl.js → colorspace_pars_fragment.glsl.js} +0 -0
  180. /package/src/renderers/shaders/ShaderChunk/{output_fragment.glsl.js → opaque_fragment.glsl.js} +0 -0
@@ -2,26 +2,26 @@ import F_Schlick from './F_Schlick.js';
2
2
  import { shininess, specularColor } from '../../core/PropertyNode.js';
3
3
  import { transformedNormalView } from '../../accessors/NormalNode.js';
4
4
  import { positionViewDirection } from '../../accessors/PositionNode.js';
5
- import { ShaderNode, float } from '../../shadernode/ShaderNode.js';
5
+ import { tslFn, float } from '../../shadernode/ShaderNode.js';
6
6
 
7
7
  const G_BlinnPhong_Implicit = () => float( 0.25 );
8
8
 
9
- const D_BlinnPhong = new ShaderNode( ( { dotNH } ) => {
9
+ const D_BlinnPhong = tslFn( ( { dotNH } ) => {
10
10
 
11
11
  return shininess.mul( 0.5 / Math.PI ).add( 1.0 ).mul( dotNH.pow( shininess ) );
12
12
 
13
13
  } );
14
14
 
15
- const BRDF_BlinnPhong = new ShaderNode( ( { lightDirection } ) => {
15
+ const BRDF_BlinnPhong = tslFn( ( { lightDirection } ) => {
16
16
 
17
17
  const halfDir = lightDirection.add( positionViewDirection ).normalize();
18
18
 
19
19
  const dotNH = transformedNormalView.dot( halfDir ).clamp();
20
20
  const dotVH = positionViewDirection.dot( halfDir ).clamp();
21
21
 
22
- const F = F_Schlick.call( { f0: specularColor, f90: 1.0, dotVH } );
22
+ const F = F_Schlick( { f0: specularColor, f90: 1.0, dotVH } );
23
23
  const G = G_BlinnPhong_Implicit();
24
- const D = D_BlinnPhong.call( { dotNH } );
24
+ const D = D_BlinnPhong( { dotNH } );
25
25
 
26
26
  return F.mul( G ).mul( D );
27
27
 
@@ -3,25 +3,27 @@ import V_GGX_SmithCorrelated from './V_GGX_SmithCorrelated.js';
3
3
  import D_GGX from './D_GGX.js';
4
4
  import { transformedNormalView } from '../../accessors/NormalNode.js';
5
5
  import { positionViewDirection } from '../../accessors/PositionNode.js';
6
- import { ShaderNode } from '../../shadernode/ShaderNode.js';
6
+ import { tslFn } from '../../shadernode/ShaderNode.js';
7
7
 
8
8
  // GGX Distribution, Schlick Fresnel, GGX_SmithCorrelated Visibility
9
- const BRDF_GGX = new ShaderNode( ( inputs ) => {
9
+ const BRDF_GGX = tslFn( ( inputs ) => {
10
10
 
11
11
  const { lightDirection, f0, f90, roughness } = inputs;
12
12
 
13
+ const normalView = inputs.normalView || transformedNormalView;
14
+
13
15
  const alpha = roughness.pow2(); // UE4's roughness
14
16
 
15
17
  const halfDir = lightDirection.add( positionViewDirection ).normalize();
16
18
 
17
- const dotNL = transformedNormalView.dot( lightDirection ).clamp();
18
- const dotNV = transformedNormalView.dot( positionViewDirection ).clamp();
19
- const dotNH = transformedNormalView.dot( halfDir ).clamp();
19
+ const dotNL = normalView.dot( lightDirection ).clamp();
20
+ const dotNV = normalView.dot( positionViewDirection ).clamp(); // @ TODO: Move to core dotNV
21
+ const dotNH = normalView.dot( halfDir ).clamp();
20
22
  const dotVH = positionViewDirection.dot( halfDir ).clamp();
21
23
 
22
- const F = F_Schlick.call( { f0, f90, dotVH } );
23
- const V = V_GGX_SmithCorrelated.call( { alpha, dotNL, dotNV } );
24
- const D = D_GGX.call( { alpha, dotNH } );
24
+ const F = F_Schlick( { f0, f90, dotVH } );
25
+ const V = V_GGX_SmithCorrelated( { alpha, dotNL, dotNV } );
26
+ const D = D_GGX( { alpha, dotNH } );
25
27
 
26
28
  return F.mul( V ).mul( D );
27
29
 
@@ -1,6 +1,6 @@
1
- import { ShaderNode } from '../../shadernode/ShaderNode.js';
1
+ import { tslFn } from '../../shadernode/ShaderNode.js';
2
2
 
3
- const BRDF_Lambert = new ShaderNode( ( inputs ) => {
3
+ const BRDF_Lambert = tslFn( ( inputs ) => {
4
4
 
5
5
  return inputs.diffuseColor.mul( 1 / Math.PI ); // punctual light
6
6
 
@@ -0,0 +1,43 @@
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
+
6
+ // https://github.com/google/filament/blob/master/shaders/src/brdf.fs
7
+ const D_Charlie = ( roughness, dotNH ) => {
8
+
9
+ const alpha = roughness.pow2();
10
+
11
+ // Estevez and Kulla 2017, "Production Friendly Microfacet Sheen BRDF"
12
+ const invAlpha = float( 1.0 ).div( alpha );
13
+ const cos2h = dotNH.pow2();
14
+ const sin2h = cos2h.oneMinus().max( 0.0078125 ); // 2^(-14/2), so sin2h^2 > 0 in fp16
15
+
16
+ return float( 2.0 ).add( invAlpha ).mul( sin2h.pow( invAlpha.mul( 0.5 ) ) ).div( 2.0 * Math.PI );
17
+
18
+ };
19
+
20
+ // https://github.com/google/filament/blob/master/shaders/src/brdf.fs
21
+ const V_Neubelt = ( dotNV, dotNL ) => {
22
+
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
+
26
+ };
27
+
28
+ const BRDF_Sheen = tslFn( ( { lightDirection } ) => {
29
+
30
+ const halfDir = lightDirection.add( positionViewDirection ).normalize();
31
+
32
+ const dotNL = transformedNormalView.dot( lightDirection ).clamp();
33
+ const dotNV = transformedNormalView.dot( positionViewDirection ).clamp();
34
+ const dotNH = transformedNormalView.dot( halfDir ).clamp();
35
+
36
+ const D = D_Charlie( sheenRoughness, dotNH );
37
+ const V = V_Neubelt( dotNV, dotNL );
38
+
39
+ return sheen.mul( D ).mul( V );
40
+
41
+ } );
42
+
43
+ export default BRDF_Sheen;
@@ -1,23 +1,23 @@
1
1
  import { transformedNormalView } from '../../accessors/NormalNode.js';
2
2
  import { positionViewDirection } from '../../accessors/PositionNode.js';
3
- import { ShaderNode, vec2, vec4 } from '../../shadernode/ShaderNode.js';
3
+ import { tslFn, vec2, vec4 } from '../../shadernode/ShaderNode.js';
4
4
 
5
5
  // Analytical approximation of the DFG LUT, one half of the
6
6
  // split-sum approximation used in indirect specular lighting.
7
7
  // via 'environmentBRDF' from "Physically Based Shading on Mobile"
8
8
  // https://www.unrealengine.com/blog/physically-based-shading-on-mobile
9
- const DFGApprox = new ShaderNode( ( inputs ) => {
9
+ const DFGApprox = tslFn( ( inputs ) => {
10
10
 
11
11
  const { roughness } = inputs;
12
12
 
13
+ const dotNV = inputs.dotNV || transformedNormalView.dot( positionViewDirection ).clamp(); // @ TODO: Move to core dotNV
14
+
13
15
  const c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );
14
16
 
15
17
  const c1 = vec4( 1, 0.0425, 1.04, - 0.04 );
16
18
 
17
19
  const r = roughness.mul( c0 ).add( c1 );
18
20
 
19
- const dotNV = transformedNormalView.dot( positionViewDirection ).clamp();
20
-
21
21
  const a004 = r.x.mul( r.x ).min( dotNV.mul( - 9.28 ).exp2() ).mul( r.x ).add( r.y );
22
22
 
23
23
  const fab = vec2( - 1.04, 1.04 ).mul( a004 ).add( r.zw );
@@ -1,9 +1,9 @@
1
- import { ShaderNode } from '../../shadernode/ShaderNode.js';
1
+ import { tslFn } from '../../shadernode/ShaderNode.js';
2
2
 
3
3
  // Microfacet Models for Refraction through Rough Surfaces - equation (33)
4
4
  // http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html
5
5
  // alpha is "roughness squared" in Disney’s reparameterization
6
- const D_GGX = new ShaderNode( ( inputs ) => {
6
+ const D_GGX = tslFn( ( inputs ) => {
7
7
 
8
8
  const { alpha, dotNH } = inputs;
9
9
 
@@ -0,0 +1,13 @@
1
+ import DFGApprox from './DFGApprox.js';
2
+ import { tslFn } from '../../shadernode/ShaderNode.js';
3
+
4
+ const EnvironmentBRDF = tslFn( ( inputs ) => {
5
+
6
+ const { dotNV, specularColor, specularF90, roughness } = inputs;
7
+
8
+ const fab = DFGApprox( { dotNV, roughness } );
9
+ return specularColor.mul( fab.x ).add( specularF90.mul( fab.y ) );
10
+
11
+ } );
12
+
13
+ export default EnvironmentBRDF;
@@ -1,8 +1,6 @@
1
- import { ShaderNode } from '../../shadernode/ShaderNode.js';
1
+ import { tslFn } from '../../shadernode/ShaderNode.js';
2
2
 
3
- const F_Schlick = new ShaderNode( ( inputs ) => {
4
-
5
- const { f0, f90, dotVH } = inputs;
3
+ const F_Schlick = tslFn( ( { f0, f90, dotVH } ) => {
6
4
 
7
5
  // Original approximation by Christophe Schlick '94
8
6
  // float fresnel = pow( 1.0 - dotVH, 5.0 );
@@ -1,10 +1,10 @@
1
1
  import { div } from '../../math/OperatorNode.js';
2
2
  import { EPSILON } from '../../math/MathNode.js';
3
- import { ShaderNode } from '../../shadernode/ShaderNode.js';
3
+ import { tslFn } from '../../shadernode/ShaderNode.js';
4
4
 
5
5
  // Moving Frostbite to Physically Based Rendering 3.0 - page 12, listing 2
6
6
  // https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf
7
- const V_GGX_SmithCorrelated = new ShaderNode( ( inputs ) => {
7
+ const V_GGX_SmithCorrelated = tslFn( ( inputs ) => {
8
8
 
9
9
  const { alpha, dotNL, dotNV } = inputs;
10
10
 
@@ -4,25 +4,25 @@ import { lightingModel } from '../core/LightingModel.js';
4
4
  import { diffuseColor } from '../core/PropertyNode.js';
5
5
  import { materialReflectivity } from '../accessors/MaterialNode.js';
6
6
  import { transformedNormalView } from '../accessors/NormalNode.js';
7
- import { ShaderNode } from '../shadernode/ShaderNode.js';
7
+ import { tslFn } from '../shadernode/ShaderNode.js';
8
8
 
9
- const RE_Direct_BlinnPhong = new ShaderNode( ( { lightDirection, lightColor, reflectedLight } ) => {
9
+ const RE_Direct_BlinnPhong = tslFn( ( { lightDirection, lightColor, reflectedLight } ) => {
10
10
 
11
11
  const dotNL = transformedNormalView.dot( lightDirection ).clamp();
12
12
  const irradiance = dotNL.mul( lightColor );
13
13
 
14
- reflectedLight.directDiffuse.addAssign( irradiance.mul( BRDF_Lambert.call( { diffuseColor: diffuseColor.rgb } ) ) );
14
+ reflectedLight.directDiffuse.addAssign( irradiance.mul( BRDF_Lambert( { diffuseColor: diffuseColor.rgb } ) ) );
15
15
 
16
- reflectedLight.directSpecular.addAssign( irradiance.mul( BRDF_BlinnPhong.call( { lightDirection } ) ).mul( materialReflectivity ) );
16
+ reflectedLight.directSpecular.addAssign( irradiance.mul( BRDF_BlinnPhong( { lightDirection } ) ).mul( materialReflectivity ) );
17
17
 
18
18
  } );
19
19
 
20
- const RE_IndirectDiffuse_BlinnPhong = new ShaderNode( ( { irradiance, reflectedLight } ) => {
20
+ const RE_IndirectDiffuse_BlinnPhong = tslFn( ( { irradiance, reflectedLight } ) => {
21
21
 
22
- reflectedLight.indirectDiffuse.addAssign( irradiance.mul( BRDF_Lambert.call( { diffuseColor } ) ) );
22
+ reflectedLight.indirectDiffuse.addAssign( irradiance.mul( BRDF_Lambert( { diffuseColor } ) ) );
23
23
 
24
24
  } );
25
25
 
26
- const phongLightingModel = lightingModel( RE_Direct_BlinnPhong, RE_IndirectDiffuse_BlinnPhong );
26
+ const phongLightingModel = lightingModel( null, RE_Direct_BlinnPhong, RE_IndirectDiffuse_BlinnPhong );
27
27
 
28
28
  export default phongLightingModel;
@@ -1,19 +1,52 @@
1
1
  import BRDF_Lambert from './BSDF/BRDF_Lambert.js';
2
2
  import BRDF_GGX from './BSDF/BRDF_GGX.js';
3
3
  import DFGApprox from './BSDF/DFGApprox.js';
4
+ import EnvironmentBRDF from './BSDF/EnvironmentBRDF.js';
5
+ import F_Schlick from './BSDF/F_Schlick.js';
6
+ import BRDF_Sheen from './BSDF/BRDF_Sheen.js';
4
7
  import { lightingModel } from '../core/LightingModel.js';
5
- import { temp } from '../core/VarNode.js';
6
- import { diffuseColor, specularColor, roughness } from '../core/PropertyNode.js';
7
- import { transformedNormalView } from '../accessors/NormalNode.js';
8
+ import { diffuseColor, specularColor, roughness, clearcoat, clearcoatRoughness, sheen, sheenRoughness } from '../core/PropertyNode.js';
9
+ import { transformedNormalView, transformedClearcoatNormalView } from '../accessors/NormalNode.js';
8
10
  import { positionViewDirection } from '../accessors/PositionNode.js';
9
- import { ShaderNode, float, vec3 } from '../shadernode/ShaderNode.js';
11
+ import { tslFn, float, vec3 } from '../shadernode/ShaderNode.js';
12
+ import { cond } from '../math/CondNode.js';
13
+
14
+ const clearcoatF0 = vec3( 0.04 );
15
+ const clearcoatF90 = vec3( 1 );
16
+
17
+ // This is a curve-fit approxmation to the "Charlie sheen" BRDF integrated over the hemisphere from
18
+ // Estevez and Kulla 2017, "Production Friendly Microfacet Sheen BRDF". The analysis can be found
19
+ // in the Sheen section of https://drive.google.com/file/d/1T0D1VSyR4AllqIJTQAraEIzjlb5h4FKH/view?usp=sharing
20
+ const IBLSheenBRDF = ( normal, viewDir, roughness ) => {
21
+
22
+ const dotNV = normal.dot( viewDir ).saturate();
23
+
24
+ const r2 = roughness.pow2();
25
+
26
+ const a = cond(
27
+ roughness.lessThan( 0.25 ),
28
+ float( - 339.2 ).mul( r2 ).add( float( 161.4 ).mul( roughness ) ).sub( 25.9 ),
29
+ float( - 8.48 ).mul( r2 ).add( float( 14.3 ).mul( roughness ) ).sub( 9.95 )
30
+ );
31
+
32
+ const b = cond(
33
+ roughness.lessThan( 0.25 ),
34
+ float( 44.0 ).mul( r2 ).sub( float( 23.7 ).mul( roughness ) ).add( 3.26 ),
35
+ float( 1.97 ).mul( r2 ).sub( float( 3.27 ).mul( roughness ) ).add( 0.72 )
36
+ );
37
+
38
+ const DG = cond( roughness.lessThan( 0.25 ), 0.0, float( 0.1 ).mul( roughness ).sub( 0.025 ) ).add( a.mul( dotNV ).add( b ).exp() );
39
+
40
+ return DG.mul( 1.0 / Math.PI ).saturate();
41
+
42
+ };
10
43
 
11
44
  // Fdez-Agüera's "Multiple-Scattering Microfacet Model for Real-Time Image Based Lighting"
12
45
  // Approximates multiscattering in order to preserve energy.
13
46
  // http://www.jcgt.org/published/0008/01/03/
14
47
  const computeMultiscattering = ( singleScatter, multiScatter, specularF90 = float( 1 ) ) => {
15
48
 
16
- const fab = DFGApprox.call( { roughness } );
49
+ const fab = DFGApprox( { roughness } );
17
50
 
18
51
  const FssEss = specularColor.mul( fab.x ).add( specularF90.mul( fab.y ) );
19
52
 
@@ -28,14 +61,75 @@ const computeMultiscattering = ( singleScatter, multiScatter, specularF90 = floa
28
61
 
29
62
  };
30
63
 
31
- const RE_IndirectSpecular_Physical = new ShaderNode( ( inputs ) => {
64
+ const LM_Init = tslFn( ( context, stack, builder ) => {
65
+
66
+ if ( builder.includes( clearcoat ) ) {
67
+
68
+ context.clearcoatRadiance = vec3().temp();
69
+ context.reflectedLight.clearcoatSpecular = vec3().temp();
70
+
71
+ const dotNVcc = transformedClearcoatNormalView.dot( positionViewDirection ).clamp();
72
+
73
+ const Fcc = F_Schlick( {
74
+ dotVH: dotNVcc,
75
+ f0: clearcoatF0,
76
+ f90: clearcoatF90
77
+ } );
78
+
79
+ const outgoingLight = context.reflectedLight.total;
80
+ const clearcoatLight = outgoingLight.mul( clearcoat.mul( Fcc ).oneMinus() ).add( context.reflectedLight.clearcoatSpecular.mul( clearcoat ) );
81
+
82
+ outgoingLight.assign( clearcoatLight );
83
+
84
+ }
85
+
86
+ if ( builder.includes( sheen ) ) {
87
+
88
+ context.reflectedLight.sheenSpecular = vec3().temp();
89
+
90
+ const outgoingLight = context.reflectedLight.total;
91
+
92
+ const sheenEnergyComp = sheen.r.max( sheen.g ).max( sheen.b ).mul( 0.157 ).oneMinus();
93
+ const sheenLight = outgoingLight.mul( sheenEnergyComp ).add( context.reflectedLight.sheenSpecular );
32
94
 
33
- const { radiance, iblIrradiance, reflectedLight } = inputs;
95
+ outgoingLight.assign( sheenLight );
96
+
97
+ }
98
+
99
+ } );
100
+
101
+ const RE_IndirectSpecular_Physical = tslFn( ( context ) => {
102
+
103
+ const { radiance, iblIrradiance, reflectedLight } = context;
104
+
105
+ if ( reflectedLight.sheenSpecular ) {
106
+
107
+ reflectedLight.sheenSpecular.addAssign( iblIrradiance.mul(
108
+ sheen,
109
+ IBLSheenBRDF( transformedNormalView, positionViewDirection, sheenRoughness )
110
+ ) );
111
+
112
+ }
113
+
114
+ if ( reflectedLight.clearcoatSpecular ) {
115
+
116
+ const dotNVcc = transformedClearcoatNormalView.dot( positionViewDirection ).clamp();
117
+
118
+ const clearcoatEnv = EnvironmentBRDF( {
119
+ dotNV: dotNVcc,
120
+ specularColor: clearcoatF0,
121
+ specularF90: clearcoatF90,
122
+ roughness: clearcoatRoughness
123
+ } );
124
+
125
+ reflectedLight.clearcoatSpecular.addAssign( context.clearcoatRadiance.mul( clearcoatEnv ) );
126
+
127
+ }
34
128
 
35
129
  // Both indirect specular and indirect diffuse light accumulate here
36
130
 
37
- const singleScattering = temp( vec3() );
38
- const multiScattering = temp( vec3() );
131
+ const singleScattering = vec3().temp();
132
+ const multiScattering = vec3().temp();
39
133
  const cosineWeightedIrradiance = iblIrradiance.mul( 1 / Math.PI );
40
134
 
41
135
  computeMultiscattering( singleScattering, multiScattering );
@@ -51,30 +145,47 @@ const RE_IndirectSpecular_Physical = new ShaderNode( ( inputs ) => {
51
145
 
52
146
  } );
53
147
 
54
- const RE_IndirectDiffuse_Physical = new ShaderNode( ( inputs ) => {
148
+ const RE_IndirectDiffuse_Physical = tslFn( ( context ) => {
55
149
 
56
- const { irradiance, reflectedLight } = inputs;
150
+ const { irradiance, reflectedLight } = context;
57
151
 
58
- reflectedLight.indirectDiffuse.addAssign( irradiance.mul( BRDF_Lambert.call( { diffuseColor } ) ) );
152
+ reflectedLight.indirectDiffuse.addAssign( irradiance.mul( BRDF_Lambert( { diffuseColor } ) ) );
59
153
 
60
154
  } );
61
155
 
62
- const RE_Direct_Physical = new ShaderNode( ( inputs ) => {
156
+ const RE_Direct_Physical = tslFn( ( inputs ) => {
63
157
 
64
158
  const { lightDirection, lightColor, reflectedLight } = inputs;
65
159
 
66
160
  const dotNL = transformedNormalView.dot( lightDirection ).clamp();
67
161
  const irradiance = dotNL.mul( lightColor );
68
162
 
69
- reflectedLight.directDiffuse.addAssign( irradiance.mul( BRDF_Lambert.call( { diffuseColor: diffuseColor.rgb } ) ) );
163
+ if ( reflectedLight.sheenSpecular ) {
164
+
165
+ reflectedLight.sheenSpecular.addAssign( irradiance.mul( BRDF_Sheen( { lightDirection } ) ) );
166
+
167
+ }
168
+
169
+ if ( reflectedLight.clearcoatSpecular ) {
70
170
 
71
- reflectedLight.directSpecular.addAssign( irradiance.mul( BRDF_GGX.call( { lightDirection, f0: specularColor, f90: 1, roughness } ) ) );
171
+ const dotNLcc = transformedClearcoatNormalView.dot( lightDirection ).clamp();
172
+ const ccIrradiance = dotNLcc.mul( lightColor );
173
+
174
+ reflectedLight.clearcoatSpecular.addAssign( ccIrradiance.mul( BRDF_GGX( { lightDirection, f0: clearcoatF0, f90: clearcoatF90, roughness: clearcoatRoughness, normalView: transformedClearcoatNormalView } ) ) );
175
+
176
+ }
177
+
178
+ reflectedLight.directDiffuse.addAssign( irradiance.mul( BRDF_Lambert( { diffuseColor: diffuseColor.rgb } ) ) );
179
+
180
+ reflectedLight.directSpecular.addAssign( irradiance.mul( BRDF_GGX( { lightDirection, f0: specularColor, f90: 1, roughness } ) ) );
72
181
 
73
182
  } );
74
183
 
75
- const RE_AmbientOcclusion_Physical = new ShaderNode( ( { ambientOcclusion, reflectedLight } ) => {
184
+ const RE_AmbientOcclusion_Physical = tslFn( ( context ) => {
185
+
186
+ const { ambientOcclusion, reflectedLight } = context;
76
187
 
77
- const dotNV = transformedNormalView.dot( positionViewDirection ).clamp();
188
+ const dotNV = transformedNormalView.dot( positionViewDirection ).clamp(); // @ TODO: Move to core dotNV
78
189
 
79
190
  const aoNV = dotNV.add( ambientOcclusion );
80
191
  const aoExp = roughness.mul( - 16.0 ).oneMinus().negate().exp2();
@@ -88,6 +199,6 @@ const RE_AmbientOcclusion_Physical = new ShaderNode( ( { ambientOcclusion, refle
88
199
 
89
200
  } );
90
201
 
91
- const physicalLightingModel = lightingModel( RE_Direct_Physical, RE_IndirectDiffuse_Physical, RE_IndirectSpecular_Physical, RE_AmbientOcclusion_Physical );
202
+ const physicalLightingModel = lightingModel( LM_Init, RE_Direct_Physical, RE_IndirectDiffuse_Physical, RE_IndirectSpecular_Physical, RE_AmbientOcclusion_Physical );
92
203
 
93
204
  export default physicalLightingModel;
@@ -1,7 +1,7 @@
1
1
  import { normalGeometry } from '../../accessors/NormalNode.js';
2
- import { ShaderNode } from '../../shadernode/ShaderNode.js';
2
+ import { tslFn } from '../../shadernode/ShaderNode.js';
3
3
 
4
- const getGeometryRoughness = new ShaderNode( () => {
4
+ const getGeometryRoughness = tslFn( () => {
5
5
 
6
6
  const dxy = normalGeometry.dFdx().abs().max( normalGeometry.dFdy().abs() );
7
7
  const geometryRoughness = dxy.x.max( dxy.y ).max( dxy.z );
@@ -1,11 +1,11 @@
1
1
  import getGeometryRoughness from './getGeometryRoughness.js';
2
- import { ShaderNode } from '../../shadernode/ShaderNode.js';
2
+ import { tslFn } from '../../shadernode/ShaderNode.js';
3
3
 
4
- const getRoughness = new ShaderNode( ( inputs ) => {
4
+ const getRoughness = tslFn( ( inputs ) => {
5
5
 
6
6
  const { roughness } = inputs;
7
7
 
8
- const geometryRoughness = getGeometryRoughness.call();
8
+ const geometryRoughness = getGeometryRoughness();
9
9
 
10
10
  let roughnessFactor = roughness.max( 0.0525 ); // 0.0525 corresponds to the base mip of a 256 cubemap.
11
11
  roughnessFactor = roughnessFactor.add( geometryRoughness );
@@ -2,7 +2,7 @@ import Node, { addNodeClass } from '../core/Node.js';
2
2
  import { getValueType } from '../core/NodeUtils.js';
3
3
  import { buffer } from '../accessors/BufferNode.js';
4
4
  //import { bufferAttribute } from '../accessors/BufferAttributeNode.js';
5
- import { instanceIndex } from '../core/InstanceIndexNode.js';
5
+ import { instanceIndex } from '../core/IndexNode.js';
6
6
  import { nodeProxy, float } from '../shadernode/ShaderNode.js';
7
7
 
8
8
  import { Vector4, MathUtils } from 'three';
@@ -24,11 +24,11 @@ class DirectionalLightNode extends AnalyticLightNode {
24
24
 
25
25
  if ( lightingModelFunctionNode && lightingModelFunctionNode.direct ) {
26
26
 
27
- lightingModelFunctionNode.direct.call( {
27
+ lightingModelFunctionNode.direct( {
28
28
  lightDirection,
29
29
  lightColor,
30
30
  reflectedLight
31
- }, builder );
31
+ } );
32
32
 
33
33
  }
34
34