super-three 0.156.0 → 0.157.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.
- package/build/three.cjs +753 -277
- package/build/three.js +753 -277
- package/build/three.min.js +2 -2
- package/build/three.module.js +750 -276
- package/build/three.module.min.js +1 -1
- package/examples/jsm/capabilities/WebGL.js +17 -0
- package/examples/jsm/controls/DragControls.js +3 -2
- package/examples/jsm/csm/CSMShader.js +25 -21
- package/examples/jsm/exporters/EXRExporter.js +102 -24
- package/examples/jsm/exporters/GLTFExporter.js +1 -1
- package/examples/jsm/libs/rhino3dm/rhino3dm.js +8726 -4
- package/examples/jsm/libs/rhino3dm/rhino3dm.module.js +8737 -4
- package/examples/jsm/libs/rhino3dm/rhino3dm.wasm +0 -0
- package/examples/jsm/lights/LightProbeGenerator.js +37 -3
- package/examples/jsm/lines/LineMaterial.js +90 -156
- package/examples/jsm/loaders/3DMLoader.js +378 -104
- package/examples/jsm/loaders/GLTFLoader.js +1 -1
- package/examples/jsm/loaders/LDrawLoader.js +22 -16
- package/examples/jsm/loaders/RGBELoader.js +1 -1
- package/examples/jsm/loaders/USDZLoader.js +215 -12
- package/examples/jsm/materials/MeshGouraudMaterial.js +22 -18
- package/examples/jsm/nodes/Nodes.js +5 -1
- package/examples/jsm/nodes/accessors/BitangentNode.js +1 -1
- package/examples/jsm/nodes/accessors/BufferAttributeNode.js +2 -2
- package/examples/jsm/nodes/accessors/BufferNode.js +1 -1
- package/examples/jsm/nodes/accessors/CameraNode.js +1 -1
- package/examples/jsm/nodes/accessors/CubeTextureNode.js +2 -2
- package/examples/jsm/nodes/accessors/ExtendedMaterialNode.js +6 -5
- package/examples/jsm/nodes/accessors/InstanceNode.js +2 -2
- package/examples/jsm/nodes/accessors/LineMaterialNode.js +7 -9
- package/examples/jsm/nodes/accessors/MaterialNode.js +34 -46
- package/examples/jsm/nodes/accessors/MaterialReferenceNode.js +9 -9
- package/examples/jsm/nodes/accessors/ModelNode.js +1 -1
- package/examples/jsm/nodes/accessors/ModelViewProjectionNode.js +5 -4
- package/examples/jsm/nodes/accessors/MorphNode.js +4 -4
- package/examples/jsm/nodes/accessors/NormalNode.js +1 -1
- package/examples/jsm/nodes/accessors/Object3DNode.js +1 -1
- package/examples/jsm/nodes/accessors/PointUVNode.js +1 -1
- package/examples/jsm/nodes/accessors/PositionNode.js +1 -1
- package/examples/jsm/nodes/accessors/ReferenceNode.js +13 -7
- package/examples/jsm/nodes/accessors/ReflectVectorNode.js +2 -2
- package/examples/jsm/nodes/accessors/SceneNode.js +2 -2
- package/examples/jsm/nodes/accessors/SkinningNode.js +2 -2
- package/examples/jsm/nodes/accessors/StorageBufferNode.js +1 -1
- package/examples/jsm/nodes/accessors/TangentNode.js +1 -1
- package/examples/jsm/nodes/accessors/TextureBicubicNode.js +2 -2
- package/examples/jsm/nodes/accessors/TextureNode.js +12 -6
- package/examples/jsm/nodes/accessors/TextureSizeNode.js +2 -2
- package/examples/jsm/nodes/accessors/TextureStoreNode.js +1 -1
- package/examples/jsm/nodes/accessors/UVNode.js +1 -1
- package/examples/jsm/nodes/accessors/UserDataNode.js +2 -2
- package/examples/jsm/nodes/code/CodeNode.js +1 -1
- package/examples/jsm/nodes/code/ExpressionNode.js +1 -1
- package/examples/jsm/nodes/code/FunctionCallNode.js +1 -1
- package/examples/jsm/nodes/code/FunctionNode.js +18 -7
- package/examples/jsm/nodes/code/ScriptableNode.js +2 -2
- package/examples/jsm/nodes/code/ScriptableValueNode.js +2 -2
- package/examples/jsm/nodes/core/ArrayUniformNode.js +1 -1
- package/examples/jsm/nodes/core/AttributeNode.js +1 -1
- package/examples/jsm/nodes/core/BypassNode.js +1 -1
- package/examples/jsm/nodes/core/CacheNode.js +1 -1
- package/examples/jsm/nodes/core/ConstNode.js +1 -1
- package/examples/jsm/nodes/core/ContextNode.js +2 -2
- package/examples/jsm/nodes/core/IndexNode.js +1 -1
- package/examples/jsm/nodes/core/InputNode.js +1 -1
- package/examples/jsm/nodes/core/Node.js +28 -13
- package/examples/jsm/nodes/core/NodeBuilder.js +3 -17
- package/examples/jsm/nodes/core/NodeFrame.js +37 -14
- package/examples/jsm/nodes/core/OutputStructNode.js +8 -4
- package/examples/jsm/nodes/core/PropertyNode.js +3 -3
- package/examples/jsm/nodes/core/StackNode.js +1 -1
- package/examples/jsm/nodes/core/StructTypeNode.js +1 -1
- package/examples/jsm/nodes/core/TempNode.js +1 -1
- package/examples/jsm/nodes/core/UniformNode.js +3 -1
- package/examples/jsm/nodes/core/VarNode.js +1 -1
- package/examples/jsm/nodes/core/VaryingNode.js +1 -1
- package/examples/jsm/nodes/core/constants.js +1 -1
- package/examples/jsm/nodes/display/BlendModeNode.js +2 -2
- package/examples/jsm/nodes/display/BumpMapNode.js +2 -2
- package/examples/jsm/nodes/display/ColorAdjustmentNode.js +2 -2
- package/examples/jsm/nodes/display/ColorSpaceNode.js +2 -2
- package/examples/jsm/nodes/display/FrontFacingNode.js +1 -1
- package/examples/jsm/nodes/display/NormalMapNode.js +2 -2
- package/examples/jsm/nodes/display/PosterizeNode.js +2 -2
- package/examples/jsm/nodes/display/ToneMappingNode.js +2 -2
- package/examples/jsm/nodes/display/ViewportDepthNode.js +2 -2
- package/examples/jsm/nodes/display/ViewportDepthTextureNode.js +1 -1
- package/examples/jsm/nodes/display/ViewportNode.js +2 -2
- package/examples/jsm/nodes/display/ViewportSharedTextureNode.js +1 -1
- package/examples/jsm/nodes/display/ViewportTextureNode.js +1 -1
- package/examples/jsm/nodes/fog/FogExp2Node.js +2 -2
- package/examples/jsm/nodes/fog/FogNode.js +2 -2
- package/examples/jsm/nodes/fog/FogRangeNode.js +2 -2
- package/examples/jsm/nodes/geometry/RangeNode.js +2 -2
- package/examples/jsm/nodes/gpgpu/ComputeNode.js +1 -1
- package/examples/jsm/nodes/lighting/AONode.js +2 -2
- package/examples/jsm/nodes/lighting/AmbientLightNode.js +3 -3
- package/examples/jsm/nodes/lighting/AnalyticLightNode.js +4 -4
- package/examples/jsm/nodes/lighting/DirectionalLightNode.js +4 -4
- package/examples/jsm/nodes/lighting/EnvironmentNode.js +2 -2
- package/examples/jsm/nodes/lighting/HemisphereLightNode.js +3 -3
- package/examples/jsm/nodes/lighting/IESSpotLightNode.js +2 -2
- package/examples/jsm/nodes/lighting/LightNode.js +2 -2
- package/examples/jsm/nodes/lighting/LightingContextNode.js +3 -3
- package/examples/jsm/nodes/lighting/LightingNode.js +1 -1
- package/examples/jsm/nodes/lighting/LightsNode.js +4 -4
- package/examples/jsm/nodes/lighting/PointLightNode.js +3 -3
- package/examples/jsm/nodes/lighting/SpotLightNode.js +4 -4
- package/examples/jsm/nodes/materials/Line2NodeMaterial.js +449 -0
- package/examples/jsm/nodes/materials/LineBasicNodeMaterial.js +1 -1
- package/examples/jsm/nodes/materials/LineDashedNodeMaterial.js +2 -2
- package/examples/jsm/nodes/materials/Materials.js +1 -0
- package/examples/jsm/nodes/materials/MeshBasicNodeMaterial.js +1 -1
- package/examples/jsm/nodes/materials/MeshLambertNodeMaterial.js +2 -2
- package/examples/jsm/nodes/materials/MeshNormalNodeMaterial.js +2 -2
- package/examples/jsm/nodes/materials/MeshPhongNodeMaterial.js +3 -3
- package/examples/jsm/nodes/materials/MeshPhysicalNodeMaterial.js +6 -6
- package/examples/jsm/nodes/materials/MeshStandardNodeMaterial.js +3 -3
- package/examples/jsm/nodes/materials/NodeMaterial.js +27 -26
- package/examples/jsm/nodes/materials/PointsNodeMaterial.js +1 -1
- package/examples/jsm/nodes/materials/SpriteNodeMaterial.js +2 -2
- package/examples/jsm/nodes/math/CondNode.js +1 -1
- package/examples/jsm/nodes/math/HashNode.js +8 -9
- package/examples/jsm/nodes/math/MathNode.js +2 -2
- package/examples/jsm/nodes/math/OperatorNode.js +1 -1
- package/examples/jsm/nodes/procedural/CheckerNode.js +3 -3
- package/examples/jsm/nodes/shadernode/ShaderNode.js +81 -28
- package/examples/jsm/nodes/utils/ArrayElementNode.js +1 -1
- package/examples/jsm/nodes/utils/ConvertNode.js +1 -1
- package/examples/jsm/nodes/utils/DiscardNode.js +1 -1
- package/examples/jsm/nodes/utils/EquirectUVNode.js +2 -2
- package/examples/jsm/nodes/utils/JoinNode.js +1 -1
- package/examples/jsm/nodes/utils/LoopNode.js +11 -11
- package/examples/jsm/nodes/utils/MatcapUVNode.js +2 -2
- package/examples/jsm/nodes/utils/MaxMipLevelNode.js +1 -1
- package/examples/jsm/nodes/utils/OscNode.js +2 -2
- package/examples/jsm/nodes/utils/PackingNode.js +2 -2
- package/examples/jsm/nodes/utils/RemapNode.js +2 -2
- package/examples/jsm/nodes/utils/RotateUVNode.js +2 -2
- package/examples/jsm/nodes/utils/SetNode.js +62 -0
- package/examples/jsm/nodes/utils/SpecularMIPLevelNode.js +2 -2
- package/examples/jsm/nodes/utils/SplitNode.js +1 -1
- package/examples/jsm/nodes/utils/SpriteSheetUVNode.js +2 -2
- package/examples/jsm/nodes/utils/TimerNode.js +2 -2
- package/examples/jsm/nodes/utils/TriplanarTexturesNode.js +2 -2
- package/examples/jsm/objects/Sky.js +1 -3
- package/examples/jsm/postprocessing/OutputPass.js +3 -2
- package/examples/jsm/renderers/common/Background.js +2 -2
- package/examples/jsm/renderers/common/Bindings.js +3 -5
- package/examples/jsm/renderers/common/Pipelines.js +7 -7
- package/examples/jsm/renderers/common/RenderContext.js +3 -0
- package/examples/jsm/renderers/common/RenderObject.js +40 -16
- package/examples/jsm/renderers/common/RenderObjects.js +8 -14
- package/examples/jsm/renderers/common/Renderer.js +40 -13
- package/examples/jsm/renderers/common/SampledTexture.js +4 -2
- package/examples/jsm/renderers/common/StorageTexture.js +19 -0
- package/examples/jsm/renderers/common/Textures.js +14 -9
- package/examples/jsm/renderers/common/nodes/NodeBuilderState.js +35 -0
- package/examples/jsm/renderers/common/nodes/NodeSampledTexture.js +20 -10
- package/examples/jsm/renderers/common/nodes/NodeSampler.js +0 -6
- package/examples/jsm/renderers/common/nodes/Nodes.js +51 -24
- package/examples/jsm/renderers/webgl/WebGLBackend.js +100 -5
- package/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js +92 -6
- package/examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js +13 -0
- package/examples/jsm/renderers/webgl-legacy/nodes/WebGLNodeBuilder.js +3 -3
- package/examples/jsm/renderers/webgl-legacy/nodes/WebGLNodes.js +14 -2
- package/examples/jsm/renderers/webgpu/WebGPUBackend.js +5 -5
- package/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js +6 -3
- package/examples/jsm/renderers/webgpu/utils/WebGPUPipelineUtils.js +5 -5
- package/examples/jsm/renderers/webgpu/utils/WebGPUTexturePassUtils.js +285 -0
- package/examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js +197 -167
- package/examples/jsm/shaders/GammaCorrectionShader.js +1 -1
- package/examples/jsm/shaders/MMDToonShader.js +4 -4
- package/examples/jsm/shaders/OutputShader.js +2 -2
- package/examples/jsm/shaders/SubsurfaceScatteringShader.js +6 -6
- package/examples/jsm/utils/BufferGeometryUtils.js +6 -4
- package/package.json +1 -1
- package/src/Three.js +0 -2
- package/src/animation/AnimationUtils.js +3 -20
- package/src/animation/KeyframeTrack.js +8 -8
- package/src/cameras/Camera.js +1 -5
- package/src/cameras/CubeCamera.js +14 -8
- package/src/constants.js +7 -1
- package/src/core/RenderTarget.js +16 -7
- package/src/extras/core/CurvePath.js +4 -1
- package/src/loaders/MaterialLoader.js +1 -1
- package/src/loaders/ObjectLoader.js +6 -0
- package/src/materials/Material.js +8 -8
- package/src/math/Color.js +1 -5
- package/src/math/ColorManagement.js +82 -60
- package/src/objects/Sprite.js +2 -2
- package/src/renderers/WebGLMultiviewRenderTarget.js +35 -0
- package/src/renderers/WebGLRenderer.js +78 -22
- package/src/renderers/shaders/ShaderChunk/aomap_fragment.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/clearcoat_normal_fragment_begin.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/colorspace_pars_fragment.glsl.js +35 -2
- package/src/renderers/shaders/ShaderChunk/common.glsl.js +0 -9
- package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +19 -15
- package/src/renderers/shaders/ShaderChunk/lights_fragment_end.glsl.js +2 -2
- package/src/renderers/shaders/ShaderChunk/lights_fragment_maps.glsl.js +4 -4
- package/src/renderers/shaders/ShaderChunk/lights_lambert_pars_fragment.glsl.js +3 -3
- package/src/renderers/shaders/ShaderChunk/lights_pars_begin.glsl.js +11 -6
- package/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl.js +4 -4
- package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +16 -16
- package/src/renderers/shaders/ShaderChunk/lights_toon_pars_fragment.glsl.js +3 -3
- package/src/renderers/shaders/ShaderChunk/normal_fragment_begin.glsl.js +1 -1
- package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +1 -1
- package/src/renderers/shaders/UniformsUtils.js +2 -2
- package/src/renderers/webgl/WebGLBackground.js +5 -4
- package/src/renderers/webgl/WebGLLights.js +14 -3
- package/src/renderers/webgl/WebGLMultiview.js +100 -0
- package/src/renderers/webgl/WebGLProgram.js +84 -5
- package/src/renderers/webgl/WebGLPrograms.js +11 -2
- package/src/renderers/webgl/WebGLTextures.js +214 -26
- package/src/renderers/webgl/WebGLUtils.js +21 -23
- package/src/renderers/webxr/WebXRManager.js +36 -12
- package/src/scenes/Fog.js +1 -0
- package/src/scenes/FogExp2.js +1 -0
- package/src/textures/Source.js +2 -2
- package/examples/jsm/renderers/webgpu/utils/WebGPUTextureMipmapUtils.js +0 -163
- package/src/lights/AmbientLightProbe.js +0 -21
- package/src/lights/HemisphereLightProbe.js +0 -30
|
@@ -15,10 +15,12 @@ class Textures extends DataMap {
|
|
|
15
15
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
updateRenderTarget( renderTarget ) {
|
|
18
|
+
updateRenderTarget( renderTarget, activeMipmapLevel = 0 ) {
|
|
19
19
|
|
|
20
20
|
const renderTargetData = this.get( renderTarget );
|
|
21
|
+
|
|
21
22
|
const sampleCount = renderTarget.samples === 0 ? 1 : renderTarget.samples;
|
|
23
|
+
const depthTextureMips = renderTargetData.depthTextureMips || ( renderTargetData.depthTextureMips = {} );
|
|
22
24
|
|
|
23
25
|
let texture, textures;
|
|
24
26
|
|
|
@@ -36,7 +38,10 @@ class Textures extends DataMap {
|
|
|
36
38
|
|
|
37
39
|
const size = this.getSize( texture );
|
|
38
40
|
|
|
39
|
-
|
|
41
|
+
const mipWidth = size.width >> activeMipmapLevel;
|
|
42
|
+
const mipHeight = size.height >> activeMipmapLevel;
|
|
43
|
+
|
|
44
|
+
let depthTexture = renderTarget.depthTexture || depthTextureMips[ activeMipmapLevel ];
|
|
40
45
|
let textureNeedsUpdate = false;
|
|
41
46
|
|
|
42
47
|
if ( depthTexture === undefined ) {
|
|
@@ -44,8 +49,10 @@ class Textures extends DataMap {
|
|
|
44
49
|
depthTexture = new DepthTexture();
|
|
45
50
|
depthTexture.format = DepthStencilFormat;
|
|
46
51
|
depthTexture.type = UnsignedInt248Type;
|
|
47
|
-
depthTexture.image.width =
|
|
48
|
-
depthTexture.image.height =
|
|
52
|
+
depthTexture.image.width = mipWidth;
|
|
53
|
+
depthTexture.image.height = mipHeight;
|
|
54
|
+
|
|
55
|
+
depthTextureMips[ activeMipmapLevel ] = depthTexture;
|
|
49
56
|
|
|
50
57
|
}
|
|
51
58
|
|
|
@@ -54,8 +61,8 @@ class Textures extends DataMap {
|
|
|
54
61
|
textureNeedsUpdate = true;
|
|
55
62
|
depthTexture.needsUpdate = true;
|
|
56
63
|
|
|
57
|
-
depthTexture.image.width =
|
|
58
|
-
depthTexture.image.height =
|
|
64
|
+
depthTexture.image.width = mipWidth;
|
|
65
|
+
depthTexture.image.height = mipHeight;
|
|
59
66
|
|
|
60
67
|
}
|
|
61
68
|
|
|
@@ -153,9 +160,7 @@ class Textures extends DataMap {
|
|
|
153
160
|
|
|
154
161
|
//
|
|
155
162
|
|
|
156
|
-
if ( isRenderTarget ||
|
|
157
|
-
|
|
158
|
-
//if ( options.store === true ) options.levels = 1; /* no mipmaps? */
|
|
163
|
+
if ( isRenderTarget || texture.isStorageTexture === true ) {
|
|
159
164
|
|
|
160
165
|
backend.createSampler( texture );
|
|
161
166
|
backend.createTexture( texture, options );
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
class NodeBuilderState {
|
|
2
|
+
|
|
3
|
+
constructor( vertexShader, fragmentShader, computeShader, nodeAttributes, bindings, updateNodes, updateBeforeNodes ) {
|
|
4
|
+
|
|
5
|
+
this.vertexShader = vertexShader;
|
|
6
|
+
this.fragmentShader = fragmentShader;
|
|
7
|
+
this.computeShader = computeShader;
|
|
8
|
+
|
|
9
|
+
this.nodeAttributes = nodeAttributes;
|
|
10
|
+
this.bindings = bindings;
|
|
11
|
+
|
|
12
|
+
this.updateNodes = updateNodes;
|
|
13
|
+
this.updateBeforeNodes = updateBeforeNodes;
|
|
14
|
+
|
|
15
|
+
this.usedTimes = 0;
|
|
16
|
+
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
createBindings() {
|
|
20
|
+
|
|
21
|
+
const bindingsArray = [];
|
|
22
|
+
|
|
23
|
+
for ( const binding of this.bindings ) {
|
|
24
|
+
|
|
25
|
+
bindingsArray.push( binding.clone() );
|
|
26
|
+
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return bindingsArray;
|
|
30
|
+
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export default NodeBuilderState;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SampledTexture
|
|
1
|
+
import { SampledTexture } from '../SampledTexture.js';
|
|
2
2
|
|
|
3
3
|
class NodeSampledTexture extends SampledTexture {
|
|
4
4
|
|
|
@@ -10,27 +10,37 @@ class NodeSampledTexture extends SampledTexture {
|
|
|
10
10
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
get needsBindingsUpdate() {
|
|
14
14
|
|
|
15
|
-
return this.textureNode.value;
|
|
15
|
+
return this.textureNode.value !== this.texture || super.needsBindingsUpdate;
|
|
16
16
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
update() {
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
const { textureNode } = this;
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
if ( this.texture !== textureNode.value ) {
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
this.texture = textureNode.value;
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
return true;
|
|
28
|
+
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return super.update();
|
|
28
32
|
|
|
29
33
|
}
|
|
30
34
|
|
|
31
|
-
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
class NodeSampledCubeTexture extends NodeSampledTexture {
|
|
38
|
+
|
|
39
|
+
constructor( name, textureNode ) {
|
|
40
|
+
|
|
41
|
+
super( name, textureNode );
|
|
32
42
|
|
|
33
|
-
|
|
43
|
+
this.isSampledCubeTexture = true;
|
|
34
44
|
|
|
35
45
|
}
|
|
36
46
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import DataMap from '../DataMap.js';
|
|
2
|
-
import
|
|
2
|
+
import NodeBuilderState from './NodeBuilderState.js';
|
|
3
3
|
import { NoToneMapping, EquirectangularReflectionMapping, EquirectangularRefractionMapping } from 'three';
|
|
4
4
|
import { NodeFrame, cubeTexture, texture, rangeFog, densityFog, reference, toneMapping, equirectUV, viewportBottomLeft, normalWorld } from '../../../nodes/Nodes.js';
|
|
5
5
|
|
|
@@ -12,15 +12,13 @@ class Nodes extends DataMap {
|
|
|
12
12
|
this.renderer = renderer;
|
|
13
13
|
this.backend = backend;
|
|
14
14
|
this.nodeFrame = new NodeFrame();
|
|
15
|
-
this.
|
|
15
|
+
this.nodeBuilderCache = new Map();
|
|
16
16
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
getForRenderCacheKey( renderObject ) {
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
return [ object.geometry, material, lightsNode, context ];
|
|
21
|
+
return renderObject.initialCacheKey;
|
|
24
22
|
|
|
25
23
|
}
|
|
26
24
|
|
|
@@ -28,35 +26,40 @@ class Nodes extends DataMap {
|
|
|
28
26
|
|
|
29
27
|
const renderObjectData = this.get( renderObject );
|
|
30
28
|
|
|
31
|
-
let
|
|
29
|
+
let nodeBuilderState = renderObjectData.nodeBuilderState;
|
|
32
30
|
|
|
33
|
-
if (
|
|
31
|
+
if ( nodeBuilderState === undefined ) {
|
|
34
32
|
|
|
35
|
-
const {
|
|
33
|
+
const { nodeBuilderCache } = this;
|
|
36
34
|
|
|
37
|
-
const
|
|
35
|
+
const cacheKey = this.getForRenderCacheKey( renderObject );
|
|
38
36
|
|
|
39
|
-
|
|
37
|
+
nodeBuilderState = nodeBuilderCache.get( cacheKey );
|
|
40
38
|
|
|
41
|
-
if (
|
|
39
|
+
if ( nodeBuilderState === undefined ) {
|
|
42
40
|
|
|
43
|
-
nodeBuilder = this.backend.createNodeBuilder( renderObject.object, this.renderer, renderObject.scene );
|
|
41
|
+
const nodeBuilder = this.backend.createNodeBuilder( renderObject.object, this.renderer, renderObject.scene );
|
|
44
42
|
nodeBuilder.material = renderObject.material;
|
|
43
|
+
nodeBuilder.context.material = renderObject.material;
|
|
45
44
|
nodeBuilder.lightsNode = renderObject.lightsNode;
|
|
46
45
|
nodeBuilder.environmentNode = this.getEnvironmentNode( renderObject.scene );
|
|
47
46
|
nodeBuilder.fogNode = this.getFogNode( renderObject.scene );
|
|
48
47
|
nodeBuilder.toneMappingNode = this.getToneMappingNode();
|
|
49
48
|
nodeBuilder.build();
|
|
50
49
|
|
|
51
|
-
|
|
50
|
+
nodeBuilderState = this._createNodeBuilderState( nodeBuilder );
|
|
51
|
+
|
|
52
|
+
nodeBuilderCache.set( cacheKey, nodeBuilderState );
|
|
52
53
|
|
|
53
54
|
}
|
|
54
55
|
|
|
55
|
-
|
|
56
|
+
nodeBuilderState.usedTimes ++;
|
|
57
|
+
|
|
58
|
+
renderObjectData.nodeBuilderState = nodeBuilderState;
|
|
56
59
|
|
|
57
60
|
}
|
|
58
61
|
|
|
59
|
-
return
|
|
62
|
+
return nodeBuilderState;
|
|
60
63
|
|
|
61
64
|
}
|
|
62
65
|
|
|
@@ -64,7 +67,14 @@ class Nodes extends DataMap {
|
|
|
64
67
|
|
|
65
68
|
if ( object.isRenderObject ) {
|
|
66
69
|
|
|
67
|
-
|
|
70
|
+
const nodeBuilderState = this.get( object ).nodeBuilderState;
|
|
71
|
+
nodeBuilderState.usedTimes --;
|
|
72
|
+
|
|
73
|
+
if ( nodeBuilderState.usedTimes === 0 ) {
|
|
74
|
+
|
|
75
|
+
this.nodeBuilderCache.delete( this.getForRenderCacheKey( object ) );
|
|
76
|
+
|
|
77
|
+
}
|
|
68
78
|
|
|
69
79
|
}
|
|
70
80
|
|
|
@@ -76,18 +86,34 @@ class Nodes extends DataMap {
|
|
|
76
86
|
|
|
77
87
|
const computeData = this.get( computeNode );
|
|
78
88
|
|
|
79
|
-
let
|
|
89
|
+
let nodeBuilderState = computeData.nodeBuilderState;
|
|
80
90
|
|
|
81
|
-
if (
|
|
91
|
+
if ( nodeBuilderState === undefined ) {
|
|
82
92
|
|
|
83
|
-
nodeBuilder = this.backend.createNodeBuilder( computeNode, this.renderer );
|
|
93
|
+
const nodeBuilder = this.backend.createNodeBuilder( computeNode, this.renderer );
|
|
84
94
|
nodeBuilder.build();
|
|
85
95
|
|
|
86
|
-
|
|
96
|
+
nodeBuilderState = this._createNodeBuilderState( nodeBuilder );
|
|
97
|
+
|
|
98
|
+
computeData.nodeBuilderState = nodeBuilder;
|
|
87
99
|
|
|
88
100
|
}
|
|
89
101
|
|
|
90
|
-
return
|
|
102
|
+
return nodeBuilderState;
|
|
103
|
+
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
_createNodeBuilderState( nodeBuilder ) {
|
|
107
|
+
|
|
108
|
+
return new NodeBuilderState(
|
|
109
|
+
nodeBuilder.vertexShader,
|
|
110
|
+
nodeBuilder.fragmentShader,
|
|
111
|
+
nodeBuilder.computeShader,
|
|
112
|
+
nodeBuilder.getAttributesArray(),
|
|
113
|
+
nodeBuilder.getBindings(),
|
|
114
|
+
nodeBuilder.updateNodes,
|
|
115
|
+
nodeBuilder.updateBeforeNodes
|
|
116
|
+
);
|
|
91
117
|
|
|
92
118
|
}
|
|
93
119
|
|
|
@@ -326,7 +352,7 @@ class Nodes extends DataMap {
|
|
|
326
352
|
updateBefore( renderObject ) {
|
|
327
353
|
|
|
328
354
|
const nodeFrame = this.getNodeFrame( renderObject );
|
|
329
|
-
const nodeBuilder = renderObject.
|
|
355
|
+
const nodeBuilder = renderObject.getNodeBuilderState();
|
|
330
356
|
|
|
331
357
|
for ( const node of nodeBuilder.updateBeforeNodes ) {
|
|
332
358
|
|
|
@@ -341,7 +367,7 @@ class Nodes extends DataMap {
|
|
|
341
367
|
updateForRender( renderObject ) {
|
|
342
368
|
|
|
343
369
|
const nodeFrame = this.getNodeFrame( renderObject );
|
|
344
|
-
const nodeBuilder = renderObject.
|
|
370
|
+
const nodeBuilder = renderObject.getNodeBuilderState();
|
|
345
371
|
|
|
346
372
|
for ( const node of nodeBuilder.updateNodes ) {
|
|
347
373
|
|
|
@@ -356,6 +382,7 @@ class Nodes extends DataMap {
|
|
|
356
382
|
super.dispose();
|
|
357
383
|
|
|
358
384
|
this.nodeFrame = new NodeFrame();
|
|
385
|
+
this.nodeBuilderCache = new Map();
|
|
359
386
|
|
|
360
387
|
}
|
|
361
388
|
|
|
@@ -54,6 +54,8 @@ class WebGLBackend extends Backend {
|
|
|
54
54
|
|
|
55
55
|
//
|
|
56
56
|
|
|
57
|
+
this._setFramebuffer( renderContext );
|
|
58
|
+
|
|
57
59
|
let clear = 0;
|
|
58
60
|
|
|
59
61
|
if ( renderContext.clearColor ) clear |= gl.COLOR_BUFFER_BIT;
|
|
@@ -62,8 +64,26 @@ class WebGLBackend extends Backend {
|
|
|
62
64
|
|
|
63
65
|
const clearColor = renderContext.clearColorValue;
|
|
64
66
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
if ( clear !== 0 ) {
|
|
68
|
+
|
|
69
|
+
if ( renderContext.textures === null ) {
|
|
70
|
+
|
|
71
|
+
gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearColor.a );
|
|
72
|
+
gl.clear( clear );
|
|
73
|
+
|
|
74
|
+
} else {
|
|
75
|
+
|
|
76
|
+
for ( let i = 0; i < renderContext.textures.length; i ++ ) {
|
|
77
|
+
|
|
78
|
+
gl.clearBufferfv( gl.COLOR, i, [ clearColor.r, clearColor.g, clearColor.b, clearColor.a ] );
|
|
79
|
+
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
gl.clearBufferfi( gl.DEPTH_STENCIL, 0, 1, 1 );
|
|
83
|
+
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
}
|
|
67
87
|
|
|
68
88
|
//
|
|
69
89
|
|
|
@@ -282,7 +302,12 @@ class WebGLBackend extends Backend {
|
|
|
282
302
|
textureUtils.setTextureParameters( glTextureType, texture );
|
|
283
303
|
|
|
284
304
|
gl.bindTexture( glTextureType, textureGPU );
|
|
285
|
-
|
|
305
|
+
|
|
306
|
+
if ( ! texture.isVideoTexture ) {
|
|
307
|
+
|
|
308
|
+
gl.texStorage2D( glTextureType, levels, glInternalFormat, width, height );
|
|
309
|
+
|
|
310
|
+
}
|
|
286
311
|
|
|
287
312
|
this.set( texture, {
|
|
288
313
|
textureGPU,
|
|
@@ -298,7 +323,7 @@ class WebGLBackend extends Backend {
|
|
|
298
323
|
|
|
299
324
|
const { gl } = this;
|
|
300
325
|
const { width, height } = options;
|
|
301
|
-
const { textureGPU, glTextureType, glFormat, glType } = this.get( texture );
|
|
326
|
+
const { textureGPU, glTextureType, glFormat, glType, glInternalFormat } = this.get( texture );
|
|
302
327
|
|
|
303
328
|
const getImage = ( source ) => {
|
|
304
329
|
|
|
@@ -306,9 +331,13 @@ class WebGLBackend extends Backend {
|
|
|
306
331
|
|
|
307
332
|
return source.image.data;
|
|
308
333
|
|
|
334
|
+
} else if ( source instanceof ImageBitmap || source instanceof OffscreenCanvas ) {
|
|
335
|
+
|
|
336
|
+
return source;
|
|
337
|
+
|
|
309
338
|
}
|
|
310
339
|
|
|
311
|
-
return source;
|
|
340
|
+
return source.data;
|
|
312
341
|
|
|
313
342
|
};
|
|
314
343
|
|
|
@@ -326,6 +355,13 @@ class WebGLBackend extends Backend {
|
|
|
326
355
|
|
|
327
356
|
}
|
|
328
357
|
|
|
358
|
+
} else if ( texture.isVideoTexture ) {
|
|
359
|
+
|
|
360
|
+
texture.update();
|
|
361
|
+
|
|
362
|
+
gl.texImage2D( glTextureType, 0, glInternalFormat, glFormat, glType, options.image );
|
|
363
|
+
|
|
364
|
+
|
|
329
365
|
} else {
|
|
330
366
|
|
|
331
367
|
const image = getImage( options.image );
|
|
@@ -602,6 +638,65 @@ class WebGLBackend extends Backend {
|
|
|
602
638
|
|
|
603
639
|
}
|
|
604
640
|
|
|
641
|
+
_setFramebuffer( renderContext ) {
|
|
642
|
+
|
|
643
|
+
const { gl } = this;
|
|
644
|
+
|
|
645
|
+
if ( renderContext.textures !== null ) {
|
|
646
|
+
|
|
647
|
+
const renderContextData = this.get( renderContext );
|
|
648
|
+
|
|
649
|
+
let fb = renderContextData.framebuffer;
|
|
650
|
+
|
|
651
|
+
if ( fb === undefined ) {
|
|
652
|
+
|
|
653
|
+
fb = gl.createFramebuffer();
|
|
654
|
+
|
|
655
|
+
gl.bindFramebuffer( gl.FRAMEBUFFER, fb );
|
|
656
|
+
|
|
657
|
+
const textures = renderContext.textures;
|
|
658
|
+
|
|
659
|
+
const drawBuffers = [];
|
|
660
|
+
|
|
661
|
+
for ( let i = 0; i < textures.length; i++ ) {
|
|
662
|
+
|
|
663
|
+
const texture = textures[ i ];
|
|
664
|
+
const { textureGPU } = this.get( texture );
|
|
665
|
+
|
|
666
|
+
const attachment = gl.COLOR_ATTACHMENT0 + i;
|
|
667
|
+
|
|
668
|
+
gl.framebufferTexture2D( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, textureGPU, 0 );
|
|
669
|
+
|
|
670
|
+
drawBuffers.push( attachment );
|
|
671
|
+
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
gl.drawBuffers( drawBuffers );
|
|
675
|
+
|
|
676
|
+
if ( renderContext.depthTexture !== null ) {
|
|
677
|
+
|
|
678
|
+
const { textureGPU } = this.get( renderContext.depthTexture );
|
|
679
|
+
|
|
680
|
+
gl.framebufferTexture2D( gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, textureGPU, 0 );
|
|
681
|
+
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
renderContextData.framebuffer = fb;
|
|
685
|
+
|
|
686
|
+
} else {
|
|
687
|
+
|
|
688
|
+
gl.bindFramebuffer( gl.FRAMEBUFFER, fb );
|
|
689
|
+
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
} else {
|
|
693
|
+
|
|
694
|
+
gl.bindFramebuffer( gl.FRAMEBUFFER, null );
|
|
695
|
+
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
}
|
|
699
|
+
|
|
605
700
|
}
|
|
606
701
|
|
|
607
702
|
export default WebGLBackend;
|
|
@@ -4,7 +4,8 @@ import UniformsGroup from '../../common/UniformsGroup.js';
|
|
|
4
4
|
import { NodeSampledTexture, NodeSampledCubeTexture } from '../../common/nodes/NodeSampledTexture.js';
|
|
5
5
|
|
|
6
6
|
const glslMethods = {
|
|
7
|
-
[ MathNode.ATAN2 ]: 'atan'
|
|
7
|
+
[ MathNode.ATAN2 ]: 'atan',
|
|
8
|
+
textureDimensions: 'textureSize'
|
|
8
9
|
};
|
|
9
10
|
|
|
10
11
|
const precisionLib = {
|
|
@@ -29,12 +30,24 @@ class GLSLNodeBuilder extends NodeBuilder {
|
|
|
29
30
|
|
|
30
31
|
}
|
|
31
32
|
|
|
33
|
+
getPropertyName( node, shaderStage ) {
|
|
34
|
+
|
|
35
|
+
if ( node.isOutputStructVar ) return '';
|
|
36
|
+
|
|
37
|
+
return super.getPropertyName( node, shaderStage );
|
|
38
|
+
|
|
39
|
+
}
|
|
40
|
+
|
|
32
41
|
getTexture( texture, textureProperty, uvSnippet ) {
|
|
33
42
|
|
|
34
43
|
if ( texture.isTextureCube ) {
|
|
35
44
|
|
|
36
45
|
return `textureCube( ${textureProperty}, ${uvSnippet} )`;
|
|
37
46
|
|
|
47
|
+
} else if ( texture.isDepthTexture ) {
|
|
48
|
+
|
|
49
|
+
return `texture( ${textureProperty}, ${uvSnippet} ).x`;
|
|
50
|
+
|
|
38
51
|
} else {
|
|
39
52
|
|
|
40
53
|
return `texture( ${textureProperty}, ${uvSnippet} )`;
|
|
@@ -49,6 +62,20 @@ class GLSLNodeBuilder extends NodeBuilder {
|
|
|
49
62
|
|
|
50
63
|
}
|
|
51
64
|
|
|
65
|
+
getTextureCompare( texture, textureProperty, uvSnippet, compareSnippet, shaderStage = this.shaderStage ) {
|
|
66
|
+
|
|
67
|
+
if ( shaderStage === 'fragment' ) {
|
|
68
|
+
|
|
69
|
+
return `texture( ${textureProperty}, vec3( ${uvSnippet}, ${compareSnippet} ) )`;
|
|
70
|
+
|
|
71
|
+
} else {
|
|
72
|
+
|
|
73
|
+
console.error( `WebGPURenderer: THREE.DepthTexture.compareFunction() does not support ${ shaderStage } shader.` );
|
|
74
|
+
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
}
|
|
78
|
+
|
|
52
79
|
getVars( shaderStage ) {
|
|
53
80
|
|
|
54
81
|
const snippets = [];
|
|
@@ -57,6 +84,8 @@ class GLSLNodeBuilder extends NodeBuilder {
|
|
|
57
84
|
|
|
58
85
|
for ( const variable of vars ) {
|
|
59
86
|
|
|
87
|
+
if ( variable.isOutputStructVar ) continue;
|
|
88
|
+
|
|
60
89
|
snippets.push( `${ this.getVar( variable.type, variable.name ) };` );
|
|
61
90
|
|
|
62
91
|
}
|
|
@@ -79,7 +108,15 @@ class GLSLNodeBuilder extends NodeBuilder {
|
|
|
79
108
|
|
|
80
109
|
if ( uniform.type === 'texture' ) {
|
|
81
110
|
|
|
82
|
-
|
|
111
|
+
if ( uniform.node.value.compareFunction ) {
|
|
112
|
+
|
|
113
|
+
snippet = `sampler2DShadow ${uniform.name};`;
|
|
114
|
+
|
|
115
|
+
} else {
|
|
116
|
+
|
|
117
|
+
snippet = `sampler2D ${uniform.name};`;
|
|
118
|
+
|
|
119
|
+
}
|
|
83
120
|
|
|
84
121
|
} else if ( uniform.type === 'cubeTexture' ) {
|
|
85
122
|
|
|
@@ -155,6 +192,49 @@ class GLSLNodeBuilder extends NodeBuilder {
|
|
|
155
192
|
|
|
156
193
|
}
|
|
157
194
|
|
|
195
|
+
getStructMembers( struct ) {
|
|
196
|
+
|
|
197
|
+
const snippets = [];
|
|
198
|
+
const members = struct.getMemberTypes();
|
|
199
|
+
|
|
200
|
+
for ( let i = 0; i < members.length; i ++ ) {
|
|
201
|
+
|
|
202
|
+
const member = members[ i ];
|
|
203
|
+
snippets.push( `layout( location = ${i} ) out ${ member} m${i};` );
|
|
204
|
+
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return snippets.join( '\n' );
|
|
208
|
+
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
getStructs( shaderStage ) {
|
|
212
|
+
|
|
213
|
+
const snippets = [];
|
|
214
|
+
const structs = this.structs[ shaderStage ];
|
|
215
|
+
|
|
216
|
+
if ( structs.length === 0 ) {
|
|
217
|
+
|
|
218
|
+
return "layout( location = 0 ) out vec4 fragColor;\n";
|
|
219
|
+
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
for ( let index = 0, length = structs.length; index < length; index ++ ) {
|
|
223
|
+
|
|
224
|
+
const struct = structs[ index ];
|
|
225
|
+
|
|
226
|
+
let snippet = `\n`;
|
|
227
|
+
snippet += this.getStructMembers( struct );
|
|
228
|
+
snippet += '\n';
|
|
229
|
+
|
|
230
|
+
snippets.push( snippet );
|
|
231
|
+
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return snippets.join( '\n\n' );
|
|
235
|
+
|
|
236
|
+
}
|
|
237
|
+
|
|
158
238
|
getVaryings( shaderStage ) {
|
|
159
239
|
|
|
160
240
|
let snippet = '';
|
|
@@ -266,6 +346,7 @@ ${ this.getSignature() }
|
|
|
266
346
|
// precision
|
|
267
347
|
precision highp float;
|
|
268
348
|
precision highp int;
|
|
349
|
+
precision lowp sampler2DShadow;
|
|
269
350
|
|
|
270
351
|
// uniforms
|
|
271
352
|
${shaderData.uniforms}
|
|
@@ -276,7 +357,7 @@ ${shaderData.varyings}
|
|
|
276
357
|
// codes
|
|
277
358
|
${shaderData.codes}
|
|
278
359
|
|
|
279
|
-
|
|
360
|
+
${shaderData.structs}
|
|
280
361
|
|
|
281
362
|
void main() {
|
|
282
363
|
|
|
@@ -325,14 +406,18 @@ void main() {
|
|
|
325
406
|
if ( shaderStage === 'vertex' ) {
|
|
326
407
|
|
|
327
408
|
flow += 'gl_Position = ';
|
|
409
|
+
flow += `${ flowSlotData.result };`;
|
|
328
410
|
|
|
329
411
|
} else if ( shaderStage === 'fragment' ) {
|
|
330
412
|
|
|
331
|
-
|
|
413
|
+
if ( ! node.outputNode.isOutputStructNode ) {
|
|
332
414
|
|
|
333
|
-
|
|
415
|
+
flow += 'fragColor = ';
|
|
416
|
+
flow += `${ flowSlotData.result };`;
|
|
417
|
+
|
|
418
|
+
}
|
|
334
419
|
|
|
335
|
-
|
|
420
|
+
}
|
|
336
421
|
|
|
337
422
|
}
|
|
338
423
|
|
|
@@ -344,6 +429,7 @@ void main() {
|
|
|
344
429
|
stageData.attributes = this.getAttributes( shaderStage );
|
|
345
430
|
stageData.varyings = this.getVaryings( shaderStage );
|
|
346
431
|
stageData.vars = this.getVars( shaderStage );
|
|
432
|
+
stageData.structs = this.getStructs( shaderStage );
|
|
347
433
|
stageData.codes = this.getCodes( shaderStage );
|
|
348
434
|
stageData.flow = flow;
|
|
349
435
|
|
|
@@ -140,6 +140,19 @@ class WebGLTextureUtils {
|
|
|
140
140
|
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
+
if ( glFormat === gl.DEPTH_COMPONENT ) {
|
|
144
|
+
|
|
145
|
+
if ( glType === gl.UNSIGNED_INT ) internalFormat = gl.DEPTH_COMPONENT24;
|
|
146
|
+
if ( glType === gl.FLOAT ) internalFormat = gl.DEPTH_COMPONENT32F;
|
|
147
|
+
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if ( glFormat === gl.DEPTH_STENCIL ) {
|
|
151
|
+
|
|
152
|
+
if ( glType === gl.UNSIGNED_INT_24_8 ) internalFormat = gl.DEPTH24_STENCIL8;
|
|
153
|
+
|
|
154
|
+
}
|
|
155
|
+
|
|
143
156
|
if ( internalFormat === gl.R16F || internalFormat === gl.R32F ||
|
|
144
157
|
internalFormat === gl.RG16F || internalFormat === gl.RG32F ||
|
|
145
158
|
internalFormat === gl.RGBA16F || internalFormat === gl.RGBA32F ) {
|
|
@@ -38,9 +38,9 @@ function getShaderStageProperty( shaderStage ) {
|
|
|
38
38
|
|
|
39
39
|
class WebGLNodeBuilder extends NodeBuilder {
|
|
40
40
|
|
|
41
|
-
constructor( object, renderer, shader ) {
|
|
41
|
+
constructor( object, renderer, shader, material = null ) {
|
|
42
42
|
|
|
43
|
-
super( object, renderer, new GLSLNodeParser() );
|
|
43
|
+
super( object, renderer, new GLSLNodeParser(), null, material );
|
|
44
44
|
|
|
45
45
|
this.shader = shader;
|
|
46
46
|
this.slots = { vertex: [], fragment: [] };
|
|
@@ -220,7 +220,7 @@ class WebGLNodeBuilder extends NodeBuilder {
|
|
|
220
220
|
this.addSlot( 'fragment', new SlotNode( {
|
|
221
221
|
node: material.clearcoatNormalNode,
|
|
222
222
|
nodeType: 'vec3',
|
|
223
|
-
source: 'vec3 clearcoatNormal =
|
|
223
|
+
source: 'vec3 clearcoatNormal = nonPerturbedNormal;',
|
|
224
224
|
target: 'vec3 clearcoatNormal = %RESULT%;'
|
|
225
225
|
} ) );
|
|
226
226
|
|