super-three 0.154.0 → 0.155.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.
- package/build/three.cjs +257 -40
- package/build/three.js +257 -40
- package/build/three.min.js +1 -2
- package/build/three.module.js +256 -41
- package/build/three.module.min.js +1 -2
- package/examples/jsm/controls/OrbitControls.js +143 -21
- package/examples/jsm/environments/RoomEnvironment.js +1 -1
- package/examples/jsm/exporters/USDZExporter.js +1 -0
- package/examples/jsm/interactive/SelectionHelper.js +7 -0
- package/examples/jsm/loaders/FBXLoader.js +1 -1
- package/examples/jsm/loaders/GLTFLoader.js +8 -3
- package/examples/jsm/loaders/KTX2Loader.js +4 -4
- package/examples/jsm/loaders/LDrawLoader.js +1 -1
- package/examples/jsm/loaders/NRRDLoader.js +3 -3
- package/examples/jsm/loaders/PLYLoader.js +1 -1
- package/examples/jsm/loaders/TGALoader.js +10 -10
- package/examples/jsm/loaders/VRMLLoader.js +1 -1
- package/examples/jsm/misc/GPUComputationRenderer.js +0 -9
- package/examples/jsm/misc/Volume.js +4 -6
- package/examples/jsm/nodes/Nodes.js +5 -6
- package/examples/jsm/nodes/accessors/BufferAttributeNode.js +1 -1
- package/examples/jsm/nodes/accessors/CubeTextureNode.js +2 -0
- package/examples/jsm/nodes/accessors/ExtendedMaterialNode.js +14 -1
- package/examples/jsm/nodes/accessors/InstanceNode.js +8 -8
- package/examples/jsm/nodes/accessors/MaterialNode.js +34 -44
- package/examples/jsm/nodes/accessors/SceneNode.js +6 -0
- package/examples/jsm/nodes/accessors/TextureNode.js +48 -7
- package/examples/jsm/nodes/core/LightingModel.js +7 -9
- package/examples/jsm/nodes/core/Node.js +11 -2
- package/examples/jsm/nodes/core/PropertyNode.js +4 -0
- package/examples/jsm/nodes/display/BumpMapNode.js +77 -0
- package/examples/jsm/nodes/display/NormalMapNode.js +2 -2
- package/examples/jsm/nodes/functions/BSDF/BRDF_GGX.js +10 -2
- package/examples/jsm/nodes/functions/BSDF/Schlick_to_F0.js +13 -0
- package/examples/jsm/nodes/functions/PhongLightingModel.js +53 -14
- package/examples/jsm/nodes/functions/PhysicalLightingModel.js +236 -97
- package/examples/jsm/nodes/geometry/RangeNode.js +2 -2
- package/examples/jsm/nodes/gpgpu/ComputeNode.js +13 -0
- package/examples/jsm/nodes/lighting/AONode.js +1 -1
- package/examples/jsm/nodes/lighting/AnalyticLightNode.js +58 -20
- package/examples/jsm/nodes/lighting/DirectionalLightNode.js +7 -10
- package/examples/jsm/nodes/lighting/EnvironmentNode.js +22 -12
- package/examples/jsm/nodes/lighting/HemisphereLightNode.js +1 -1
- package/examples/jsm/nodes/lighting/LightingContextNode.js +12 -9
- package/examples/jsm/nodes/lighting/PointLightNode.js +7 -10
- package/examples/jsm/nodes/lighting/SpotLightNode.js +7 -10
- package/examples/jsm/nodes/materials/Materials.js +1 -0
- package/examples/jsm/nodes/materials/MeshLambertNodeMaterial.js +34 -0
- package/examples/jsm/nodes/materials/MeshNormalNodeMaterial.js +2 -0
- package/examples/jsm/nodes/materials/MeshPhongNodeMaterial.js +2 -2
- package/examples/jsm/nodes/materials/MeshPhysicalNodeMaterial.js +19 -2
- package/examples/jsm/nodes/materials/MeshStandardNodeMaterial.js +2 -2
- package/examples/jsm/nodes/materials/NodeMaterial.js +50 -24
- package/examples/jsm/nodes/materials/SpriteNodeMaterial.js +2 -2
- package/examples/jsm/nodes/shadernode/ShaderNode.js +2 -2
- package/examples/jsm/objects/Reflector.js +1 -9
- package/examples/jsm/objects/Refractor.js +0 -8
- package/examples/jsm/offscreen/scene.js +0 -1
- package/examples/jsm/postprocessing/MaskPass.js +4 -1
- package/examples/jsm/postprocessing/OutputPass.js +33 -14
- package/examples/jsm/postprocessing/UnrealBloomPass.js +21 -17
- package/examples/jsm/renderers/common/Background.js +22 -20
- package/examples/jsm/renderers/common/Binding.js +8 -0
- package/examples/jsm/renderers/common/Bindings.js +2 -6
- package/examples/jsm/renderers/common/Geometries.js +1 -1
- package/examples/jsm/renderers/common/Pipelines.js +94 -45
- package/examples/jsm/renderers/common/RenderContext.js +1 -0
- package/examples/jsm/renderers/common/RenderContexts.js +16 -5
- package/examples/jsm/renderers/common/RenderObject.js +20 -4
- package/examples/jsm/renderers/common/RenderObjects.js +10 -7
- package/examples/jsm/renderers/common/Renderer.js +70 -39
- package/examples/jsm/renderers/common/Textures.js +20 -8
- package/examples/jsm/renderers/common/nodes/Nodes.js +15 -4
- package/examples/jsm/renderers/webgpu/WebGPUBackend.js +51 -54
- package/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js +33 -9
- package/examples/jsm/renderers/webgpu/utils/WebGPUAttributeUtils.js +55 -36
- package/examples/jsm/renderers/webgpu/utils/WebGPUBindingUtils.js +83 -5
- package/examples/jsm/renderers/webgpu/utils/WebGPUConstants.js +24 -22
- package/examples/jsm/renderers/webgpu/utils/WebGPUPipelineUtils.js +83 -130
- package/examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js +35 -8
- package/examples/jsm/renderers/webgpu/utils/WebGPUUtils.js +1 -1
- package/examples/jsm/shaders/OutputShader.js +19 -2
- package/examples/jsm/utils/BufferGeometryUtils.js +13 -4
- package/examples/jsm/webxr/OculusHandPointerModel.js +2 -2
- package/package.json +2 -2
- package/src/Three.js +2 -0
- package/src/animation/PropertyBinding.js +1 -1
- package/src/cameras/CubeCamera.js +1 -4
- package/src/constants.js +1 -1
- package/src/core/BufferAttribute.js +20 -0
- package/src/core/Object3D.js +1 -1
- package/src/core/RenderTarget.js +122 -0
- package/src/geometries/CapsuleGeometry.js +1 -1
- package/src/loaders/DataTextureLoader.js +21 -2
- package/src/renderers/WebGLMultipleRenderTargets.js +0 -2
- package/src/renderers/WebGLRenderTarget.js +3 -110
- package/src/renderers/WebGLRenderer.js +62 -8
- package/src/renderers/shaders/ShaderChunk/iridescence_fragment.glsl.js +1 -2
- package/src/renderers/webgl/WebGLGeometries.js +5 -1
- package/src/renderers/webgl/WebGLMaterials.js +1 -1
- package/src/renderers/webgl/WebGLPrograms.js +14 -2
- package/src/renderers/webgl/WebGLTextures.js +97 -12
- package/src/renderers/webxr/WebXRManager.js +1 -1
- package/src/textures/CompressedCubeTexture.js +19 -0
- package/examples/jsm/nodes/functions/BSDF/BRDF_BlinnPhong.js +0 -30
- package/examples/jsm/renderers/common/RenderTarget.js +0 -15
- package/examples/jsm/renderers/common/nodes/NodeRender.js +0 -302
|
@@ -4,6 +4,7 @@ import MaterialNode from './MaterialNode.js';
|
|
|
4
4
|
import { materialReference } from './MaterialReferenceNode.js';
|
|
5
5
|
import { normalView } from './NormalNode.js';
|
|
6
6
|
import { normalMap } from '../display/NormalMapNode.js';
|
|
7
|
+
import { bumpMap } from '../display/BumpMapNode.js';
|
|
7
8
|
import { addNodeClass } from '../core/Node.js';
|
|
8
9
|
import { nodeImmutable } from '../shadernode/ShaderNode.js';
|
|
9
10
|
|
|
@@ -39,7 +40,19 @@ class ExtendedMaterialNode extends MaterialNode {
|
|
|
39
40
|
|
|
40
41
|
if ( scope === ExtendedMaterialNode.NORMAL ) {
|
|
41
42
|
|
|
42
|
-
|
|
43
|
+
if ( material.normalMap ) {
|
|
44
|
+
|
|
45
|
+
node = normalMap( this.getTexture( 'normalMap' ), materialReference( 'normalScale', 'vec2' ) );
|
|
46
|
+
|
|
47
|
+
} else if ( material.bumpMap ) {
|
|
48
|
+
|
|
49
|
+
node = bumpMap( material.bumpMap, materialReference( 'bumpScale', 'float' ) );
|
|
50
|
+
|
|
51
|
+
} else {
|
|
52
|
+
|
|
53
|
+
node = normalView;
|
|
54
|
+
|
|
55
|
+
}
|
|
43
56
|
|
|
44
57
|
} else if ( scope === ExtendedMaterialNode.CLEARCOAT_NORMAL ) {
|
|
45
58
|
|
|
@@ -3,7 +3,7 @@ import { instancedBufferAttribute, instancedDynamicBufferAttribute } from './Buf
|
|
|
3
3
|
import { normalLocal } from './NormalNode.js';
|
|
4
4
|
import { positionLocal } from './PositionNode.js';
|
|
5
5
|
import { nodeProxy, vec3, mat3, mat4 } from '../shadernode/ShaderNode.js';
|
|
6
|
-
import { DynamicDrawUsage } from 'three';
|
|
6
|
+
import { DynamicDrawUsage, InstancedInterleavedBuffer } from 'three';
|
|
7
7
|
|
|
8
8
|
class InstanceNode extends Node {
|
|
9
9
|
|
|
@@ -24,17 +24,17 @@ class InstanceNode extends Node {
|
|
|
24
24
|
if ( instanceMatrixNode === null ) {
|
|
25
25
|
|
|
26
26
|
const instanceMesh = this.instanceMesh;
|
|
27
|
-
const
|
|
28
|
-
const
|
|
27
|
+
const instanceAttribute = instanceMesh.instanceMatrix;
|
|
28
|
+
const buffer = new InstancedInterleavedBuffer( instanceAttribute.array, 16, 1 );
|
|
29
29
|
|
|
30
|
-
const bufferFn =
|
|
30
|
+
const bufferFn = instanceAttribute.usage === DynamicDrawUsage ? instancedDynamicBufferAttribute : instancedBufferAttribute;
|
|
31
31
|
|
|
32
32
|
const instanceBuffers = [
|
|
33
33
|
// F.Signature -> bufferAttribute( array, type, stride, offset )
|
|
34
|
-
bufferFn(
|
|
35
|
-
bufferFn(
|
|
36
|
-
bufferFn(
|
|
37
|
-
bufferFn(
|
|
34
|
+
bufferFn( buffer, 'vec4', 16, 0 ),
|
|
35
|
+
bufferFn( buffer, 'vec4', 16, 4 ),
|
|
36
|
+
bufferFn( buffer, 'vec4', 16, 8 ),
|
|
37
|
+
bufferFn( buffer, 'vec4', 16, 12 )
|
|
38
38
|
];
|
|
39
39
|
|
|
40
40
|
instanceMatrixNode = mat4( ...instanceBuffers );
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import Node, { addNodeClass } from '../core/Node.js';
|
|
2
|
+
import { reference } from './ReferenceNode.js';
|
|
2
3
|
import { materialReference } from './MaterialReferenceNode.js';
|
|
3
|
-
import { nodeImmutable } from '../shadernode/ShaderNode.js';
|
|
4
|
+
import { nodeImmutable, float } from '../shadernode/ShaderNode.js';
|
|
4
5
|
|
|
5
6
|
class MaterialNode extends Node {
|
|
6
7
|
|
|
@@ -12,31 +13,6 @@ class MaterialNode extends Node {
|
|
|
12
13
|
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
getNodeType( builder ) {
|
|
16
|
-
|
|
17
|
-
const scope = this.scope;
|
|
18
|
-
const material = builder.context.material;
|
|
19
|
-
|
|
20
|
-
if ( scope === MaterialNode.COLOR ) {
|
|
21
|
-
|
|
22
|
-
return material.map !== null ? 'vec4' : 'vec3';
|
|
23
|
-
|
|
24
|
-
} else if ( scope === MaterialNode.OPACITY || scope === MaterialNode.ROTATION ) {
|
|
25
|
-
|
|
26
|
-
return 'float';
|
|
27
|
-
|
|
28
|
-
} else if ( scope === MaterialNode.EMISSIVE || scope === MaterialNode.SHEEN ) {
|
|
29
|
-
|
|
30
|
-
return 'vec3';
|
|
31
|
-
|
|
32
|
-
} else if ( scope === MaterialNode.ROUGHNESS || scope === MaterialNode.METALNESS || scope === MaterialNode.SPECULAR || scope === MaterialNode.SHININESS || scope === MaterialNode.CLEARCOAT_ROUGHNESS || scope === MaterialNode.SHEEN_ROUGHNESS ) {
|
|
33
|
-
|
|
34
|
-
return 'float';
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
|
|
40
16
|
getFloat( property ) {
|
|
41
17
|
|
|
42
18
|
//@TODO: Check if it can be cached by property name.
|
|
@@ -70,9 +46,13 @@ class MaterialNode extends Node {
|
|
|
70
46
|
|
|
71
47
|
let node = null;
|
|
72
48
|
|
|
73
|
-
if ( scope === MaterialNode.ALPHA_TEST ) {
|
|
49
|
+
if ( scope === MaterialNode.ALPHA_TEST || scope === MaterialNode.SHININESS || scope === MaterialNode.REFLECTIVITY || scope === MaterialNode.ROTATION || scope === MaterialNode.IRIDESCENCE || scope === MaterialNode.IRIDESCENCE_IOR ) {
|
|
74
50
|
|
|
75
|
-
node = this.getFloat(
|
|
51
|
+
node = this.getFloat( scope );
|
|
52
|
+
|
|
53
|
+
} else if ( scope === MaterialNode.SPECULAR_COLOR ) {
|
|
54
|
+
|
|
55
|
+
node = this.getColor( 'specular' );
|
|
76
56
|
|
|
77
57
|
} else if ( scope === MaterialNode.COLOR ) {
|
|
78
58
|
|
|
@@ -102,25 +82,15 @@ class MaterialNode extends Node {
|
|
|
102
82
|
|
|
103
83
|
}
|
|
104
84
|
|
|
105
|
-
} else if ( scope === MaterialNode.
|
|
106
|
-
|
|
107
|
-
node = this.getFloat( 'shininess' );
|
|
108
|
-
|
|
109
|
-
} else if ( scope === MaterialNode.SPECULAR_COLOR ) {
|
|
110
|
-
|
|
111
|
-
node = this.getColor( 'specular' );
|
|
112
|
-
|
|
113
|
-
} else if ( scope === MaterialNode.REFLECTIVITY ) {
|
|
114
|
-
|
|
115
|
-
const reflectivityNode = this.getFloat( 'reflectivity' );
|
|
85
|
+
} else if ( scope === MaterialNode.SPECULAR_STRENGTH ) {
|
|
116
86
|
|
|
117
87
|
if ( material.specularMap && material.specularMap.isTexture === true ) {
|
|
118
88
|
|
|
119
|
-
node =
|
|
89
|
+
node = this.getTexture( 'specularMap' ).r;
|
|
120
90
|
|
|
121
91
|
} else {
|
|
122
92
|
|
|
123
|
-
node =
|
|
93
|
+
node = float( 1 );
|
|
124
94
|
|
|
125
95
|
}
|
|
126
96
|
|
|
@@ -224,9 +194,21 @@ class MaterialNode extends Node {
|
|
|
224
194
|
|
|
225
195
|
node = node.clamp( 0.07, 1.0 );
|
|
226
196
|
|
|
227
|
-
} else if ( scope === MaterialNode.
|
|
197
|
+
} else if ( scope === MaterialNode.IRIDESCENCE_THICKNESS ) {
|
|
228
198
|
|
|
229
|
-
|
|
199
|
+
const iridescenceThicknessMaximum = reference( 1, 'float', material.iridescenceThicknessRange );
|
|
200
|
+
|
|
201
|
+
if ( material.iridescenceThicknessMap ) {
|
|
202
|
+
|
|
203
|
+
const iridescenceThicknessMinimum = reference( 0, 'float', material.iridescenceThicknessRange );
|
|
204
|
+
|
|
205
|
+
node = iridescenceThicknessMaximum.sub( iridescenceThicknessMinimum ).mul( this.getTexture( 'iridescenceThicknessMap' ).g ).add( iridescenceThicknessMinimum );
|
|
206
|
+
|
|
207
|
+
} else {
|
|
208
|
+
|
|
209
|
+
node = iridescenceThicknessMaximum;
|
|
210
|
+
|
|
211
|
+
}
|
|
230
212
|
|
|
231
213
|
} else {
|
|
232
214
|
|
|
@@ -246,7 +228,8 @@ MaterialNode.ALPHA_TEST = 'alphaTest';
|
|
|
246
228
|
MaterialNode.COLOR = 'color';
|
|
247
229
|
MaterialNode.OPACITY = 'opacity';
|
|
248
230
|
MaterialNode.SHININESS = 'shininess';
|
|
249
|
-
MaterialNode.
|
|
231
|
+
MaterialNode.SPECULAR = 'specular';
|
|
232
|
+
MaterialNode.SPECULAR_STRENGTH = 'specularStrength';
|
|
250
233
|
MaterialNode.REFLECTIVITY = 'reflectivity';
|
|
251
234
|
MaterialNode.ROUGHNESS = 'roughness';
|
|
252
235
|
MaterialNode.METALNESS = 'metalness';
|
|
@@ -256,6 +239,9 @@ MaterialNode.EMISSIVE = 'emissive';
|
|
|
256
239
|
MaterialNode.ROTATION = 'rotation';
|
|
257
240
|
MaterialNode.SHEEN = 'sheen';
|
|
258
241
|
MaterialNode.SHEEN_ROUGHNESS = 'sheenRoughness';
|
|
242
|
+
MaterialNode.IRIDESCENCE = 'iridescence';
|
|
243
|
+
MaterialNode.IRIDESCENCE_IOR = 'iridescenceIOR';
|
|
244
|
+
MaterialNode.IRIDESCENCE_THICKNESS = 'iridescenceThickness';
|
|
259
245
|
|
|
260
246
|
export default MaterialNode;
|
|
261
247
|
|
|
@@ -265,6 +251,7 @@ export const materialShininess = nodeImmutable( MaterialNode, MaterialNode.SHINI
|
|
|
265
251
|
export const materialEmissive = nodeImmutable( MaterialNode, MaterialNode.EMISSIVE );
|
|
266
252
|
export const materialOpacity = nodeImmutable( MaterialNode, MaterialNode.OPACITY );
|
|
267
253
|
export const materialSpecularColor = nodeImmutable( MaterialNode, MaterialNode.SPECULAR_COLOR );
|
|
254
|
+
export const materialSpecularStrength = nodeImmutable( MaterialNode, MaterialNode.SPECULAR_STRENGTH );
|
|
268
255
|
export const materialReflectivity = nodeImmutable( MaterialNode, MaterialNode.REFLECTIVITY );
|
|
269
256
|
export const materialRoughness = nodeImmutable( MaterialNode, MaterialNode.ROUGHNESS );
|
|
270
257
|
export const materialMetalness = nodeImmutable( MaterialNode, MaterialNode.METALNESS );
|
|
@@ -273,5 +260,8 @@ export const materialClearcoatRoughness = nodeImmutable( MaterialNode, MaterialN
|
|
|
273
260
|
export const materialRotation = nodeImmutable( MaterialNode, MaterialNode.ROTATION );
|
|
274
261
|
export const materialSheen = nodeImmutable( MaterialNode, MaterialNode.SHEEN );
|
|
275
262
|
export const materialSheenRoughness = nodeImmutable( MaterialNode, MaterialNode.SHEEN_ROUGHNESS );
|
|
263
|
+
export const materialIridescence = nodeImmutable( MaterialNode, MaterialNode.IRIDESCENCE );
|
|
264
|
+
export const materialIridescenceIOR = nodeImmutable( MaterialNode, MaterialNode.IRIDESCENCE_IOR );
|
|
265
|
+
export const materialIridescenceThickness = nodeImmutable( MaterialNode, MaterialNode.IRIDESCENCE_THICKNESS );
|
|
276
266
|
|
|
277
267
|
addNodeClass( MaterialNode );
|
|
@@ -25,6 +25,10 @@ class SceneNode extends Node {
|
|
|
25
25
|
|
|
26
26
|
output = reference( 'backgroundBlurriness', 'float', scene );
|
|
27
27
|
|
|
28
|
+
} else if ( scope === SceneNode.BACKGROUND_INTENSITY ) {
|
|
29
|
+
|
|
30
|
+
output = reference( 'backgroundIntensity', 'float', scene );
|
|
31
|
+
|
|
28
32
|
} else {
|
|
29
33
|
|
|
30
34
|
console.error( 'THREE.SceneNode: Unknown scope:', scope );
|
|
@@ -38,9 +42,11 @@ class SceneNode extends Node {
|
|
|
38
42
|
}
|
|
39
43
|
|
|
40
44
|
SceneNode.BACKGROUND_BLURRINESS = 'backgroundBlurriness';
|
|
45
|
+
SceneNode.BACKGROUND_INTENSITY = 'backgroundIntensity';
|
|
41
46
|
|
|
42
47
|
export default SceneNode;
|
|
43
48
|
|
|
44
49
|
export const backgroundBlurriness = nodeImmutable( SceneNode, SceneNode.BACKGROUND_BLURRINESS );
|
|
50
|
+
export const backgroundIntensity = nodeImmutable( SceneNode, SceneNode.BACKGROUND_INTENSITY );
|
|
45
51
|
|
|
46
52
|
addNodeClass( SceneNode );
|
|
@@ -5,12 +5,12 @@ import { colorSpaceToLinear } from '../display/ColorSpaceNode.js';
|
|
|
5
5
|
import { context } from '../core/ContextNode.js';
|
|
6
6
|
import { expression } from '../code/ExpressionNode.js';
|
|
7
7
|
import { addNodeClass } from '../core/Node.js';
|
|
8
|
-
import { addNodeElement, nodeProxy, vec3 } from '../shadernode/ShaderNode.js';
|
|
8
|
+
import { addNodeElement, nodeProxy, vec3, nodeObject } from '../shadernode/ShaderNode.js';
|
|
9
9
|
import { NodeUpdateType } from '../core/constants.js';
|
|
10
10
|
|
|
11
11
|
class TextureNode extends UniformNode {
|
|
12
12
|
|
|
13
|
-
constructor( value, uvNode = null, levelNode = null ) {
|
|
13
|
+
constructor( value, uvNode = null, levelNode = null, compareNode = null ) {
|
|
14
14
|
|
|
15
15
|
super( value );
|
|
16
16
|
|
|
@@ -18,8 +18,12 @@ class TextureNode extends UniformNode {
|
|
|
18
18
|
|
|
19
19
|
this.uvNode = uvNode;
|
|
20
20
|
this.levelNode = levelNode;
|
|
21
|
+
this.compareNode = compareNode;
|
|
21
22
|
|
|
22
|
-
this.
|
|
23
|
+
this.updateMatrix = false;
|
|
24
|
+
this.updateType = NodeUpdateType.NONE;
|
|
25
|
+
|
|
26
|
+
this.setUpdateMatrix( uvNode === null );
|
|
23
27
|
|
|
24
28
|
}
|
|
25
29
|
|
|
@@ -45,9 +49,24 @@ class TextureNode extends UniformNode {
|
|
|
45
49
|
|
|
46
50
|
getDefaultUV() {
|
|
47
51
|
|
|
52
|
+
return uv( this.value.channel );
|
|
53
|
+
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
getTextureMatrix( uvNode ) {
|
|
57
|
+
|
|
48
58
|
const texture = this.value;
|
|
49
59
|
|
|
50
|
-
return uniform( texture.matrix ).mul( vec3(
|
|
60
|
+
return uniform( texture.matrix ).mul( vec3( uvNode, 1 ) ).xy;
|
|
61
|
+
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
setUpdateMatrix( value ) {
|
|
65
|
+
|
|
66
|
+
this.updateMatrix = value;
|
|
67
|
+
this.updateType = value ? NodeUpdateType.FRAME : NodeUpdateType.NONE;
|
|
68
|
+
|
|
69
|
+
return this;
|
|
51
70
|
|
|
52
71
|
}
|
|
53
72
|
|
|
@@ -65,7 +84,13 @@ class TextureNode extends UniformNode {
|
|
|
65
84
|
|
|
66
85
|
}
|
|
67
86
|
|
|
68
|
-
|
|
87
|
+
if ( ! uvNode ) uvNode = this.getDefaultUV();
|
|
88
|
+
|
|
89
|
+
if ( this.updateMatrix ) {
|
|
90
|
+
|
|
91
|
+
uvNode = this.getTextureMatrix( uvNode );
|
|
92
|
+
|
|
93
|
+
}
|
|
69
94
|
|
|
70
95
|
//
|
|
71
96
|
|
|
@@ -88,6 +113,7 @@ class TextureNode extends UniformNode {
|
|
|
88
113
|
|
|
89
114
|
const { uvNode, levelNode } = builder.getNodeProperties( this );
|
|
90
115
|
|
|
116
|
+
const compareNode = this.compareNode;
|
|
91
117
|
const texture = this.value;
|
|
92
118
|
|
|
93
119
|
if ( ! texture || texture.isTexture !== true ) {
|
|
@@ -128,6 +154,12 @@ class TextureNode extends UniformNode {
|
|
|
128
154
|
|
|
129
155
|
snippet = builder.getTextureLevel( texture, textureProperty, uvSnippet, levelSnippet );
|
|
130
156
|
|
|
157
|
+
} else if ( compareNode !== null ) {
|
|
158
|
+
|
|
159
|
+
const compareSnippet = compareNode.build( builder, 'float' );
|
|
160
|
+
|
|
161
|
+
snippet = builder.getTextureCompare( texture, textureProperty, uvSnippet, compareSnippet );
|
|
162
|
+
|
|
131
163
|
} else {
|
|
132
164
|
|
|
133
165
|
snippet = builder.getTexture( texture, textureProperty, uvSnippet );
|
|
@@ -160,7 +192,7 @@ class TextureNode extends UniformNode {
|
|
|
160
192
|
const textureNode = this.clone();
|
|
161
193
|
textureNode.uvNode = uvNode;
|
|
162
194
|
|
|
163
|
-
return textureNode;
|
|
195
|
+
return nodeObject( textureNode );
|
|
164
196
|
|
|
165
197
|
}
|
|
166
198
|
|
|
@@ -181,6 +213,15 @@ class TextureNode extends UniformNode {
|
|
|
181
213
|
|
|
182
214
|
}
|
|
183
215
|
|
|
216
|
+
compare( compareNode ) {
|
|
217
|
+
|
|
218
|
+
const textureNode = this.clone();
|
|
219
|
+
textureNode.compareNode = nodeObject( compareNode );
|
|
220
|
+
|
|
221
|
+
return nodeObject( textureNode );
|
|
222
|
+
|
|
223
|
+
}
|
|
224
|
+
|
|
184
225
|
serialize( data ) {
|
|
185
226
|
|
|
186
227
|
super.serialize( data );
|
|
@@ -211,7 +252,7 @@ class TextureNode extends UniformNode {
|
|
|
211
252
|
|
|
212
253
|
clone() {
|
|
213
254
|
|
|
214
|
-
return new this.constructor( this.value, this.uvNode, this.levelNode );
|
|
255
|
+
return new this.constructor( this.value, this.uvNode, this.levelNode, this.compareNode );
|
|
215
256
|
|
|
216
257
|
}
|
|
217
258
|
|
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
class LightingModel {
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
init( /*input, stack, builder*/ ) { }
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
this.direct = direct;
|
|
7
|
-
this.indirectDiffuse = indirectDiffuse;
|
|
8
|
-
this.indirectSpecular = indirectSpecular;
|
|
9
|
-
this.ambientOcclusion = ambientOcclusion;
|
|
5
|
+
direct( /*input, stack, builder*/ ) { }
|
|
10
6
|
|
|
11
|
-
}
|
|
7
|
+
indirectDiffuse( /*input, stack, builder*/ ) { }
|
|
8
|
+
|
|
9
|
+
indirectSpecular( /*input, stack, builder*/ ) { }
|
|
10
|
+
|
|
11
|
+
ambientOcclusion( /*input, stack, builder*/ ) { }
|
|
12
12
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export default LightingModel;
|
|
16
|
-
|
|
17
|
-
export const lightingModel = ( ...params ) => new LightingModel( ...params );
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { EventDispatcher } from 'three';
|
|
1
2
|
import { NodeUpdateType } from './constants.js';
|
|
2
3
|
import { getNodeChildren, getCacheKey } from './NodeUtils.js';
|
|
3
4
|
import { MathUtils } from 'three';
|
|
@@ -6,11 +7,11 @@ const NodeClasses = new Map();
|
|
|
6
7
|
|
|
7
8
|
let _nodeId = 0;
|
|
8
9
|
|
|
9
|
-
class Node {
|
|
10
|
+
class Node extends EventDispatcher {
|
|
10
11
|
|
|
11
12
|
constructor( nodeType = null ) {
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
super();
|
|
14
15
|
|
|
15
16
|
this.nodeType = nodeType;
|
|
16
17
|
|
|
@@ -19,6 +20,8 @@ class Node {
|
|
|
19
20
|
|
|
20
21
|
this.uuid = MathUtils.generateUUID();
|
|
21
22
|
|
|
23
|
+
this.isNode = true;
|
|
24
|
+
|
|
22
25
|
Object.defineProperty( this, 'id', { value: _nodeId ++ } );
|
|
23
26
|
|
|
24
27
|
}
|
|
@@ -52,6 +55,12 @@ class Node {
|
|
|
52
55
|
|
|
53
56
|
}
|
|
54
57
|
|
|
58
|
+
dispose() {
|
|
59
|
+
|
|
60
|
+
this.dispatchEvent( { type: 'dispose' } );
|
|
61
|
+
|
|
62
|
+
}
|
|
63
|
+
|
|
55
64
|
traverse( callback, replaceNode = null ) {
|
|
56
65
|
|
|
57
66
|
callback( this, replaceNode );
|
|
@@ -51,7 +51,11 @@ export const clearcoat = nodeImmutable( PropertyNode, 'float', 'Clearcoat' );
|
|
|
51
51
|
export const clearcoatRoughness = nodeImmutable( PropertyNode, 'float', 'ClearcoatRoughness' );
|
|
52
52
|
export const sheen = nodeImmutable( PropertyNode, 'vec3', 'Sheen' );
|
|
53
53
|
export const sheenRoughness = nodeImmutable( PropertyNode, 'float', 'SheenRoughness' );
|
|
54
|
+
export const iridescence = nodeImmutable( PropertyNode, 'float', 'Iridescence' );
|
|
55
|
+
export const iridescenceIOR = nodeImmutable( PropertyNode, 'float', 'IridescenceIOR' );
|
|
56
|
+
export const iridescenceThickness = nodeImmutable( PropertyNode, 'float', 'IridescenceThickness' );
|
|
54
57
|
export const specularColor = nodeImmutable( PropertyNode, 'color', 'SpecularColor' );
|
|
55
58
|
export const shininess = nodeImmutable( PropertyNode, 'float', 'Shininess' );
|
|
59
|
+
export const output = nodeImmutable( PropertyNode, 'vec4', 'Output' );
|
|
56
60
|
|
|
57
61
|
addNodeClass( PropertyNode );
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import TempNode from '../core/TempNode.js';
|
|
2
|
+
import { texture } from '../accessors/TextureNode.js';
|
|
3
|
+
import { addNodeClass } from '../core/Node.js';
|
|
4
|
+
import { uv } from '../accessors/UVNode.js';
|
|
5
|
+
import { normalView } from '../accessors/NormalNode.js';
|
|
6
|
+
import { positionView } from '../accessors/PositionNode.js';
|
|
7
|
+
import { faceDirection } from './FrontFacingNode.js';
|
|
8
|
+
import { tslFn, nodeProxy, vec2 } from '../shadernode/ShaderNode.js';
|
|
9
|
+
|
|
10
|
+
// Bump Mapping Unparametrized Surfaces on the GPU by Morten S. Mikkelsen
|
|
11
|
+
// https://mmikk.github.io/papers3d/mm_sfgrad_bump.pdf
|
|
12
|
+
|
|
13
|
+
// Evaluate the derivative of the height w.r.t. screen-space using forward differencing (listing 2)
|
|
14
|
+
|
|
15
|
+
const dHdxy_fwd = tslFn( ( { bumpTexture, bumpScale } ) => {
|
|
16
|
+
|
|
17
|
+
const uvNode = uv();
|
|
18
|
+
|
|
19
|
+
const Hll = texture( bumpTexture, uvNode ).x;
|
|
20
|
+
|
|
21
|
+
return vec2(
|
|
22
|
+
texture( bumpTexture, uvNode.add( uvNode.dFdx() ) ).x.sub( Hll ),
|
|
23
|
+
texture( bumpTexture, uvNode.add( uvNode.dFdy() ) ).x.sub( Hll )
|
|
24
|
+
).mul( bumpScale );
|
|
25
|
+
|
|
26
|
+
} );
|
|
27
|
+
|
|
28
|
+
const perturbNormalArb = tslFn( ( inputs ) => {
|
|
29
|
+
|
|
30
|
+
const { surf_pos, surf_norm, dHdxy } = inputs;
|
|
31
|
+
|
|
32
|
+
const vSigmaX = surf_pos.dFdx();
|
|
33
|
+
const vSigmaY = surf_pos.dFdy();
|
|
34
|
+
const vN = surf_norm; // normalized
|
|
35
|
+
|
|
36
|
+
const R1 = vSigmaY.cross( vN );
|
|
37
|
+
const R2 = vN.cross( vSigmaX );
|
|
38
|
+
|
|
39
|
+
const fDet = vSigmaX.dot( R1 ).mul( faceDirection );
|
|
40
|
+
|
|
41
|
+
const vGrad = fDet.sign().mul( dHdxy.x.mul( R1 ).add( dHdxy.y.mul( R2 ) ) );
|
|
42
|
+
|
|
43
|
+
return fDet.abs().mul( surf_norm ).sub( vGrad ).normalize();
|
|
44
|
+
|
|
45
|
+
} );
|
|
46
|
+
|
|
47
|
+
class BumpMapNode extends TempNode {
|
|
48
|
+
|
|
49
|
+
constructor( texture, scaleNode = null ) {
|
|
50
|
+
|
|
51
|
+
super( 'vec3' );
|
|
52
|
+
|
|
53
|
+
this.texture = texture;
|
|
54
|
+
this.scaleNode = scaleNode;
|
|
55
|
+
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
construct() {
|
|
59
|
+
|
|
60
|
+
const bumpScale = this.scaleNode !== null ? this.scaleNode : 1;
|
|
61
|
+
const dHdxy = dHdxy_fwd( { bumpTexture: this.texture, bumpScale } );
|
|
62
|
+
|
|
63
|
+
return perturbNormalArb( {
|
|
64
|
+
surf_pos: positionView.negate(),
|
|
65
|
+
surf_norm: normalView,
|
|
66
|
+
dHdxy
|
|
67
|
+
} );
|
|
68
|
+
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export default BumpMapNode;
|
|
74
|
+
|
|
75
|
+
export const bumpMap = nodeProxy( BumpMapNode );
|
|
76
|
+
|
|
77
|
+
addNodeClass( BumpMapNode );
|
|
@@ -15,7 +15,7 @@ import { TangentSpaceNormalMap, ObjectSpaceNormalMap } from 'three';
|
|
|
15
15
|
// Normal Mapping Without Precomputed Tangents
|
|
16
16
|
// http://www.thetenthplanet.de/archives/1180
|
|
17
17
|
|
|
18
|
-
const
|
|
18
|
+
const perturbNormal2Arb = tslFn( ( inputs ) => {
|
|
19
19
|
|
|
20
20
|
const { eye_pos, surf_norm, mapN, uv } = inputs;
|
|
21
21
|
|
|
@@ -80,7 +80,7 @@ class NormalMapNode extends TempNode {
|
|
|
80
80
|
|
|
81
81
|
} else {
|
|
82
82
|
|
|
83
|
-
outputNode =
|
|
83
|
+
outputNode = perturbNormal2Arb( {
|
|
84
84
|
eye_pos: positionView,
|
|
85
85
|
surf_norm: normalView,
|
|
86
86
|
mapN: normalMap,
|
|
@@ -3,12 +3,13 @@ import V_GGX_SmithCorrelated from './V_GGX_SmithCorrelated.js';
|
|
|
3
3
|
import D_GGX from './D_GGX.js';
|
|
4
4
|
import { transformedNormalView } from '../../accessors/NormalNode.js';
|
|
5
5
|
import { positionViewDirection } from '../../accessors/PositionNode.js';
|
|
6
|
+
import { iridescence } from '../../core/PropertyNode.js';
|
|
6
7
|
import { tslFn } from '../../shadernode/ShaderNode.js';
|
|
7
8
|
|
|
8
9
|
// GGX Distribution, Schlick Fresnel, GGX_SmithCorrelated Visibility
|
|
9
10
|
const BRDF_GGX = tslFn( ( inputs ) => {
|
|
10
11
|
|
|
11
|
-
const { lightDirection, f0, f90, roughness } = inputs;
|
|
12
|
+
const { lightDirection, f0, f90, roughness, iridescenceFresnel } = inputs;
|
|
12
13
|
|
|
13
14
|
const normalView = inputs.normalView || transformedNormalView;
|
|
14
15
|
|
|
@@ -21,7 +22,14 @@ const BRDF_GGX = tslFn( ( inputs ) => {
|
|
|
21
22
|
const dotNH = normalView.dot( halfDir ).clamp();
|
|
22
23
|
const dotVH = positionViewDirection.dot( halfDir ).clamp();
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
let F = F_Schlick( { f0, f90, dotVH } );
|
|
26
|
+
|
|
27
|
+
if ( iridescenceFresnel ) {
|
|
28
|
+
|
|
29
|
+
F = iridescence.mix( F, iridescenceFresnel );
|
|
30
|
+
|
|
31
|
+
}
|
|
32
|
+
|
|
25
33
|
const V = V_GGX_SmithCorrelated( { alpha, dotNL, dotNV } );
|
|
26
34
|
const D = D_GGX( { alpha, dotNH } );
|
|
27
35
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { tslFn, vec3 } from '../../shadernode/ShaderNode.js';
|
|
2
|
+
|
|
3
|
+
const Schlick_to_F0 = tslFn( ( { f, f90, dotVH } ) => {
|
|
4
|
+
|
|
5
|
+
const x = dotVH.oneMinus().saturate();
|
|
6
|
+
const x2 = x.mul( x );
|
|
7
|
+
const x5 = x.mul( x2, x2 ).clamp( 0, .9999 );
|
|
8
|
+
|
|
9
|
+
return f.sub( vec3( f90 ).mul( x5 ) ).div( x5.oneMinus() );
|
|
10
|
+
|
|
11
|
+
} );
|
|
12
|
+
|
|
13
|
+
export default Schlick_to_F0;
|
|
@@ -1,28 +1,67 @@
|
|
|
1
|
+
import LightingModel from '../core/LightingModel.js';
|
|
2
|
+
import F_Schlick from './BSDF/F_Schlick.js';
|
|
1
3
|
import BRDF_Lambert from './BSDF/BRDF_Lambert.js';
|
|
2
|
-
import BRDF_BlinnPhong from './BSDF/BRDF_BlinnPhong.js';
|
|
3
|
-
import { lightingModel } from '../core/LightingModel.js';
|
|
4
4
|
import { diffuseColor } from '../core/PropertyNode.js';
|
|
5
|
-
import { materialReflectivity } from '../accessors/MaterialNode.js';
|
|
6
5
|
import { transformedNormalView } from '../accessors/NormalNode.js';
|
|
7
|
-
import {
|
|
6
|
+
import { materialSpecularStrength } from '../accessors/MaterialNode.js';
|
|
7
|
+
import { shininess, specularColor } from '../core/PropertyNode.js';
|
|
8
|
+
import { positionViewDirection } from '../accessors/PositionNode.js';
|
|
9
|
+
import { tslFn, float } from '../shadernode/ShaderNode.js';
|
|
8
10
|
|
|
9
|
-
const
|
|
11
|
+
const G_BlinnPhong_Implicit = () => float( 0.25 );
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
const irradiance = dotNL.mul( lightColor );
|
|
13
|
+
const D_BlinnPhong = tslFn( ( { dotNH } ) => {
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
reflectedLight.directSpecular.addAssign( irradiance.mul( BRDF_BlinnPhong( { lightDirection } ) ).mul( materialReflectivity ) );
|
|
15
|
+
return shininess.mul( 0.5 / Math.PI ).add( 1.0 ).mul( dotNH.pow( shininess ) );
|
|
17
16
|
|
|
18
17
|
} );
|
|
19
18
|
|
|
20
|
-
const
|
|
19
|
+
const BRDF_BlinnPhong = tslFn( ( { lightDirection } ) => {
|
|
20
|
+
|
|
21
|
+
const halfDir = lightDirection.add( positionViewDirection ).normalize();
|
|
22
|
+
|
|
23
|
+
const dotNH = transformedNormalView.dot( halfDir ).clamp();
|
|
24
|
+
const dotVH = positionViewDirection.dot( halfDir ).clamp();
|
|
21
25
|
|
|
22
|
-
|
|
26
|
+
const F = F_Schlick( { f0: specularColor, f90: 1.0, dotVH } );
|
|
27
|
+
const G = G_BlinnPhong_Implicit();
|
|
28
|
+
const D = D_BlinnPhong( { dotNH } );
|
|
29
|
+
|
|
30
|
+
return F.mul( G ).mul( D );
|
|
23
31
|
|
|
24
32
|
} );
|
|
25
33
|
|
|
26
|
-
|
|
34
|
+
class PhongLightingModel extends LightingModel {
|
|
35
|
+
|
|
36
|
+
constructor( specular = true ) {
|
|
37
|
+
|
|
38
|
+
super();
|
|
39
|
+
|
|
40
|
+
this.specular = specular;
|
|
41
|
+
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
direct( { lightDirection, lightColor, reflectedLight } ) {
|
|
45
|
+
|
|
46
|
+
const dotNL = transformedNormalView.dot( lightDirection ).clamp();
|
|
47
|
+
const irradiance = dotNL.mul( lightColor );
|
|
48
|
+
|
|
49
|
+
reflectedLight.directDiffuse.addAssign( irradiance.mul( BRDF_Lambert( { diffuseColor: diffuseColor.rgb } ) ) );
|
|
50
|
+
|
|
51
|
+
if ( this.specular === true ) {
|
|
52
|
+
|
|
53
|
+
reflectedLight.directSpecular.addAssign( irradiance.mul( BRDF_BlinnPhong( { lightDirection } ) ).mul( materialSpecularStrength ) );
|
|
54
|
+
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
indirectDiffuse( { irradiance, reflectedLight } ) {
|
|
60
|
+
|
|
61
|
+
reflectedLight.indirectDiffuse.addAssign( irradiance.mul( BRDF_Lambert( { diffuseColor } ) ) );
|
|
62
|
+
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
}
|
|
27
66
|
|
|
28
|
-
export default
|
|
67
|
+
export default PhongLightingModel;
|