super-three 0.162.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 (187) hide show
  1. package/build/three.cjs +847 -1226
  2. package/build/three.module.js +846 -1225
  3. package/build/three.module.min.js +2 -2
  4. package/examples/jsm/animation/CCDIKSolver.js +4 -2
  5. package/examples/jsm/controls/TransformControls.js +3 -3
  6. package/examples/jsm/exporters/GLTFExporter.js +66 -5
  7. package/examples/jsm/exporters/USDZExporter.js +22 -1
  8. package/examples/jsm/geometries/TextGeometry.js +10 -2
  9. package/examples/jsm/interactive/HTMLMesh.js +7 -9
  10. package/examples/jsm/libs/draco/README.md +2 -2
  11. package/examples/jsm/libs/fflate.module.js +694 -496
  12. package/examples/jsm/lines/LineMaterial.js +0 -2
  13. package/examples/jsm/loaders/3MFLoader.js +2 -0
  14. package/examples/jsm/loaders/EXRLoader.js +351 -97
  15. package/examples/jsm/loaders/FBXLoader.js +1 -1
  16. package/examples/jsm/loaders/GLTFLoader.js +59 -0
  17. package/examples/jsm/loaders/KTX2Loader.js +3 -10
  18. package/examples/jsm/loaders/LUT3dlLoader.js +0 -15
  19. package/examples/jsm/loaders/LUTCubeLoader.js +0 -14
  20. package/examples/jsm/loaders/LUTImageLoader.js +0 -14
  21. package/examples/jsm/loaders/RGBMLoader.js +16 -0
  22. package/examples/jsm/loaders/VRMLLoader.js +1 -1
  23. package/examples/jsm/loaders/lwo/IFFParser.js +8 -5
  24. package/examples/jsm/materials/MeshGouraudMaterial.js +7 -1
  25. package/examples/jsm/math/Octree.js +26 -20
  26. package/examples/jsm/misc/GPUComputationRenderer.js +0 -6
  27. package/examples/jsm/nodes/Nodes.js +10 -4
  28. package/examples/jsm/nodes/accessors/AccessorsUtils.js +16 -1
  29. package/examples/jsm/nodes/accessors/BatchNode.js +78 -0
  30. package/examples/jsm/nodes/accessors/ClippingNode.js +3 -2
  31. package/examples/jsm/nodes/accessors/InstanceNode.js +25 -2
  32. package/examples/jsm/nodes/accessors/MaterialNode.js +107 -3
  33. package/examples/jsm/nodes/accessors/MaterialReferenceNode.js +1 -1
  34. package/examples/jsm/nodes/accessors/MorphNode.js +13 -3
  35. package/examples/jsm/nodes/accessors/NormalNode.js +12 -2
  36. package/examples/jsm/nodes/accessors/ReferenceNode.js +1 -1
  37. package/examples/jsm/nodes/accessors/RendererReferenceNode.js +29 -0
  38. package/examples/jsm/nodes/accessors/StorageBufferNode.js +9 -0
  39. package/examples/jsm/nodes/accessors/TextureNode.js +51 -10
  40. package/examples/jsm/nodes/accessors/TextureSizeNode.js +1 -1
  41. package/examples/jsm/nodes/code/FunctionNode.js +0 -8
  42. package/examples/jsm/nodes/core/Node.js +63 -4
  43. package/examples/jsm/nodes/core/NodeBuilder.js +26 -25
  44. package/examples/jsm/nodes/core/NodeFrame.js +10 -10
  45. package/examples/jsm/nodes/core/NodeUtils.js +2 -2
  46. package/examples/jsm/nodes/core/OutputStructNode.js +2 -1
  47. package/examples/jsm/nodes/core/PropertyNode.js +10 -0
  48. package/examples/jsm/nodes/core/UniformNode.js +20 -0
  49. package/examples/jsm/nodes/display/BumpMapNode.js +7 -26
  50. package/examples/jsm/nodes/display/FrontFacingNode.js +13 -0
  51. package/examples/jsm/nodes/display/PassNode.js +17 -1
  52. package/examples/jsm/nodes/display/ToneMappingNode.js +8 -4
  53. package/examples/jsm/nodes/display/ViewportDepthNode.js +1 -1
  54. package/examples/jsm/nodes/display/ViewportNode.js +4 -2
  55. package/examples/jsm/nodes/display/ViewportSharedTextureNode.js +6 -0
  56. package/examples/jsm/nodes/display/ViewportTextureNode.js +4 -1
  57. package/examples/jsm/nodes/fog/FogExp2Node.js +4 -5
  58. package/examples/jsm/nodes/fog/FogNode.js +13 -3
  59. package/examples/jsm/nodes/fog/FogRangeNode.js +4 -3
  60. package/examples/jsm/nodes/functions/BSDF/BRDF_GGX.js +26 -7
  61. package/examples/jsm/nodes/functions/BSDF/D_GGX_Anisotropic.js +28 -0
  62. package/examples/jsm/nodes/functions/BSDF/V_GGX_SmithCorrelated.js +1 -3
  63. package/examples/jsm/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.js +29 -0
  64. package/examples/jsm/nodes/functions/PhongLightingModel.js +1 -1
  65. package/examples/jsm/nodes/functions/PhysicalLightingModel.js +164 -10
  66. package/examples/jsm/nodes/functions/ShadowMaskModel.js +31 -0
  67. package/examples/jsm/nodes/lighting/AnalyticLightNode.js +19 -5
  68. package/examples/jsm/nodes/lighting/DirectionalLightNode.js +2 -1
  69. package/examples/jsm/nodes/lighting/EnvironmentNode.js +22 -70
  70. package/examples/jsm/nodes/lighting/IrradianceNode.js +24 -0
  71. package/examples/jsm/nodes/lighting/LightsNode.js +11 -1
  72. package/examples/jsm/nodes/lighting/PointLightNode.js +2 -1
  73. package/examples/jsm/nodes/lighting/SpotLightNode.js +2 -1
  74. package/examples/jsm/nodes/materials/Line2NodeMaterial.js +10 -6
  75. package/examples/jsm/nodes/materials/Materials.js +1 -0
  76. package/examples/jsm/nodes/materials/MeshNormalNodeMaterial.js +0 -2
  77. package/examples/jsm/nodes/materials/MeshPhongNodeMaterial.js +2 -2
  78. package/examples/jsm/nodes/materials/MeshPhysicalNodeMaterial.js +76 -5
  79. package/examples/jsm/nodes/materials/MeshStandardNodeMaterial.js +11 -4
  80. package/examples/jsm/nodes/materials/NodeMaterial.js +55 -43
  81. package/examples/jsm/nodes/materials/ShadowNodeMaterial.js +34 -0
  82. package/examples/jsm/nodes/pmrem/PMREMNode.js +193 -0
  83. package/examples/jsm/nodes/pmrem/PMREMUtils.js +288 -0
  84. package/examples/jsm/nodes/shadernode/ShaderNode.js +3 -9
  85. package/examples/jsm/nodes/utils/EquirectUVNode.js +1 -1
  86. package/examples/jsm/objects/QuadMesh.js +7 -23
  87. package/examples/jsm/physics/JoltPhysics.js +281 -0
  88. package/examples/jsm/physics/RapierPhysics.js +4 -4
  89. package/examples/jsm/postprocessing/GlitchPass.js +0 -3
  90. package/examples/jsm/postprocessing/LUTPass.js +5 -71
  91. package/examples/jsm/postprocessing/RenderTransitionPass.js +193 -0
  92. package/examples/jsm/postprocessing/SAOPass.js +0 -1
  93. package/examples/jsm/postprocessing/SSAOPass.js +0 -3
  94. package/examples/jsm/renderers/common/Animation.js +3 -0
  95. package/examples/jsm/renderers/common/Background.js +8 -8
  96. package/examples/jsm/renderers/common/ClippingContext.js +1 -1
  97. package/examples/jsm/renderers/common/Info.js +11 -19
  98. package/examples/jsm/renderers/common/PostProcessing.js +12 -4
  99. package/examples/jsm/renderers/common/RenderContext.js +1 -1
  100. package/examples/jsm/renderers/common/RenderList.js +1 -1
  101. package/examples/jsm/renderers/common/RenderObject.js +47 -5
  102. package/examples/jsm/renderers/common/RenderObjects.js +1 -1
  103. package/examples/jsm/renderers/common/Renderer.js +153 -21
  104. package/examples/jsm/renderers/common/Textures.js +1 -1
  105. package/examples/jsm/renderers/common/extras/PMREMGenerator.js +773 -0
  106. package/examples/jsm/renderers/common/nodes/Nodes.js +34 -63
  107. package/examples/jsm/renderers/webgl/WebGLBackend.js +146 -36
  108. package/examples/jsm/renderers/webgl/WebGLBufferRenderer.js +145 -0
  109. package/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js +9 -3
  110. package/examples/jsm/renderers/webgl/utils/WebGLAttributeUtils.js +1 -1
  111. package/examples/jsm/renderers/webgl/utils/WebGLConstants.js +1 -0
  112. package/examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js +64 -7
  113. package/examples/jsm/renderers/webgl/utils/WebGLUtils.js +6 -23
  114. package/examples/jsm/renderers/webgpu/WebGPUBackend.js +77 -60
  115. package/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js +21 -4
  116. package/examples/jsm/renderers/webgpu/utils/WebGPUAttributeUtils.js +29 -1
  117. package/examples/jsm/renderers/webgpu/utils/WebGPUBindingUtils.js +18 -4
  118. package/examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js +92 -18
  119. package/examples/jsm/transpiler/GLSLDecoder.js +1 -1
  120. package/examples/jsm/transpiler/ShaderToyDecoder.js +1 -1
  121. package/examples/jsm/utils/GPUStatsPanel.js +10 -45
  122. package/examples/jsm/utils/SceneUtils.js +60 -1
  123. package/examples/jsm/utils/TextureUtils.js +1 -1
  124. package/examples/jsm/webxr/OculusHandModel.js +3 -2
  125. package/examples/jsm/webxr/XRHandModelFactory.js +4 -2
  126. package/package.json +1 -1
  127. package/src/Three.js +0 -1
  128. package/src/animation/AnimationClip.js +1 -1
  129. package/src/constants.js +3 -3
  130. package/src/core/Object3D.js +10 -7
  131. package/src/core/RenderTarget.js +8 -0
  132. package/src/extras/PMREMGenerator.js +21 -11
  133. package/src/loaders/FileLoader.js +1 -1
  134. package/src/loaders/MaterialLoader.js +1 -0
  135. package/src/loaders/ObjectLoader.js +2 -0
  136. package/src/materials/Material.js +2 -0
  137. package/src/materials/MeshPhysicalMaterial.js +20 -0
  138. package/src/materials/ShaderMaterial.js +0 -4
  139. package/src/math/Spherical.js +4 -5
  140. package/src/objects/BatchedMesh.js +27 -3
  141. package/src/objects/InstancedMesh.js +10 -0
  142. package/src/objects/Line.js +66 -43
  143. package/src/renderers/WebGLRenderer.js +130 -158
  144. package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +6 -0
  145. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +1 -0
  146. package/src/renderers/shaders/ShaderChunk/logdepthbuf_fragment.glsl.js +2 -2
  147. package/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_fragment.glsl.js +1 -1
  148. package/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_vertex.glsl.js +2 -10
  149. package/src/renderers/shaders/ShaderChunk/logdepthbuf_vertex.glsl.js +2 -16
  150. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +32 -22
  151. package/src/renderers/shaders/ShaderChunk/tonemapping_pars_fragment.glsl.js +17 -9
  152. package/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js +1 -1
  153. package/src/renderers/shaders/ShaderChunk/transmission_pars_fragment.glsl.js +47 -13
  154. package/src/renderers/shaders/ShaderChunk.js +0 -2
  155. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +4 -0
  156. package/src/renderers/shaders/ShaderLib.js +2 -1
  157. package/src/renderers/shaders/UniformsUtils.js +10 -1
  158. package/src/renderers/webgl/WebGLAttributes.js +6 -33
  159. package/src/renderers/webgl/WebGLBackground.js +18 -3
  160. package/src/renderers/webgl/WebGLBindingStates.js +14 -51
  161. package/src/renderers/webgl/WebGLBufferRenderer.js +35 -21
  162. package/src/renderers/webgl/WebGLCapabilities.js +35 -13
  163. package/src/renderers/webgl/WebGLCubeUVMaps.js +10 -6
  164. package/src/renderers/webgl/WebGLExtensions.js +4 -19
  165. package/src/renderers/webgl/WebGLIndexedBufferRenderer.js +35 -21
  166. package/src/renderers/webgl/WebGLLights.js +6 -32
  167. package/src/renderers/webgl/WebGLMaterials.js +8 -3
  168. package/src/renderers/webgl/WebGLMorphtargets.js +79 -217
  169. package/src/renderers/webgl/WebGLProgram.js +21 -52
  170. package/src/renderers/webgl/WebGLPrograms.js +24 -31
  171. package/src/renderers/webgl/WebGLRenderStates.js +13 -7
  172. package/src/renderers/webgl/WebGLShadowMap.js +25 -25
  173. package/src/renderers/webgl/WebGLState.js +15 -59
  174. package/src/renderers/webgl/WebGLTextures.js +138 -292
  175. package/src/renderers/webgl/WebGLUniformsGroups.js +1 -1
  176. package/src/renderers/webgl/WebGLUtils.js +9 -78
  177. package/src/renderers/webxr/WebXRDepthSensing.js +2 -3
  178. package/src/renderers/webxr/WebXRManager.js +4 -6
  179. package/src/scenes/Scene.js +7 -1
  180. package/src/textures/Texture.js +11 -1
  181. package/examples/jsm/nodes/utils/SpecularMIPLevelNode.js +0 -37
  182. package/examples/jsm/renderers/webgl-legacy/nodes/GLSL1NodeBuilder.js +0 -320
  183. package/examples/jsm/renderers/webgl-legacy/nodes/SlotNode.js +0 -26
  184. package/examples/jsm/renderers/webgl-legacy/nodes/WebGLNodeBuilder.js +0 -794
  185. package/examples/jsm/renderers/webgl-legacy/nodes/WebGLNodes.js +0 -51
  186. package/src/renderers/WebGL1Renderer.js +0 -7
  187. package/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl.js +0 -10
@@ -0,0 +1,29 @@
1
+ import { div } from '../../math/OperatorNode.js';
2
+ import { tslFn, vec3 } from '../../shadernode/ShaderNode.js';
3
+
4
+ // https://google.github.io/filament/Filament.md.html#materialsystem/anisotropicmodel/anisotropicspecularbrdf
5
+
6
+ const V_GGX_SmithCorrelated_Anisotropic = tslFn( ( { alphaT, alphaB, dotTV, dotBV, dotTL, dotBL, dotNV, dotNL } ) => {
7
+
8
+ const gv = dotNL.mul( vec3( alphaT.mul( dotTV ), alphaB.mul( dotBV ), dotNV ).length() );
9
+ const gl = dotNV.mul( vec3( alphaT.mul( dotTL ), alphaB.mul( dotBL ), dotNL ).length() );
10
+ const v = div( 0.5, gv.add( gl ) );
11
+
12
+ return v.saturate();
13
+
14
+ } ).setLayout( {
15
+ name: 'V_GGX_SmithCorrelated_Anisotropic',
16
+ type: 'float',
17
+ inputs: [
18
+ { name: 'alphaT', type: 'float', qualifier: 'in' },
19
+ { name: 'alphaB', type: 'float', qualifier: 'in' },
20
+ { name: 'dotTV', type: 'float', qualifier: 'in' },
21
+ { name: 'dotBV', type: 'float', qualifier: 'in' },
22
+ { name: 'dotTL', type: 'float', qualifier: 'in' },
23
+ { name: 'dotBL', type: 'float', qualifier: 'in' },
24
+ { name: 'dotNV', type: 'float', qualifier: 'in' },
25
+ { name: 'dotNL', type: 'float', qualifier: 'in' }
26
+ ]
27
+ } );
28
+
29
+ export default V_GGX_SmithCorrelated_Anisotropic;
@@ -12,7 +12,7 @@ const G_BlinnPhong_Implicit = () => float( 0.25 );
12
12
 
13
13
  const D_BlinnPhong = tslFn( ( { dotNH } ) => {
14
14
 
15
- return shininess.mul( 0.5 / Math.PI ).add( 1.0 ).mul( dotNH.pow( shininess ) );
15
+ return shininess.mul( float( 0.5 ) ).add( 1.0 ).mul( float( 1 / Math.PI ) ).mul( dotNH.pow( shininess ) );
16
16
 
17
17
  } );
18
18
 
@@ -6,12 +6,135 @@ import F_Schlick from './BSDF/F_Schlick.js';
6
6
  import Schlick_to_F0 from './BSDF/Schlick_to_F0.js';
7
7
  import BRDF_Sheen from './BSDF/BRDF_Sheen.js';
8
8
  import LightingModel from '../core/LightingModel.js';
9
- import { diffuseColor, specularColor, roughness, clearcoat, clearcoatRoughness, sheen, sheenRoughness, iridescence, iridescenceIOR, iridescenceThickness } from '../core/PropertyNode.js';
10
- import { transformedNormalView, transformedClearcoatNormalView } from '../accessors/NormalNode.js';
11
- import { positionViewDirection } from '../accessors/PositionNode.js';
12
- import { tslFn, float, vec3, mat3 } from '../shadernode/ShaderNode.js';
9
+ import { diffuseColor, specularColor, specularF90, roughness, clearcoat, clearcoatRoughness, sheen, sheenRoughness, iridescence, iridescenceIOR, iridescenceThickness, ior, thickness, transmission, attenuationDistance, attenuationColor } from '../core/PropertyNode.js';
10
+ import { transformedNormalView, transformedClearcoatNormalView, transformedNormalWorld } from '../accessors/NormalNode.js';
11
+ import { positionViewDirection, positionWorld } from '../accessors/PositionNode.js';
12
+ import { tslFn, float, vec2, vec3, vec4, mat3, If } from '../shadernode/ShaderNode.js';
13
13
  import { cond } from '../math/CondNode.js';
14
- import { mix, smoothstep } from '../math/MathNode.js';
14
+ import { mix, normalize, refract, length, clamp, log2, log, exp, smoothstep } from '../math/MathNode.js';
15
+ import { div } from '../math/OperatorNode.js';
16
+ import { cameraPosition, cameraProjectionMatrix, cameraViewMatrix } from '../accessors/CameraNode.js';
17
+ import { modelWorldMatrix } from '../accessors/ModelNode.js';
18
+ import { viewportResolution } from '../display/ViewportNode.js';
19
+ import { viewportMipTexture } from '../display/ViewportTextureNode.js';
20
+
21
+ //
22
+ // Transmission
23
+ //
24
+
25
+ const getVolumeTransmissionRay = tslFn( ( [ n, v, thickness, ior, modelMatrix ] ) => {
26
+
27
+ // Direction of refracted light.
28
+ const refractionVector = vec3( refract( v.negate(), normalize( n ), div( 1.0, ior ) ) );
29
+
30
+ // Compute rotation-independant scaling of the model matrix.
31
+ const modelScale = vec3(
32
+ length( modelMatrix[ 0 ].xyz ),
33
+ length( modelMatrix[ 1 ].xyz ),
34
+ length( modelMatrix[ 2 ].xyz )
35
+ );
36
+
37
+ // The thickness is specified in local space.
38
+ return normalize( refractionVector ).mul( thickness.mul( modelScale ) );
39
+
40
+ } ).setLayout( {
41
+ name: 'getVolumeTransmissionRay',
42
+ type: 'vec3',
43
+ inputs: [
44
+ { name: 'n', type: 'vec3' },
45
+ { name: 'v', type: 'vec3' },
46
+ { name: 'thickness', type: 'float' },
47
+ { name: 'ior', type: 'float' },
48
+ { name: 'modelMatrix', type: 'mat4' }
49
+ ]
50
+ } );
51
+
52
+ const applyIorToRoughness = tslFn( ( [ roughness, ior ] ) => {
53
+
54
+ // Scale roughness with IOR so that an IOR of 1.0 results in no microfacet refraction and
55
+ // an IOR of 1.5 results in the default amount of microfacet refraction.
56
+ return roughness.mul( clamp( ior.mul( 2.0 ).sub( 2.0 ), 0.0, 1.0 ) );
57
+
58
+ } ).setLayout( {
59
+ name: 'applyIorToRoughness',
60
+ type: 'float',
61
+ inputs: [
62
+ { name: 'roughness', type: 'float' },
63
+ { name: 'ior', type: 'float' }
64
+ ]
65
+ } );
66
+
67
+ const singleViewportMipTexture = viewportMipTexture();
68
+
69
+ const getTransmissionSample = tslFn( ( [ fragCoord, roughness, ior ] ) => {
70
+
71
+ const transmissionSample = singleViewportMipTexture.uv( fragCoord );
72
+ //const transmissionSample = viewportMipTexture( fragCoord );
73
+
74
+ const lod = log2( float( viewportResolution.x ) ).mul( applyIorToRoughness( roughness, ior ) );
75
+
76
+ return transmissionSample.bicubic( lod );
77
+
78
+ } );
79
+
80
+ const volumeAttenuation = tslFn( ( [ transmissionDistance, attenuationColor, attenuationDistance ] ) => {
81
+
82
+ If( attenuationDistance.notEqual( 0 ), () => {
83
+
84
+ // Compute light attenuation using Beer's law.
85
+ const attenuationCoefficient = log( attenuationColor ).negate().div( attenuationDistance );
86
+ const transmittance = exp( attenuationCoefficient.negate().mul( transmissionDistance ) );
87
+
88
+ return transmittance;
89
+
90
+ } );
91
+
92
+ // Attenuation distance is +∞, i.e. the transmitted color is not attenuated at all.
93
+ return vec3( 1.0 );
94
+
95
+ } ).setLayout( {
96
+ name: 'volumeAttenuation',
97
+ type: 'vec3',
98
+ inputs: [
99
+ { name: 'transmissionDistance', type: 'float' },
100
+ { name: 'attenuationColor', type: 'vec3' },
101
+ { name: 'attenuationDistance', type: 'float' }
102
+ ]
103
+ } );
104
+
105
+ const getIBLVolumeRefraction = tslFn( ( [ n, v, roughness, diffuseColor, specularColor, specularF90, position, modelMatrix, viewMatrix, projMatrix, ior, thickness, attenuationColor, attenuationDistance ] ) => {
106
+
107
+ const transmissionRay = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix );
108
+ const refractedRayExit = position.add( transmissionRay );
109
+
110
+ // Project refracted vector on the framebuffer, while mapping to normalized device coordinates.
111
+ const ndcPos = projMatrix.mul( viewMatrix.mul( vec4( refractedRayExit, 1.0 ) ) );
112
+ const refractionCoords = vec2( ndcPos.xy.div( ndcPos.w ) ).toVar();
113
+ refractionCoords.addAssign( 1.0 );
114
+ refractionCoords.divAssign( 2.0 );
115
+ refractionCoords.assign( vec2( refractionCoords.x, refractionCoords.y.oneMinus() ) ); // webgpu
116
+
117
+ // Sample framebuffer to get pixel the refracted ray hits.
118
+ const transmittedLight = getTransmissionSample( refractionCoords, roughness, ior );
119
+ const transmittance = diffuseColor.mul( volumeAttenuation( length( transmissionRay ), attenuationColor, attenuationDistance ) );
120
+ const attenuatedColor = transmittance.rgb.mul( transmittedLight.rgb );
121
+ const dotNV = n.dot( v ).clamp();
122
+
123
+ // Get the specular component.
124
+ const F = vec3( EnvironmentBRDF( { // n, v, specularColor, specularF90, roughness
125
+ dotNV,
126
+ specularColor,
127
+ specularF90,
128
+ roughness
129
+ } ) );
130
+
131
+ // As less light is transmitted, the opacity should be increased. This simple approximation does a decent job
132
+ // of modulating a CSS background, and has no effect when the buffer is opaque, due to a solid object or clear color.
133
+ const transmittanceFactor = transmittance.r.add( transmittance.g, transmittance.b ).div( 3.0 );
134
+
135
+ return vec4( F.oneMinus().mul( attenuatedColor ), transmittedLight.a.oneMinus().mul( transmittanceFactor ).oneMinus() );
136
+
137
+ } );
15
138
 
16
139
  //
17
140
  // Iridescence
@@ -172,13 +295,15 @@ const clearcoatF90 = vec3( 1 );
172
295
 
173
296
  class PhysicalLightingModel extends LightingModel {
174
297
 
175
- constructor( clearcoat = false, sheen = false, iridescence = false ) {
298
+ constructor( clearcoat = false, sheen = false, iridescence = false, anisotropy = false, transmission = false ) {
176
299
 
177
300
  super();
178
301
 
179
302
  this.clearcoat = clearcoat;
180
303
  this.sheen = sheen;
181
304
  this.iridescence = iridescence;
305
+ this.anisotropy = anisotropy;
306
+ this.transmission = transmission;
182
307
 
183
308
  this.clearcoatRadiance = null;
184
309
  this.clearcoatSpecularDirect = null;
@@ -190,7 +315,7 @@ class PhysicalLightingModel extends LightingModel {
190
315
 
191
316
  }
192
317
 
193
- start( /*context*/ ) {
318
+ start( context ) {
194
319
 
195
320
  if ( this.clearcoat === true ) {
196
321
 
@@ -223,13 +348,42 @@ class PhysicalLightingModel extends LightingModel {
223
348
 
224
349
  }
225
350
 
351
+ if ( this.transmission === true ) {
352
+
353
+ const position = positionWorld;
354
+ const v = cameraPosition.sub( positionWorld ).normalize(); // TODO: Create Node for this, same issue in MaterialX
355
+ const n = transformedNormalWorld;
356
+
357
+ context.backdrop = getIBLVolumeRefraction(
358
+ n,
359
+ v,
360
+ roughness,
361
+ diffuseColor,
362
+ specularColor,
363
+ specularF90, // specularF90
364
+ position, // positionWorld
365
+ modelWorldMatrix, // modelMatrix
366
+ cameraViewMatrix, // viewMatrix
367
+ cameraProjectionMatrix, // projMatrix
368
+ ior,
369
+ thickness,
370
+ attenuationColor,
371
+ attenuationDistance
372
+ );
373
+
374
+ context.backdropAlpha = transmission;
375
+
376
+ diffuseColor.a.mulAssign( mix( 1, context.backdrop.a, transmission ) );
377
+
378
+ }
379
+
226
380
  }
227
381
 
228
382
  // Fdez-Agüera's "Multiple-Scattering Microfacet Model for Real-Time Image Based Lighting"
229
383
  // Approximates multiscattering in order to preserve energy.
230
384
  // http://www.jcgt.org/published/0008/01/03/
231
385
 
232
- computeMultiscattering( singleScatter, multiScatter, specularF90 = float( 1 ) ) {
386
+ computeMultiscattering( singleScatter, multiScatter, specularF90 ) {
233
387
 
234
388
  const dotNV = transformedNormalView.dot( positionViewDirection ).clamp(); // @ TODO: Move to core dotNV
235
389
 
@@ -272,7 +426,7 @@ class PhysicalLightingModel extends LightingModel {
272
426
 
273
427
  reflectedLight.directDiffuse.addAssign( irradiance.mul( BRDF_Lambert( { diffuseColor: diffuseColor.rgb } ) ) );
274
428
 
275
- reflectedLight.directSpecular.addAssign( irradiance.mul( BRDF_GGX( { lightDirection, f0: specularColor, f90: 1, roughness, iridescence: this.iridescence, iridescenceFresnel: this.iridescenceFresnel } ) ) );
429
+ reflectedLight.directSpecular.addAssign( irradiance.mul( BRDF_GGX( { lightDirection, f0: specularColor, f90: 1, roughness, iridescence: this.iridescence, f: this.iridescenceFresnel, USE_IRIDESCENCE: this.iridescence, USE_ANISOTROPY: this.anisotropy } ) ) );
276
430
 
277
431
  }
278
432
 
@@ -318,7 +472,7 @@ class PhysicalLightingModel extends LightingModel {
318
472
  const multiScattering = vec3().temp( 'multiScattering' );
319
473
  const cosineWeightedIrradiance = iblIrradiance.mul( 1 / Math.PI );
320
474
 
321
- this.computeMultiscattering( singleScattering, multiScattering );
475
+ this.computeMultiscattering( singleScattering, multiScattering, specularF90 );
322
476
 
323
477
  const totalScattering = singleScattering.add( multiScattering );
324
478
 
@@ -0,0 +1,31 @@
1
+ import LightingModel from '../core/LightingModel.js';
2
+ import { diffuseColor } from '../core/PropertyNode.js';
3
+ import { float } from '../shadernode/ShaderNode.js';
4
+
5
+ class ShadowMaskModel extends LightingModel {
6
+
7
+ constructor() {
8
+
9
+ super();
10
+
11
+ this.shadowNode = float( 1 ).toVar( 'shadowMask' );
12
+
13
+ }
14
+
15
+ direct( { shadowMask } ) {
16
+
17
+ this.shadowNode.mulAssign( shadowMask );
18
+
19
+ }
20
+
21
+ finish( context ) {
22
+
23
+ diffuseColor.a.mulAssign( this.shadowNode.oneMinus() );
24
+
25
+ context.outgoingLight.rgb.assign( diffuseColor.rgb ); // TODO: Optimize LightsNode to avoid this assignment
26
+
27
+ }
28
+
29
+ }
30
+
31
+ export default ShadowMaskModel;
@@ -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 ) {
@@ -63,7 +68,7 @@ class AnalyticLightNode extends LightingNode {
63
68
  }
64
69
 
65
70
  const shadow = this.light.shadow;
66
- const rtt = builder.getRenderTarget( shadow.mapSize.width, shadow.mapSize.height );
71
+ const rtt = builder.createRenderTarget( shadow.mapSize.width, shadow.mapSize.height );
67
72
 
68
73
  const depthTexture = new DepthTexture();
69
74
  depthTexture.minFilter = NearestFilter;
@@ -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
  }
@@ -1,17 +1,15 @@
1
1
  import LightingNode from './LightingNode.js';
2
2
  import { cache } from '../core/CacheNode.js';
3
3
  import { context } from '../core/ContextNode.js';
4
- import { maxMipLevel } from '../utils/MaxMipLevelNode.js';
5
4
  import { roughness, clearcoatRoughness } from '../core/PropertyNode.js';
6
- import { equirectUV } from '../utils/EquirectUVNode.js';
7
- import { specularMIPLevel } from '../utils/SpecularMIPLevelNode.js';
8
5
  import { cameraViewMatrix } from '../accessors/CameraNode.js';
9
6
  import { transformedClearcoatNormalView, transformedNormalView, transformedNormalWorld } from '../accessors/NormalNode.js';
10
7
  import { positionViewDirection } from '../accessors/PositionNode.js';
11
8
  import { addNodeClass } from '../core/Node.js';
12
- import { vec2 } from '../shadernode/ShaderNode.js';
13
- import { cubeTexture } from '../accessors/CubeTextureNode.js';
9
+ import { float } from '../shadernode/ShaderNode.js';
14
10
  import { reference } from '../accessors/ReferenceNode.js';
11
+ import { transformedBentNormalView } from '../accessors/AccessorsUtils.js';
12
+ import { pmremTexture } from '../pmrem/PMREMNode.js';
15
13
 
16
14
  const envNodeCache = new WeakMap();
17
15
 
@@ -29,19 +27,13 @@ class EnvironmentNode extends LightingNode {
29
27
 
30
28
  let envNode = this.envNode;
31
29
 
32
- if ( envNode.isTextureNode && envNode.value.isCubeTexture !== true ) {
30
+ if ( envNode.isTextureNode ) {
33
31
 
34
32
  let cacheEnvNode = envNodeCache.get( envNode.value );
35
33
 
36
34
  if ( cacheEnvNode === undefined ) {
37
35
 
38
- const texture = envNode.value;
39
- const renderer = builder.renderer;
40
-
41
- // @TODO: Add dispose logic here
42
- const cubeRTT = builder.getCubeRenderTarget( 512 ).fromEquirectangularTexture( renderer, texture );
43
-
44
- cacheEnvNode = cubeTexture( cubeRTT.texture );
36
+ cacheEnvNode = pmremTexture( envNode.value );
45
37
 
46
38
  envNodeCache.set( envNode.value, cacheEnvNode );
47
39
 
@@ -53,9 +45,15 @@ class EnvironmentNode extends LightingNode {
53
45
 
54
46
  //
55
47
 
56
- const intensity = reference( 'envMapIntensity', 'float', builder.material ); // @TODO: Add materialEnvIntensity in MaterialNode
48
+ const { material } = builder;
49
+
50
+ const envMap = material.envMap;
51
+ const intensity = envMap ? reference( 'envMapIntensity', 'float', builder.material ) : reference( 'environmentIntensity', 'float', builder.scene ); // @TODO: Add materialEnvIntensity in MaterialNode
57
52
 
58
- 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 );
59
57
  const irradiance = context( envNode, createIrradianceContext( transformedNormalWorld ) ).mul( Math.PI ).mul( intensity );
60
58
 
61
59
  const isolateRadiance = cache( radiance );
@@ -86,51 +84,28 @@ class EnvironmentNode extends LightingNode {
86
84
  const createRadianceContext = ( roughnessNode, normalViewNode ) => {
87
85
 
88
86
  let reflectVec = null;
89
- let textureUVNode = null;
90
87
 
91
88
  return {
92
- getUV: ( textureNode ) => {
93
-
94
- let node = null;
89
+ getUV: () => {
95
90
 
96
91
  if ( reflectVec === null ) {
97
92
 
98
93
  reflectVec = positionViewDirection.negate().reflect( normalViewNode );
99
- reflectVec = roughnessNode.mul( roughnessNode ).mix( reflectVec, normalViewNode ).normalize();
100
- reflectVec = reflectVec.transformDirection( cameraViewMatrix );
101
-
102
- }
103
94
 
104
- if ( textureNode.isCubeTextureNode ) {
105
-
106
- node = reflectVec;
107
-
108
- } else if ( textureNode.isTextureNode ) {
109
-
110
- if ( textureUVNode === null ) {
111
-
112
- // @TODO: Needed PMREM
113
-
114
- textureUVNode = equirectUV( reflectVec );
115
-
116
- }
95
+ // Mixing the reflection with the normal is more accurate and keeps rough objects from gathering light from behind their tangent plane.
96
+ reflectVec = roughnessNode.mul( roughnessNode ).mix( reflectVec, normalViewNode ).normalize();
117
97
 
118
- node = textureUVNode;
98
+ reflectVec = reflectVec.transformDirection( cameraViewMatrix );
119
99
 
120
100
  }
121
101
 
122
- return node;
102
+ return reflectVec;
123
103
 
124
104
  },
125
105
  getTextureLevel: () => {
126
106
 
127
107
  return roughnessNode;
128
108
 
129
- },
130
- getTextureLevelAlgorithm: ( textureNode, levelNode ) => {
131
-
132
- return specularMIPLevel( textureNode, levelNode );
133
-
134
109
  }
135
110
  };
136
111
 
@@ -138,38 +113,15 @@ const createRadianceContext = ( roughnessNode, normalViewNode ) => {
138
113
 
139
114
  const createIrradianceContext = ( normalWorldNode ) => {
140
115
 
141
- let textureUVNode = null;
142
-
143
116
  return {
144
- getUV: ( textureNode ) => {
145
-
146
- let node = null;
147
-
148
- if ( textureNode.isCubeTextureNode ) {
149
-
150
- node = normalWorldNode;
151
-
152
- } else if ( textureNode.isTextureNode ) {
117
+ getUV: () => {
153
118
 
154
- if ( textureUVNode === null ) {
155
-
156
- // @TODO: Needed PMREM
157
-
158
- textureUVNode = equirectUV( normalWorldNode );
159
- textureUVNode = vec2( textureUVNode.x, textureUVNode.y.oneMinus() );
160
-
161
- }
162
-
163
- node = textureUVNode;
164
-
165
- }
166
-
167
- return node;
119
+ return normalWorldNode;
168
120
 
169
121
  },
170
- getTextureLevel: ( textureNode ) => {
122
+ getTextureLevel: () => {
171
123
 
172
- return maxMipLevel( textureNode );
124
+ return float( 1.0 );
173
125
 
174
126
  }
175
127
  };
@@ -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