super-three 0.163.0 → 0.164.0

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 (114) hide show
  1. package/build/three.cjs +473 -245
  2. package/build/three.module.js +473 -245
  3. package/build/three.module.min.js +2 -2
  4. package/examples/jsm/animation/CCDIKSolver.js +4 -2
  5. package/examples/jsm/exporters/GLTFExporter.js +45 -1
  6. package/examples/jsm/exporters/USDZExporter.js +7 -1
  7. package/examples/jsm/libs/draco/README.md +2 -2
  8. package/examples/jsm/loaders/EXRLoader.js +283 -99
  9. package/examples/jsm/loaders/GLTFLoader.js +53 -0
  10. package/examples/jsm/loaders/KTX2Loader.js +3 -6
  11. package/examples/jsm/loaders/VRMLLoader.js +1 -1
  12. package/examples/jsm/loaders/lwo/IFFParser.js +8 -5
  13. package/examples/jsm/materials/MeshGouraudMaterial.js +7 -1
  14. package/examples/jsm/math/Octree.js +26 -20
  15. package/examples/jsm/nodes/Nodes.js +4 -3
  16. package/examples/jsm/nodes/accessors/AccessorsUtils.js +16 -1
  17. package/examples/jsm/nodes/accessors/ClippingNode.js +3 -2
  18. package/examples/jsm/nodes/accessors/MaterialNode.js +107 -3
  19. package/examples/jsm/nodes/accessors/StorageBufferNode.js +9 -0
  20. package/examples/jsm/nodes/accessors/TextureNode.js +21 -3
  21. package/examples/jsm/nodes/accessors/TextureSizeNode.js +1 -1
  22. package/examples/jsm/nodes/code/FunctionNode.js +0 -8
  23. package/examples/jsm/nodes/core/Node.js +8 -0
  24. package/examples/jsm/nodes/core/NodeBuilder.js +5 -9
  25. package/examples/jsm/nodes/core/OutputStructNode.js +2 -1
  26. package/examples/jsm/nodes/core/PropertyNode.js +10 -0
  27. package/examples/jsm/nodes/display/BumpMapNode.js +7 -26
  28. package/examples/jsm/nodes/display/FrontFacingNode.js +13 -0
  29. package/examples/jsm/nodes/display/ViewportDepthNode.js +1 -1
  30. package/examples/jsm/nodes/display/ViewportNode.js +4 -2
  31. package/examples/jsm/nodes/display/ViewportTextureNode.js +4 -1
  32. package/examples/jsm/nodes/functions/BSDF/BRDF_GGX.js +26 -7
  33. package/examples/jsm/nodes/functions/BSDF/D_GGX_Anisotropic.js +28 -0
  34. package/examples/jsm/nodes/functions/BSDF/V_GGX_SmithCorrelated.js +1 -3
  35. package/examples/jsm/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.js +29 -0
  36. package/examples/jsm/nodes/functions/PhongLightingModel.js +1 -1
  37. package/examples/jsm/nodes/functions/PhysicalLightingModel.js +164 -10
  38. package/examples/jsm/nodes/functions/ShadowMaskModel.js +31 -0
  39. package/examples/jsm/nodes/lighting/AnalyticLightNode.js +18 -4
  40. package/examples/jsm/nodes/lighting/DirectionalLightNode.js +2 -1
  41. package/examples/jsm/nodes/lighting/EnvironmentNode.js +11 -2
  42. package/examples/jsm/nodes/lighting/IrradianceNode.js +24 -0
  43. package/examples/jsm/nodes/lighting/LightsNode.js +11 -1
  44. package/examples/jsm/nodes/lighting/PointLightNode.js +2 -1
  45. package/examples/jsm/nodes/lighting/SpotLightNode.js +2 -1
  46. package/examples/jsm/nodes/materials/Line2NodeMaterial.js +10 -6
  47. package/examples/jsm/nodes/materials/Materials.js +1 -0
  48. package/examples/jsm/nodes/materials/MeshNormalNodeMaterial.js +0 -2
  49. package/examples/jsm/nodes/materials/MeshPhongNodeMaterial.js +2 -2
  50. package/examples/jsm/nodes/materials/MeshPhysicalNodeMaterial.js +76 -5
  51. package/examples/jsm/nodes/materials/MeshStandardNodeMaterial.js +11 -4
  52. package/examples/jsm/nodes/materials/NodeMaterial.js +31 -41
  53. package/examples/jsm/nodes/materials/ShadowNodeMaterial.js +34 -0
  54. package/examples/jsm/nodes/pmrem/PMREMUtils.js +1 -1
  55. package/examples/jsm/nodes/shadernode/ShaderNode.js +2 -8
  56. package/examples/jsm/physics/JoltPhysics.js +281 -0
  57. package/examples/jsm/postprocessing/RenderTransitionPass.js +193 -0
  58. package/examples/jsm/renderers/common/Background.js +3 -3
  59. package/examples/jsm/renderers/common/ClippingContext.js +1 -1
  60. package/examples/jsm/renderers/common/RenderList.js +1 -1
  61. package/examples/jsm/renderers/common/RenderObject.js +43 -1
  62. package/examples/jsm/renderers/common/Renderer.js +129 -14
  63. package/examples/jsm/renderers/common/Textures.js +1 -1
  64. package/examples/jsm/renderers/common/extras/PMREMGenerator.js +13 -17
  65. package/examples/jsm/renderers/common/nodes/Nodes.js +31 -47
  66. package/examples/jsm/renderers/webgl/WebGLBackend.js +7 -21
  67. package/examples/jsm/renderers/webgl/WebGLBufferRenderer.js +5 -1
  68. package/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js +6 -0
  69. package/examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js +21 -7
  70. package/examples/jsm/renderers/webgl/utils/WebGLUtils.js +3 -21
  71. package/examples/jsm/renderers/webgpu/WebGPUBackend.js +33 -45
  72. package/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js +16 -1
  73. package/examples/jsm/renderers/webgpu/utils/WebGPUAttributeUtils.js +4 -1
  74. package/examples/jsm/transpiler/GLSLDecoder.js +1 -1
  75. package/examples/jsm/transpiler/ShaderToyDecoder.js +1 -1
  76. package/examples/jsm/utils/SceneUtils.js +60 -1
  77. package/examples/jsm/webxr/OculusHandModel.js +3 -2
  78. package/examples/jsm/webxr/XRHandModelFactory.js +4 -2
  79. package/package.json +1 -1
  80. package/src/constants.js +1 -1
  81. package/src/core/RenderTarget.js +8 -0
  82. package/src/extras/PMREMGenerator.js +12 -11
  83. package/src/loaders/FileLoader.js +1 -1
  84. package/src/loaders/MaterialLoader.js +1 -0
  85. package/src/materials/Material.js +2 -0
  86. package/src/materials/MeshPhysicalMaterial.js +20 -0
  87. package/src/objects/BatchedMesh.js +23 -0
  88. package/src/objects/Line.js +66 -43
  89. package/src/renderers/WebGLRenderer.js +92 -61
  90. package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +6 -0
  91. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +1 -0
  92. package/src/renderers/shaders/ShaderChunk/tonemapping_pars_fragment.glsl.js +17 -9
  93. package/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js +1 -1
  94. package/src/renderers/shaders/ShaderChunk/transmission_pars_fragment.glsl.js +47 -13
  95. package/src/renderers/shaders/ShaderChunk.js +0 -2
  96. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +4 -0
  97. package/src/renderers/shaders/ShaderLib.js +1 -0
  98. package/src/renderers/webgl/WebGLBackground.js +18 -3
  99. package/src/renderers/webgl/WebGLBufferRenderer.js +36 -0
  100. package/src/renderers/webgl/WebGLCapabilities.js +33 -1
  101. package/src/renderers/webgl/WebGLIndexedBufferRenderer.js +36 -0
  102. package/src/renderers/webgl/WebGLMaterials.js +6 -0
  103. package/src/renderers/webgl/WebGLProgram.js +3 -5
  104. package/src/renderers/webgl/WebGLPrograms.js +5 -0
  105. package/src/renderers/webgl/WebGLRenderStates.js +6 -2
  106. package/src/renderers/webgl/WebGLShadowMap.js +25 -25
  107. package/src/renderers/webgl/WebGLTextures.js +68 -60
  108. package/src/renderers/webgl/WebGLUtils.js +3 -21
  109. package/src/renderers/webxr/WebXRManager.js +2 -4
  110. package/examples/jsm/renderers/webgl-legacy/nodes/GLSL1NodeBuilder.js +0 -318
  111. package/examples/jsm/renderers/webgl-legacy/nodes/SlotNode.js +0 -26
  112. package/examples/jsm/renderers/webgl-legacy/nodes/WebGLNodeBuilder.js +0 -792
  113. package/examples/jsm/renderers/webgl-legacy/nodes/WebGLNodes.js +0 -51
  114. package/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl.js +0 -10
@@ -10,7 +10,7 @@ import { normalWorld } from '../accessors/NormalNode.js';
10
10
  import { WebGPUCoordinateSystem } from 'three';
11
11
  //import { add } from '../math/OperatorNode.js';
12
12
 
13
- import { Color, DepthTexture, NearestFilter, LessCompare } from 'three';
13
+ import { Color, DepthTexture, NearestFilter, LessCompare, NoToneMapping } from 'three';
14
14
 
15
15
  let overrideMaterial = null;
16
16
 
@@ -26,6 +26,7 @@ class AnalyticLightNode extends LightingNode {
26
26
 
27
27
  this.rtt = null;
28
28
  this.shadowNode = null;
29
+ this.shadowMaskNode = null;
29
30
 
30
31
  this.color = new Color();
31
32
  this._defaultColorNode = uniform( this.color );
@@ -50,6 +51,10 @@ class AnalyticLightNode extends LightingNode {
50
51
 
51
52
  setupShadow( builder ) {
52
53
 
54
+ const { object } = builder;
55
+
56
+ if ( object.receiveShadow === false ) return;
57
+
53
58
  let shadowNode = this.shadowNode;
54
59
 
55
60
  if ( shadowNode === null ) {
@@ -81,7 +86,9 @@ class AnalyticLightNode extends LightingNode {
81
86
  const bias = reference( 'bias', 'float', shadow );
82
87
  const normalBias = reference( 'normalBias', 'float', shadow );
83
88
 
84
- let shadowCoord = uniform( shadow.matrix ).mul( positionWorld.add( normalWorld.mul( normalBias ) ) );
89
+ const position = object.material.shadowPositionNode || positionWorld;
90
+
91
+ let shadowCoord = uniform( shadow.matrix ).mul( position.add( normalWorld.mul( normalBias ) ) );
85
92
  shadowCoord = shadowCoord.xyz.div( shadowCoord.w );
86
93
 
87
94
  const frustumTest = shadowCoord.x.greaterThanEqual( 0 )
@@ -145,15 +152,17 @@ class AnalyticLightNode extends LightingNode {
145
152
  textureCompare( depthTexture, shadowCoord.xy.add( vec2( 0, dy1 ) ), shadowCoord.z ),
146
153
  textureCompare( depthTexture, shadowCoord.xy.add( vec2( dx1, dy1 ) ), shadowCoord.z )
147
154
  ).mul( 1 / 17 );
148
- */
155
+ */
149
156
  //
150
157
 
151
158
  const shadowColor = texture( rtt.texture, shadowCoord );
159
+ const shadowMaskNode = frustumTest.mix( 1, shadowNode.mix( shadowColor.a.mix( 1, shadowColor ), 1 ) );
152
160
 
153
161
  this.rtt = rtt;
154
- this.colorNode = this.colorNode.mul( frustumTest.mix( 1, shadowNode.mix( shadowColor.a.mix( 1, shadowColor ), 1 ) ) );
162
+ this.colorNode = this.colorNode.mul( shadowMaskNode );
155
163
 
156
164
  this.shadowNode = shadowNode;
165
+ this.shadowMaskNode = shadowMaskNode;
157
166
 
158
167
  //
159
168
 
@@ -183,6 +192,7 @@ class AnalyticLightNode extends LightingNode {
183
192
 
184
193
  light.shadow.updateMatrices( light );
185
194
 
195
+ const currentToneMapping = renderer.toneMapping;
186
196
  const currentRenderTarget = renderer.getRenderTarget();
187
197
  const currentRenderObjectFunction = renderer.getRenderObjectFunction();
188
198
 
@@ -197,12 +207,15 @@ class AnalyticLightNode extends LightingNode {
197
207
  } );
198
208
 
199
209
  renderer.setRenderTarget( rtt );
210
+ renderer.toneMapping = NoToneMapping;
200
211
 
201
212
  renderer.render( scene, light.shadow.camera );
202
213
 
203
214
  renderer.setRenderTarget( currentRenderTarget );
204
215
  renderer.setRenderObjectFunction( currentRenderObjectFunction );
205
216
 
217
+ renderer.toneMapping = currentToneMapping;
218
+
206
219
  scene.overrideMaterial = currentOverrideMaterial;
207
220
 
208
221
  }
@@ -212,6 +225,7 @@ class AnalyticLightNode extends LightingNode {
212
225
  this.rtt.dispose();
213
226
 
214
227
  this.shadowNode = null;
228
+ this.shadowMaskNode = null;
215
229
  this.rtt = null;
216
230
 
217
231
  this.colorNode = this._defaultColorNode;
@@ -26,7 +26,8 @@ class DirectionalLightNode extends AnalyticLightNode {
26
26
  lightingModel.direct( {
27
27
  lightDirection,
28
28
  lightColor,
29
- reflectedLight
29
+ reflectedLight,
30
+ shadowMask: this.shadowMaskNode
30
31
  }, builder.stack, builder );
31
32
 
32
33
  }
@@ -8,6 +8,7 @@ import { positionViewDirection } from '../accessors/PositionNode.js';
8
8
  import { addNodeClass } from '../core/Node.js';
9
9
  import { float } from '../shadernode/ShaderNode.js';
10
10
  import { reference } from '../accessors/ReferenceNode.js';
11
+ import { transformedBentNormalView } from '../accessors/AccessorsUtils.js';
11
12
  import { pmremTexture } from '../pmrem/PMREMNode.js';
12
13
 
13
14
  const envNodeCache = new WeakMap();
@@ -44,10 +45,15 @@ class EnvironmentNode extends LightingNode {
44
45
 
45
46
  //
46
47
 
47
- const envMap = builder.material.envMap;
48
+ const { material } = builder;
49
+
50
+ const envMap = material.envMap;
48
51
  const intensity = envMap ? reference( 'envMapIntensity', 'float', builder.material ) : reference( 'environmentIntensity', 'float', builder.scene ); // @TODO: Add materialEnvIntensity in MaterialNode
49
52
 
50
- const radiance = context( envNode, createRadianceContext( roughness, transformedNormalView ) ).mul( intensity );
53
+ const useAnisotropy = material.useAnisotropy === true || material.anisotropy > 0;
54
+ const radianceNormalView = useAnisotropy ? transformedBentNormalView : transformedNormalView;
55
+
56
+ const radiance = context( envNode, createRadianceContext( roughness, radianceNormalView ) ).mul( intensity );
51
57
  const irradiance = context( envNode, createIrradianceContext( transformedNormalWorld ) ).mul( Math.PI ).mul( intensity );
52
58
 
53
59
  const isolateRadiance = cache( radiance );
@@ -85,7 +91,10 @@ const createRadianceContext = ( roughnessNode, normalViewNode ) => {
85
91
  if ( reflectVec === null ) {
86
92
 
87
93
  reflectVec = positionViewDirection.negate().reflect( normalViewNode );
94
+
95
+ // Mixing the reflection with the normal is more accurate and keeps rough objects from gathering light from behind their tangent plane.
88
96
  reflectVec = roughnessNode.mul( roughnessNode ).mix( reflectVec, normalViewNode ).normalize();
97
+
89
98
  reflectVec = reflectVec.transformDirection( cameraViewMatrix );
90
99
 
91
100
  }
@@ -0,0 +1,24 @@
1
+ import LightingNode from './LightingNode.js';
2
+ import { addNodeClass } from '../core/Node.js';
3
+
4
+ class IrradianceNode extends LightingNode {
5
+
6
+ constructor( node ) {
7
+
8
+ super();
9
+
10
+ this.node = node;
11
+
12
+ }
13
+
14
+ setup( builder ) {
15
+
16
+ builder.context.irradiance.addAssign( this.node );
17
+
18
+ }
19
+
20
+ }
21
+
22
+ export default IrradianceNode;
23
+
24
+ addNodeClass( 'IrradianceNode', IrradianceNode );
@@ -95,7 +95,17 @@ class LightsNode extends Node {
95
95
 
96
96
  if ( backdrop !== null ) {
97
97
 
98
- totalDiffuse = vec3( backdropAlpha !== null ? backdropAlpha.mix( totalDiffuse, backdrop ) : backdrop );
98
+ if ( backdropAlpha !== null ) {
99
+
100
+ totalDiffuse = vec3( backdropAlpha.mix( totalDiffuse, backdrop ) );
101
+
102
+ } else {
103
+
104
+ totalDiffuse = vec3( backdrop );
105
+
106
+ }
107
+
108
+ context.material.transparent = true;
99
109
 
100
110
  }
101
111
 
@@ -54,7 +54,8 @@ class PointLightNode extends AnalyticLightNode {
54
54
  lightingModel.direct( {
55
55
  lightDirection,
56
56
  lightColor,
57
- reflectedLight
57
+ reflectedLight,
58
+ shadowMask: this.shadowMaskNode
58
59
  }, builder.stack, builder );
59
60
 
60
61
  }
@@ -75,7 +75,8 @@ class SpotLightNode extends AnalyticLightNode {
75
75
  lightingModel.direct( {
76
76
  lightDirection,
77
77
  lightColor,
78
- reflectedLight
78
+ reflectedLight,
79
+ shadowMask: this.shadowMaskNode
79
80
  }, builder.stack, builder );
80
81
 
81
82
  }
@@ -43,9 +43,15 @@ class Line2NodeMaterial extends NodeMaterial {
43
43
  this.dashSizeNode = null;
44
44
  this.gapSizeNode = null;
45
45
 
46
+ this.setValues( params );
47
+
48
+ }
49
+
50
+ setup( builder ) {
51
+
46
52
  this.setupShaders();
47
53
 
48
- this.setValues( params );
54
+ super.setup( builder );
49
55
 
50
56
  }
51
57
 
@@ -371,8 +377,6 @@ class Line2NodeMaterial extends NodeMaterial {
371
377
 
372
378
  } )();
373
379
 
374
- this.needsUpdate = true;
375
-
376
380
  }
377
381
 
378
382
 
@@ -387,7 +391,7 @@ class Line2NodeMaterial extends NodeMaterial {
387
391
  if ( this.useWorldUnits !== value ) {
388
392
 
389
393
  this.useWorldUnits = value;
390
- this.setupShaders();
394
+ this.needsUpdate = true;
391
395
 
392
396
  }
393
397
 
@@ -405,7 +409,7 @@ class Line2NodeMaterial extends NodeMaterial {
405
409
  if ( this.useDash !== value ) {
406
410
 
407
411
  this.useDash = value;
408
- this.setupShaders();
412
+ this.needsUpdate = true;
409
413
 
410
414
  }
411
415
 
@@ -423,7 +427,7 @@ class Line2NodeMaterial extends NodeMaterial {
423
427
  if ( this.useAlphaToCoverage !== value ) {
424
428
 
425
429
  this.useAlphaToCoverage = value;
426
- this.setupShaders();
430
+ this.needsUpdate = true;
427
431
 
428
432
  }
429
433
 
@@ -14,3 +14,4 @@ export { default as MeshPhysicalNodeMaterial } from './MeshPhysicalNodeMaterial.
14
14
  export { default as MeshSSSNodeMaterial } from './MeshSSSNodeMaterial.js';
15
15
  export { default as PointsNodeMaterial } from './PointsNodeMaterial.js';
16
16
  export { default as SpriteNodeMaterial } from './SpriteNodeMaterial.js';
17
+ export { default as ShadowNodeMaterial } from './ShadowNodeMaterial.js';
@@ -17,8 +17,6 @@ class MeshNormalNodeMaterial extends NodeMaterial {
17
17
 
18
18
  this.isMeshNormalNodeMaterial = true;
19
19
 
20
- this.colorSpaced = false;
21
-
22
20
  this.setDefaultValues( defaultValues );
23
21
 
24
22
  this.setValues( parameters );
@@ -1,6 +1,6 @@
1
1
  import NodeMaterial, { addNodeMaterial } from './NodeMaterial.js';
2
2
  import { shininess, specularColor } from '../core/PropertyNode.js';
3
- import { materialShininess, materialSpecularColor } from '../accessors/MaterialNode.js';
3
+ import { materialShininess, materialSpecular } from '../accessors/MaterialNode.js';
4
4
  import { float } from '../shadernode/ShaderNode.js';
5
5
  import PhongLightingModel from '../functions/PhongLightingModel.js';
6
6
 
@@ -43,7 +43,7 @@ class MeshPhongNodeMaterial extends NodeMaterial {
43
43
 
44
44
  // SPECULAR COLOR
45
45
 
46
- const specularNode = this.specularNode || materialSpecularColor;
46
+ const specularNode = this.specularNode || materialSpecular;
47
47
 
48
48
  specularColor.assign( specularNode );
49
49
 
@@ -1,11 +1,12 @@
1
1
  import { addNodeMaterial } from './NodeMaterial.js';
2
2
  import { transformedClearcoatNormalView } from '../accessors/NormalNode.js';
3
- import { clearcoat, clearcoatRoughness, sheen, sheenRoughness, iridescence, iridescenceIOR, iridescenceThickness } from '../core/PropertyNode.js';
4
- import { materialClearcoat, materialClearcoatRoughness, materialClearcoatNormal, materialSheen, materialSheenRoughness, materialIridescence, materialIridescenceIOR, materialIridescenceThickness } from '../accessors/MaterialNode.js';
5
- import { float, vec3 } from '../shadernode/ShaderNode.js';
3
+ import { clearcoat, clearcoatRoughness, sheen, sheenRoughness, iridescence, iridescenceIOR, iridescenceThickness, specularColor, specularF90, diffuseColor, metalness, roughness, anisotropy, alphaT, anisotropyT, anisotropyB, ior, transmission, thickness, attenuationDistance, attenuationColor } from '../core/PropertyNode.js';
4
+ import { materialClearcoat, materialClearcoatRoughness, materialClearcoatNormal, materialSheen, materialSheenRoughness, materialIridescence, materialIridescenceIOR, materialIridescenceThickness, materialSpecularIntensity, materialSpecularColor, materialAnisotropy, materialIOR, materialTransmission, materialThickness, materialAttenuationDistance, materialAttenuationColor } from '../accessors/MaterialNode.js';
5
+ import { float, vec2, vec3, If } from '../shadernode/ShaderNode.js';
6
+ import { TBNViewMatrix } from '../accessors/AccessorsUtils.js';
6
7
  import PhysicalLightingModel from '../functions/PhysicalLightingModel.js';
7
8
  import MeshStandardNodeMaterial from './MeshStandardNodeMaterial.js';
8
-
9
+ import { mix, pow2, min } from '../math/MathNode.js';
9
10
  import { MeshPhysicalMaterial } from 'three';
10
11
 
11
12
  const defaultValues = new MeshPhysicalMaterial();
@@ -32,11 +33,14 @@ class MeshPhysicalNodeMaterial extends MeshStandardNodeMaterial {
32
33
  this.specularIntensityNode = null;
33
34
  this.specularColorNode = null;
34
35
 
36
+ this.iorNode = null;
35
37
  this.transmissionNode = null;
36
38
  this.thicknessNode = null;
37
39
  this.attenuationDistanceNode = null;
38
40
  this.attenuationColorNode = null;
39
41
 
42
+ this.anisotropyNode = null;
43
+
40
44
  this.setDefaultValues( defaultValues );
41
45
 
42
46
  this.setValues( parameters );
@@ -61,9 +65,31 @@ class MeshPhysicalNodeMaterial extends MeshStandardNodeMaterial {
61
65
 
62
66
  }
63
67
 
68
+ get useAnisotropy() {
69
+
70
+ return this.anisotropy > 0 || this.anisotropyNode !== null;
71
+
72
+ }
73
+
74
+ get useTransmission() {
75
+
76
+ return this.transmission > 0 || this.transmissionNode !== null;
77
+
78
+ }
79
+
80
+ setupSpecular() {
81
+
82
+ const iorNode = this.iorNode ? float( this.iorNode ) : materialIOR;
83
+
84
+ ior.assign( iorNode );
85
+ specularColor.assign( mix( min( pow2( ior.sub( 1.0 ).div( ior.add( 1.0 ) ) ).mul( materialSpecularColor ), vec3( 1.0 ) ).mul( materialSpecularIntensity ), diffuseColor.rgb, metalness ) );
86
+ specularF90.assign( mix( materialSpecularIntensity, 1.0, metalness ) );
87
+
88
+ }
89
+
64
90
  setupLightingModel( /*builder*/ ) {
65
91
 
66
- return new PhysicalLightingModel( this.useClearcoat, this.useSheen, this.useIridescence );
92
+ return new PhysicalLightingModel( this.useClearcoat, this.useSheen, this.useIridescence, this.useAnisotropy, this.useTransmission );
67
93
 
68
94
  }
69
95
 
@@ -109,6 +135,49 @@ class MeshPhysicalNodeMaterial extends MeshStandardNodeMaterial {
109
135
 
110
136
  }
111
137
 
138
+ // ANISOTROPY
139
+
140
+ if ( this.useAnisotropy ) {
141
+
142
+ const anisotropyV = ( this.anisotropyNode ? vec2( this.anisotropyNode ) : materialAnisotropy ).toVar();
143
+
144
+ anisotropy.assign( anisotropyV.length() );
145
+
146
+ If( anisotropy.equal( 0.0 ), () => {
147
+
148
+ anisotropyV.assign( vec2( 1.0, 0.0 ) );
149
+
150
+ } ).else( () => {
151
+
152
+ anisotropyV.divAssign( anisotropy );
153
+ anisotropy.assign( anisotropy.saturate() );
154
+
155
+ } );
156
+
157
+ // Roughness along the anisotropy bitangent is the material roughness, while the tangent roughness increases with anisotropy.
158
+ alphaT.assign( anisotropy.pow2().mix( roughness.pow2(), 1.0 ) );
159
+
160
+ anisotropyT.assign( TBNViewMatrix[ 0 ].mul( anisotropyV.x ).add( TBNViewMatrix[ 1 ].mul( anisotropyV.y ) ) );
161
+ anisotropyB.assign( TBNViewMatrix[ 1 ].mul( anisotropyV.x ).sub( TBNViewMatrix[ 0 ].mul( anisotropyV.y ) ) );
162
+
163
+ }
164
+
165
+ // TRANSMISSION
166
+
167
+ if ( this.useTransmission ) {
168
+
169
+ const transmissionNode = this.transmissionNode ? float( this.transmissionNode ) : materialTransmission;
170
+ const thicknessNode = this.thicknessNode ? float( this.thicknessNode ) : materialThickness;
171
+ const attenuationDistanceNode = this.attenuationDistanceNode ? float( this.attenuationDistanceNode ) : materialAttenuationDistance;
172
+ const attenuationColorNode = this.attenuationColorNode ? vec3( this.attenuationColorNode ) : materialAttenuationColor;
173
+
174
+ transmission.assign( transmissionNode );
175
+ thickness.assign( thicknessNode );
176
+ attenuationDistance.assign( attenuationDistanceNode );
177
+ attenuationColor.assign( attenuationColorNode );
178
+
179
+ }
180
+
112
181
  }
113
182
 
114
183
  setupNormal( builder ) {
@@ -144,6 +213,8 @@ class MeshPhysicalNodeMaterial extends MeshStandardNodeMaterial {
144
213
  this.attenuationDistanceNode = source.attenuationDistanceNode;
145
214
  this.attenuationColorNode = source.attenuationColorNode;
146
215
 
216
+ this.anisotropyNode = source.anisotropyNode;
217
+
147
218
  return super.copy( source );
148
219
 
149
220
  }
@@ -1,5 +1,5 @@
1
1
  import NodeMaterial, { addNodeMaterial } from './NodeMaterial.js';
2
- import { diffuseColor, metalness, roughness, specularColor } from '../core/PropertyNode.js';
2
+ import { diffuseColor, metalness, roughness, specularColor, specularF90 } from '../core/PropertyNode.js';
3
3
  import { mix } from '../math/MathNode.js';
4
4
  import { materialRoughness, materialMetalness } from '../accessors/MaterialNode.js';
5
5
  import getRoughness from '../functions/material/getRoughness.js';
@@ -35,6 +35,15 @@ class MeshStandardNodeMaterial extends NodeMaterial {
35
35
 
36
36
  }
37
37
 
38
+ setupSpecular() {
39
+
40
+ const specularColorNode = mix( vec3( 0.04 ), diffuseColor.rgb, metalness );
41
+
42
+ specularColor.assign( specularColorNode );
43
+ specularF90.assign( 1.0 );
44
+
45
+ }
46
+
38
47
  setupVariants() {
39
48
 
40
49
  // METALNESS
@@ -52,9 +61,7 @@ class MeshStandardNodeMaterial extends NodeMaterial {
52
61
 
53
62
  // SPECULAR COLOR
54
63
 
55
- const specularColorNode = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessNode );
56
-
57
- specularColor.assign( specularColorNode );
64
+ this.setupSpecular();
58
65
 
59
66
  // DIFFUSE COLOR
60
67
 
@@ -1,4 +1,4 @@
1
- import { Material, ShaderMaterial, NoColorSpace, LinearSRGBColorSpace } from 'three';
1
+ import { Material, ShaderMaterial } from 'three';
2
2
  import { getNodeChildren, getCacheKey } from '../core/NodeUtils.js';
3
3
  import { attribute } from '../core/AttributeNode.js';
4
4
  import { output, diffuseColor, varyingProperty } from '../core/PropertyNode.js';
@@ -7,7 +7,7 @@ import { modelViewProjection } from '../accessors/ModelViewProjectionNode.js';
7
7
  import { transformedNormalView } from '../accessors/NormalNode.js';
8
8
  import { instance } from '../accessors/InstanceNode.js';
9
9
  import { batch } from '../accessors/BatchNode.js';
10
-
10
+ import { materialReference } from '../accessors/MaterialReferenceNode.js';
11
11
  import { positionLocal, positionView } from '../accessors/PositionNode.js';
12
12
  import { skinningReference } from '../accessors/SkinningNode.js';
13
13
  import { morphReference } from '../accessors/MorphNode.js';
@@ -19,6 +19,7 @@ import { float, vec3, vec4 } from '../shadernode/ShaderNode.js';
19
19
  import AONode from '../lighting/AONode.js';
20
20
  import { lightingContext } from '../lighting/LightingContextNode.js';
21
21
  import EnvironmentNode from '../lighting/EnvironmentNode.js';
22
+ import IrradianceNode from '../lighting/IrradianceNode.js';
22
23
  import { depthPixel } from '../display/ViewportDepthNode.js';
23
24
  import { cameraLogDepth } from '../accessors/CameraNode.js';
24
25
  import { clipping, clippingAlpha } from '../accessors/ClippingNode.js';
@@ -42,10 +43,9 @@ class NodeMaterial extends ShaderMaterial {
42
43
  this.lights = true;
43
44
  this.normals = true;
44
45
 
45
- this.colorSpaced = true;
46
-
47
46
  this.lightsNode = null;
48
47
  this.envNode = null;
48
+ this.aoNode = null;
49
49
 
50
50
  this.colorNode = null;
51
51
  this.normalNode = null;
@@ -58,6 +58,7 @@ class NodeMaterial extends ShaderMaterial {
58
58
 
59
59
  this.depthNode = null;
60
60
  this.shadowNode = null;
61
+ this.shadowPositionNode = null;
61
62
 
62
63
  this.outputNode = null;
63
64
 
@@ -96,9 +97,9 @@ class NodeMaterial extends ShaderMaterial {
96
97
 
97
98
  const clippingNode = this.setupClipping( builder );
98
99
 
99
- if ( this.fragmentNode === null ) {
100
+ if ( this.depthWrite === true ) this.setupDepth( builder );
100
101
 
101
- if ( this.depthWrite === true ) this.setupDepth( builder );
102
+ if ( this.fragmentNode === null ) {
102
103
 
103
104
  if ( this.normals === true ) this.setupNormal( builder );
104
105
 
@@ -125,7 +126,15 @@ class NodeMaterial extends ShaderMaterial {
125
126
 
126
127
  } else {
127
128
 
128
- resultNode = this.setupOutput( builder, this.fragmentNode );
129
+ let fragmentNode = this.fragmentNode;
130
+
131
+ if ( fragmentNode.isOutputStructNode !== true ) {
132
+
133
+ fragmentNode = vec4( fragmentNode );
134
+
135
+ }
136
+
137
+ resultNode = this.setupOutput( builder, fragmentNode );
129
138
 
130
139
  }
131
140
 
@@ -137,6 +146,8 @@ class NodeMaterial extends ShaderMaterial {
137
146
 
138
147
  setupClipping( builder ) {
139
148
 
149
+ if ( builder.clippingContext === null ) return null;
150
+
140
151
  const { globalClippingCount, localClippingCount } = builder.clippingContext;
141
152
 
142
153
  let result = null;
@@ -337,9 +348,17 @@ class NodeMaterial extends ShaderMaterial {
337
348
 
338
349
  }
339
350
 
340
- if ( builder.material.aoMap ) {
351
+ if ( builder.material.lightMap ) {
352
+
353
+ materialLightsNode.push( new IrradianceNode( materialReference( 'lightMap', 'texture' ) ) );
354
+
355
+ }
356
+
357
+ if ( this.aoNode !== null || builder.material.aoMap ) {
358
+
359
+ const aoNode = this.aoNode !== null ? this.aoNode : texture( builder.material.aoMap );
341
360
 
342
- materialLightsNode.push( new AONode( texture( builder.material.aoMap ) ) );
361
+ materialLightsNode.push( new AONode( aoNode ) );
343
362
 
344
363
  }
345
364
 
@@ -400,41 +419,11 @@ class NodeMaterial extends ShaderMaterial {
400
419
 
401
420
  setupOutput( builder, outputNode ) {
402
421
 
403
- const renderer = builder.renderer;
404
-
405
422
  // FOG
406
423
 
407
- if ( this.fog === true ) {
408
-
409
- const fogNode = builder.fogNode;
424
+ const fogNode = builder.fogNode;
410
425
 
411
- if ( fogNode ) outputNode = vec4( fogNode.mix( outputNode.rgb, fogNode.colorNode ), outputNode.a );
412
-
413
- }
414
-
415
- // TONE MAPPING
416
-
417
- const toneMappingNode = builder.toneMappingNode;
418
-
419
- if ( this.toneMapped === true && toneMappingNode ) {
420
-
421
- outputNode = vec4( toneMappingNode.context( { color: outputNode.rgb } ), outputNode.a );
422
-
423
- }
424
-
425
- // ENCODING
426
-
427
- if ( this.colorSpaced === true ) {
428
-
429
- const outputColorSpace = renderer.currentColorSpace;
430
-
431
- if ( outputColorSpace !== LinearSRGBColorSpace && outputColorSpace !== NoColorSpace ) {
432
-
433
- outputNode = outputNode.linearToColorSpace( outputColorSpace );
434
-
435
- }
436
-
437
- }
426
+ if ( fogNode ) outputNode = vec4( fogNode.mix( outputNode.rgb, fogNode.colorNode ), outputNode.a );
438
427
 
439
428
  return outputNode;
440
429
 
@@ -551,6 +540,7 @@ class NodeMaterial extends ShaderMaterial {
551
540
 
552
541
  this.depthNode = source.depthNode;
553
542
  this.shadowNode = source.shadowNode;
543
+ this.shadowPositionNode = source.shadowPositionNode;
554
544
 
555
545
  this.outputNode = source.outputNode;
556
546
 
@@ -0,0 +1,34 @@
1
+ import NodeMaterial, { addNodeMaterial } from './NodeMaterial.js';
2
+ import ShadowMaskModel from '../functions/ShadowMaskModel.js';
3
+
4
+ import { ShadowMaterial } from 'three';
5
+
6
+ const defaultValues = new ShadowMaterial();
7
+
8
+ class ShadowNodeMaterial extends NodeMaterial {
9
+
10
+ constructor( parameters ) {
11
+
12
+ super();
13
+
14
+ this.isShadowNodeMaterial = true;
15
+
16
+ this.lights = true;
17
+
18
+ this.setDefaultValues( defaultValues );
19
+
20
+ this.setValues( parameters );
21
+
22
+ }
23
+
24
+ setupLightingModel( /*builder*/ ) {
25
+
26
+ return new ShadowMaskModel();
27
+
28
+ }
29
+
30
+ }
31
+
32
+ export default ShadowNodeMaterial;
33
+
34
+ addNodeMaterial( 'ShadowNodeMaterial', ShadowNodeMaterial );
@@ -237,7 +237,7 @@ const bilinearCubeUV = tslFn( ( [ envMap, direction_immutable, mipInt_immutable,
237
237
  uv.x.mulAssign( CUBEUV_TEXEL_WIDTH );
238
238
  uv.y.mulAssign( CUBEUV_TEXEL_HEIGHT );
239
239
 
240
- return envMap.uv( uv );
240
+ return envMap.uv( uv ).grad( vec2(), vec2() ); // disable anisotropic filtering
241
241
 
242
242
  } );
243
243
 
@@ -456,6 +456,8 @@ const ConvertType = function ( type, cacheMap = null ) {
456
456
 
457
457
  // exports
458
458
 
459
+ export const defined = ( value ) => value && value.value;
460
+
459
461
  // utils
460
462
 
461
463
  export const getConstNodeType = ( value ) => ( value !== undefined && value !== null ) ? ( value.nodeType || value.convertTo || ( typeof value === 'string' ? value : null ) ) : null;
@@ -474,14 +476,6 @@ export const nodeArray = ( val, altType = null ) => new ShaderNodeArray( val, al
474
476
  export const nodeProxy = ( ...params ) => new ShaderNodeProxy( ...params );
475
477
  export const nodeImmutable = ( ...params ) => new ShaderNodeImmutable( ...params );
476
478
 
477
- export const shader = ( jsFunc ) => { // @deprecated, r154
478
-
479
- console.warn( 'TSL: shader() is deprecated. Use tslFn() instead.' );
480
-
481
- return new ShaderNode( jsFunc );
482
-
483
- };
484
-
485
479
  export const tslFn = ( jsFunc ) => {
486
480
 
487
481
  const shaderNode = new ShaderNode( jsFunc );