super-three 0.160.1 → 0.161.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/LICENSE +1 -1
- package/build/three.cjs +379 -108
- package/build/three.module.js +380 -108
- package/build/three.module.min.js +1 -1
- package/examples/jsm/Addons.js +5 -1
- package/examples/jsm/capabilities/WebGPU.js +13 -9
- package/examples/jsm/controls/OrbitControls.js +102 -13
- package/examples/jsm/curves/NURBSUtils.js +59 -4
- package/examples/jsm/curves/NURBSVolume.js +62 -0
- package/examples/jsm/exporters/USDZExporter.js +8 -7
- package/examples/jsm/helpers/TextureHelper.js +3 -3
- package/examples/jsm/loaders/3DMLoader.js +44 -43
- package/examples/jsm/loaders/DDSLoader.js +1 -0
- package/examples/jsm/loaders/KTX2Loader.js +20 -5
- package/examples/jsm/loaders/LUT3dlLoader.js +78 -46
- package/examples/jsm/loaders/LUTCubeLoader.js +81 -67
- package/examples/jsm/loaders/LUTImageLoader.js +3 -2
- package/examples/jsm/loaders/MaterialXLoader.js +115 -16
- package/examples/jsm/loaders/SVGLoader.js +4 -3
- package/examples/jsm/loaders/VRMLLoader.js +1 -1
- package/examples/jsm/materials/MeshPostProcessingMaterial.js +144 -0
- package/examples/jsm/misc/Timer.js +13 -4
- package/examples/jsm/nodes/Nodes.js +16 -5
- package/examples/jsm/nodes/accessors/BufferAttributeNode.js +5 -3
- package/examples/jsm/nodes/accessors/CameraNode.js +9 -4
- package/examples/jsm/nodes/accessors/CubeTextureNode.js +12 -1
- package/examples/jsm/nodes/accessors/StorageBufferNode.js +27 -0
- package/examples/jsm/nodes/accessors/TextureStoreNode.js +56 -3
- package/examples/jsm/nodes/accessors/VertexColorNode.js +70 -0
- package/examples/jsm/nodes/core/AttributeNode.js +1 -1
- package/examples/jsm/nodes/core/NodeBuilder.js +23 -18
- package/examples/jsm/nodes/core/NodeFrame.js +16 -8
- package/examples/jsm/nodes/core/constants.js +1 -0
- package/examples/jsm/nodes/display/AfterImageNode.js +148 -0
- package/examples/jsm/nodes/display/AnamorphicNode.js +148 -0
- package/examples/jsm/nodes/display/ColorAdjustmentNode.js +3 -0
- package/examples/jsm/nodes/display/GaussianBlurNode.js +33 -13
- package/examples/jsm/nodes/display/PassNode.js +3 -2
- package/examples/jsm/nodes/display/ToneMappingNode.js +46 -3
- package/examples/jsm/nodes/display/ViewportDepthTextureNode.js +1 -4
- package/examples/jsm/nodes/display/ViewportNode.js +0 -2
- package/examples/jsm/nodes/display/ViewportSharedTextureNode.js +4 -4
- package/examples/jsm/nodes/fog/FogNode.js +2 -1
- package/examples/jsm/nodes/lighting/AmbientLightNode.js +1 -1
- package/examples/jsm/nodes/lighting/AnalyticLightNode.js +13 -5
- package/examples/jsm/nodes/lighting/LightingContextNode.js +1 -1
- package/examples/jsm/nodes/lighting/LightsNode.js +1 -1
- package/examples/jsm/nodes/materials/Line2NodeMaterial.js +18 -30
- package/examples/jsm/nodes/materials/Materials.js +1 -0
- package/examples/jsm/nodes/materials/MeshSSSNodeMaterial.js +84 -0
- package/examples/jsm/nodes/materials/NodeMaterial.js +6 -4
- package/examples/jsm/nodes/materials/SpriteNodeMaterial.js +1 -7
- package/examples/jsm/nodes/math/MathNode.js +12 -2
- package/examples/jsm/nodes/math/MathUtils.js +15 -0
- package/examples/jsm/nodes/math/OperatorNode.js +13 -5
- package/examples/jsm/nodes/math/TriNoise3D.js +71 -0
- package/examples/jsm/nodes/shadernode/ShaderNode.js +10 -1
- package/examples/jsm/nodes/utils/ArrayElementNode.js +6 -0
- package/examples/jsm/nodes/utils/JoinNode.js +2 -2
- package/examples/jsm/nodes/utils/LoopNode.js +3 -3
- package/examples/jsm/nodes/utils/ReflectorNode.js +227 -0
- package/examples/jsm/nodes/utils/RotateNode.js +68 -0
- package/examples/jsm/nodes/utils/RotateUVNode.js +1 -9
- package/examples/jsm/nodes/utils/SplitNode.js +4 -4
- package/examples/jsm/objects/GroundedSkybox.js +50 -0
- package/examples/jsm/objects/QuadMesh.js +8 -2
- package/examples/jsm/objects/Water2.js +8 -8
- package/examples/jsm/postprocessing/GTAOPass.js +11 -1
- package/examples/jsm/renderers/common/Backend.js +14 -0
- package/examples/jsm/renderers/common/Bindings.js +1 -1
- package/examples/jsm/renderers/common/DataMap.js +1 -1
- package/examples/jsm/renderers/common/Info.js +25 -1
- package/examples/jsm/renderers/common/Pipelines.js +8 -8
- package/examples/jsm/renderers/common/PostProcessing.js +2 -2
- package/examples/jsm/renderers/common/ProgrammableStage.js +3 -1
- package/examples/jsm/renderers/common/RenderObject.js +2 -0
- package/examples/jsm/renderers/common/Renderer.js +238 -22
- package/examples/jsm/renderers/common/StorageBufferAttribute.js +17 -0
- package/examples/jsm/renderers/common/Textures.js +25 -5
- package/examples/jsm/renderers/common/nodes/NodeBuilderState.js +2 -1
- package/examples/jsm/renderers/common/nodes/Nodes.js +4 -2
- package/examples/jsm/renderers/webgl/WebGLBackend.js +631 -270
- package/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js +37 -30
- package/examples/jsm/renderers/webgl/utils/WebGLAttributeUtils.js +89 -8
- package/examples/jsm/renderers/webgl/utils/WebGLConstants.js +11 -0
- package/examples/jsm/renderers/webgl/utils/WebGLState.js +197 -0
- package/examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js +377 -11
- package/examples/jsm/renderers/webgl/utils/WebGLUtils.js +2 -2
- package/examples/jsm/renderers/webgl-legacy/nodes/GLSL1NodeBuilder.js +1 -21
- package/examples/jsm/renderers/webgl-legacy/nodes/WebGLNodeBuilder.js +2 -2
- package/examples/jsm/renderers/webgpu/WebGPUBackend.js +289 -102
- package/examples/jsm/renderers/webgpu/WebGPURenderer.js +7 -2
- package/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js +56 -39
- package/examples/jsm/renderers/webgpu/utils/WebGPUAttributeUtils.js +9 -1
- package/examples/jsm/renderers/webgpu/utils/WebGPUPipelineUtils.js +38 -4
- package/examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js +85 -12
- package/examples/jsm/transpiler/AST.js +1 -1
- package/examples/jsm/transpiler/GLSLDecoder.js +1 -1
- package/examples/jsm/transpiler/ShaderToyDecoder.js +1 -1
- package/examples/jsm/transpiler/TSLEncoder.js +1 -1
- package/examples/jsm/utils/BufferGeometryUtils.js +23 -27
- package/examples/jsm/utils/SortUtils.js +2 -0
- package/examples/jsm/webxr/ARButton.js +12 -2
- package/examples/jsm/webxr/VRButton.js +12 -2
- package/examples/jsm/webxr/XRButton.js +12 -2
- package/examples/jsm/webxr/XRControllerModelFactory.js +6 -1
- package/examples/jsm/webxr/XRHandMeshModel.js +3 -1
- package/package.json +2 -2
- package/src/audio/Audio.js +1 -3
- package/src/cameras/PerspectiveCamera.js +35 -0
- package/src/constants.js +1 -2
- package/src/core/BufferAttribute.js +2 -1
- package/src/core/InterleavedBuffer.js +2 -1
- package/src/core/InterleavedBufferAttribute.js +20 -0
- package/src/materials/ShaderMaterial.js +2 -1
- package/src/math/Triangle.js +0 -30
- package/src/objects/BatchedMesh.js +6 -7
- package/src/objects/SkinnedMesh.js +0 -8
- package/src/renderers/WebGLRenderer.js +5 -1
- package/src/renderers/shaders/ShaderChunk/alphatest_fragment.glsl.js +9 -0
- package/src/renderers/shaders/ShaderChunk/clipping_planes_fragment.glsl.js +56 -11
- package/src/renderers/shaders/ShaderChunk/tonemapping_pars_fragment.glsl.js +15 -7
- package/src/renderers/shaders/ShaderLib/depth.glsl.js +1 -2
- package/src/renderers/shaders/ShaderLib/distanceRGBA.glsl.js +1 -2
- package/src/renderers/shaders/ShaderLib/linedashed.glsl.js +1 -1
- package/src/renderers/shaders/ShaderLib/meshbasic.glsl.js +1 -2
- package/src/renderers/shaders/ShaderLib/meshlambert.glsl.js +1 -1
- package/src/renderers/shaders/ShaderLib/meshmatcap.glsl.js +1 -2
- package/src/renderers/shaders/ShaderLib/meshnormal.glsl.js +3 -1
- package/src/renderers/shaders/ShaderLib/meshphong.glsl.js +1 -1
- package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +1 -1
- package/src/renderers/shaders/ShaderLib/meshtoon.glsl.js +1 -1
- package/src/renderers/shaders/ShaderLib/points.glsl.js +1 -1
- package/src/renderers/shaders/ShaderLib/sprite.glsl.js +1 -1
- package/src/renderers/webgl/WebGLAttributes.js +2 -2
- package/src/renderers/webgl/WebGLCubeMaps.js +1 -1
- package/src/renderers/webgl/WebGLProgram.js +30 -3
- package/src/renderers/webgl/WebGLPrograms.js +19 -11
- package/src/renderers/webgl/WebGLTextures.js +90 -16
- package/src/renderers/webxr/WebXRDepthSensing.js +105 -0
- package/src/renderers/webxr/WebXRManager.js +46 -0
- package/src/textures/Source.js +1 -0
- package/build/three.js +0 -54519
- package/build/three.min.js +0 -7
- package/examples/jsm/objects/GroundProjectedSkybox.js +0 -172
|
@@ -120,17 +120,32 @@ class KTX2Loader extends Loader {
|
|
|
120
120
|
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
+
async detectSupportAsync( renderer ) {
|
|
124
|
+
|
|
125
|
+
this.workerConfig = {
|
|
126
|
+
astcSupported: await renderer.hasFeatureAsync( 'texture-compression-astc' ),
|
|
127
|
+
etc1Supported: await renderer.hasFeatureAsync( 'texture-compression-etc1' ),
|
|
128
|
+
etc2Supported: await renderer.hasFeatureAsync( 'texture-compression-etc2' ),
|
|
129
|
+
dxtSupported: await renderer.hasFeatureAsync( 'texture-compression-bc' ),
|
|
130
|
+
bptcSupported: await renderer.hasFeatureAsync( 'texture-compression-bptc' ),
|
|
131
|
+
pvrtcSupported: await renderer.hasFeatureAsync( 'texture-compression-pvrtc' )
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
return this;
|
|
135
|
+
|
|
136
|
+
}
|
|
137
|
+
|
|
123
138
|
detectSupport( renderer ) {
|
|
124
139
|
|
|
125
140
|
if ( renderer.isWebGPURenderer === true ) {
|
|
126
141
|
|
|
127
142
|
this.workerConfig = {
|
|
128
143
|
astcSupported: renderer.hasFeature( 'texture-compression-astc' ),
|
|
129
|
-
etc1Supported:
|
|
144
|
+
etc1Supported: renderer.hasFeature( 'texture-compression-etc1' ),
|
|
130
145
|
etc2Supported: renderer.hasFeature( 'texture-compression-etc2' ),
|
|
131
146
|
dxtSupported: renderer.hasFeature( 'texture-compression-bc' ),
|
|
132
|
-
bptcSupported:
|
|
133
|
-
pvrtcSupported:
|
|
147
|
+
bptcSupported: renderer.hasFeature( 'texture-compression-bptc' ),
|
|
148
|
+
pvrtcSupported: renderer.hasFeature( 'texture-compression-pvrtc' )
|
|
134
149
|
};
|
|
135
150
|
|
|
136
151
|
} else {
|
|
@@ -865,8 +880,8 @@ async function createRawTexture( container ) {
|
|
|
865
880
|
if ( UNCOMPRESSED_FORMATS.has( FORMAT_MAP[ vkFormat ] ) ) {
|
|
866
881
|
|
|
867
882
|
texture = container.pixelDepth === 0
|
|
868
|
-
|
|
869
|
-
|
|
883
|
+
? new DataTexture( mipmaps[ 0 ].data, container.pixelWidth, container.pixelHeight )
|
|
884
|
+
: new Data3DTexture( mipmaps[ 0 ].data, container.pixelWidth, container.pixelHeight, container.pixelDepth );
|
|
870
885
|
|
|
871
886
|
} else {
|
|
872
887
|
|
|
@@ -1,18 +1,42 @@
|
|
|
1
1
|
// http://download.autodesk.com/us/systemdocs/help/2011/lustre/index.html?url=./files/WSc4e151a45a3b785a24c3d9a411df9298473-7ffd.htm,topicNumber=d0e9492
|
|
2
2
|
// https://community.foundry.com/discuss/topic/103636/format-spec-for-3dl?mode=Post&postID=895258
|
|
3
|
+
|
|
3
4
|
import {
|
|
4
|
-
|
|
5
|
-
FileLoader,
|
|
5
|
+
ClampToEdgeWrapping,
|
|
6
6
|
DataTexture,
|
|
7
7
|
Data3DTexture,
|
|
8
|
+
FileLoader,
|
|
9
|
+
FloatType,
|
|
10
|
+
LinearFilter,
|
|
11
|
+
Loader,
|
|
8
12
|
RGBAFormat,
|
|
9
13
|
UnsignedByteType,
|
|
10
|
-
ClampToEdgeWrapping,
|
|
11
|
-
LinearFilter,
|
|
12
14
|
} from 'three';
|
|
13
15
|
|
|
14
16
|
export class LUT3dlLoader extends Loader {
|
|
15
17
|
|
|
18
|
+
constructor( manager ) {
|
|
19
|
+
|
|
20
|
+
super( manager );
|
|
21
|
+
|
|
22
|
+
this.type = UnsignedByteType;
|
|
23
|
+
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
setType( type ) {
|
|
27
|
+
|
|
28
|
+
if ( type !== UnsignedByteType && type !== FloatType ) {
|
|
29
|
+
|
|
30
|
+
throw new Error( 'LUT3dlLoader: Unsupported type' );
|
|
31
|
+
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
this.type = type;
|
|
35
|
+
|
|
36
|
+
return this;
|
|
37
|
+
|
|
38
|
+
}
|
|
39
|
+
|
|
16
40
|
load( url, onLoad, onProgress, onError ) {
|
|
17
41
|
|
|
18
42
|
const loader = new FileLoader( this.manager );
|
|
@@ -44,80 +68,88 @@ export class LUT3dlLoader extends Loader {
|
|
|
44
68
|
|
|
45
69
|
}
|
|
46
70
|
|
|
47
|
-
parse(
|
|
71
|
+
parse( input ) {
|
|
72
|
+
|
|
73
|
+
const regExpGridInfo = /^[\d ]+$/m;
|
|
74
|
+
const regExpDataPoints = /^([\d.e+-]+) +([\d.e+-]+) +([\d.e+-]+) *$/gm;
|
|
48
75
|
|
|
49
|
-
//
|
|
50
|
-
|
|
51
|
-
.replace( /^#.*?(\n|\r)/gm, '' )
|
|
52
|
-
.replace( /^\s*?(\n|\r)/gm, '' )
|
|
53
|
-
.trim();
|
|
76
|
+
// The first line describes the positions of values on the LUT grid.
|
|
77
|
+
let result = regExpGridInfo.exec( input );
|
|
54
78
|
|
|
55
|
-
|
|
79
|
+
if ( result === null ) {
|
|
56
80
|
|
|
57
|
-
|
|
58
|
-
|
|
81
|
+
throw new Error( 'LUT3dlLoader: Missing grid information' );
|
|
82
|
+
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const gridLines = result[ 0 ].trim().split( /\s+/g ).map( Number );
|
|
59
86
|
const gridStep = gridLines[ 1 ] - gridLines[ 0 ];
|
|
60
87
|
const size = gridLines.length;
|
|
88
|
+
const sizeSq = size ** 2;
|
|
61
89
|
|
|
62
|
-
for ( let i = 1, l = gridLines.length; i < l; i
|
|
90
|
+
for ( let i = 1, l = gridLines.length; i < l; ++ i ) {
|
|
63
91
|
|
|
64
92
|
if ( gridStep !== ( gridLines[ i ] - gridLines[ i - 1 ] ) ) {
|
|
65
93
|
|
|
66
|
-
throw new Error( 'LUT3dlLoader: Inconsistent grid size
|
|
94
|
+
throw new Error( 'LUT3dlLoader: Inconsistent grid size' );
|
|
67
95
|
|
|
68
96
|
}
|
|
69
97
|
|
|
70
98
|
}
|
|
71
99
|
|
|
72
|
-
const
|
|
100
|
+
const dataFloat = new Float32Array( size ** 3 * 4 );
|
|
101
|
+
let maxValue = 0.0;
|
|
73
102
|
let index = 0;
|
|
74
|
-
let maxOutputValue = 0.0;
|
|
75
|
-
for ( let i = 1, l = lines.length; i < l; i ++ ) {
|
|
76
103
|
|
|
77
|
-
|
|
78
|
-
|
|
104
|
+
while ( ( result = regExpDataPoints.exec( input ) ) !== null ) {
|
|
105
|
+
|
|
106
|
+
const r = Number( result[ 1 ] );
|
|
107
|
+
const g = Number( result[ 2 ] );
|
|
108
|
+
const b = Number( result[ 3 ] );
|
|
79
109
|
|
|
80
|
-
|
|
81
|
-
const g = parseFloat( split[ 1 ] );
|
|
82
|
-
const b = parseFloat( split[ 2 ] );
|
|
83
|
-
maxOutputValue = Math.max( maxOutputValue, r, g, b );
|
|
110
|
+
maxValue = Math.max( maxValue, r, g, b );
|
|
84
111
|
|
|
85
112
|
const bLayer = index % size;
|
|
86
113
|
const gLayer = Math.floor( index / size ) % size;
|
|
87
|
-
const rLayer = Math.floor( index / (
|
|
114
|
+
const rLayer = Math.floor( index / ( sizeSq ) ) % size;
|
|
88
115
|
|
|
89
|
-
// b grows first, then g, then r
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
index
|
|
116
|
+
// b grows first, then g, then r.
|
|
117
|
+
const d4 = ( bLayer * sizeSq + gLayer * size + rLayer ) * 4;
|
|
118
|
+
dataFloat[ d4 + 0 ] = r;
|
|
119
|
+
dataFloat[ d4 + 1 ] = g;
|
|
120
|
+
dataFloat[ d4 + 2 ] = b;
|
|
121
|
+
|
|
122
|
+
++ index;
|
|
96
123
|
|
|
97
124
|
}
|
|
98
125
|
|
|
99
|
-
//
|
|
100
|
-
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
126
|
+
// Determine the bit depth to scale the values to [0.0, 1.0].
|
|
127
|
+
const bits = Math.ceil( Math.log2( maxValue ) );
|
|
128
|
+
const maxBitValue = Math.pow( 2, bits );
|
|
129
|
+
|
|
130
|
+
const data = this.type === UnsignedByteType ? new Uint8Array( dataFloat.length ) : dataFloat;
|
|
131
|
+
const scale = this.type === UnsignedByteType ? 255 : 1;
|
|
132
|
+
|
|
133
|
+
for ( let i = 0, l = data.length; i < l; i += 4 ) {
|
|
134
|
+
|
|
135
|
+
const i1 = i + 1;
|
|
136
|
+
const i2 = i + 2;
|
|
137
|
+
const i3 = i + 3;
|
|
104
138
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
dataArray[ i + 2 ] = 255 * b / maxBitValue; // b
|
|
139
|
+
// Note: data is dataFloat when type is FloatType.
|
|
140
|
+
data[ i ] = dataFloat[ i ] / maxBitValue * scale;
|
|
141
|
+
data[ i1 ] = dataFloat[ i1 ] / maxBitValue * scale;
|
|
142
|
+
data[ i2 ] = dataFloat[ i2 ] / maxBitValue * scale;
|
|
143
|
+
data[ i3 ] = scale;
|
|
111
144
|
|
|
112
145
|
}
|
|
113
146
|
|
|
114
|
-
const data = new Uint8Array( dataArray );
|
|
115
147
|
const texture = new DataTexture();
|
|
116
148
|
texture.image.data = data;
|
|
117
149
|
texture.image.width = size;
|
|
118
150
|
texture.image.height = size * size;
|
|
119
151
|
texture.format = RGBAFormat;
|
|
120
|
-
texture.type =
|
|
152
|
+
texture.type = this.type;
|
|
121
153
|
texture.magFilter = LinearFilter;
|
|
122
154
|
texture.minFilter = LinearFilter;
|
|
123
155
|
texture.wrapS = ClampToEdgeWrapping;
|
|
@@ -131,7 +163,7 @@ export class LUT3dlLoader extends Loader {
|
|
|
131
163
|
texture3D.image.height = size;
|
|
132
164
|
texture3D.image.depth = size;
|
|
133
165
|
texture3D.format = RGBAFormat;
|
|
134
|
-
texture3D.type =
|
|
166
|
+
texture3D.type = this.type;
|
|
135
167
|
texture3D.magFilter = LinearFilter;
|
|
136
168
|
texture3D.minFilter = LinearFilter;
|
|
137
169
|
texture3D.wrapS = ClampToEdgeWrapping;
|
|
@@ -1,18 +1,41 @@
|
|
|
1
1
|
// https://wwwimages2.adobe.com/content/dam/acom/en/products/speedgrade/cc/pdfs/cube-lut-specification-1.0.pdf
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
|
-
|
|
5
|
-
FileLoader,
|
|
6
|
-
Vector3,
|
|
4
|
+
ClampToEdgeWrapping,
|
|
7
5
|
DataTexture,
|
|
8
6
|
Data3DTexture,
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
FileLoader,
|
|
8
|
+
FloatType,
|
|
11
9
|
LinearFilter,
|
|
10
|
+
Loader,
|
|
11
|
+
UnsignedByteType,
|
|
12
|
+
Vector3,
|
|
12
13
|
} from 'three';
|
|
13
14
|
|
|
14
15
|
export class LUTCubeLoader extends Loader {
|
|
15
16
|
|
|
17
|
+
constructor( manager ) {
|
|
18
|
+
|
|
19
|
+
super( manager );
|
|
20
|
+
|
|
21
|
+
this.type = UnsignedByteType;
|
|
22
|
+
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
setType( type ) {
|
|
26
|
+
|
|
27
|
+
if ( type !== UnsignedByteType && type !== FloatType ) {
|
|
28
|
+
|
|
29
|
+
throw new Error( 'LUTCubeLoader: Unsupported type' );
|
|
30
|
+
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
this.type = type;
|
|
34
|
+
|
|
35
|
+
return this;
|
|
36
|
+
|
|
37
|
+
}
|
|
38
|
+
|
|
16
39
|
load( url, onLoad, onProgress, onError ) {
|
|
17
40
|
|
|
18
41
|
const loader = new FileLoader( this.manager );
|
|
@@ -44,72 +67,63 @@ export class LUTCubeLoader extends Loader {
|
|
|
44
67
|
|
|
45
68
|
}
|
|
46
69
|
|
|
47
|
-
parse(
|
|
70
|
+
parse( input ) {
|
|
48
71
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
72
|
+
const regExpTitle = /TITLE +"([^"]*)"/;
|
|
73
|
+
const regExpSize = /LUT_3D_SIZE +(\d+)/;
|
|
74
|
+
const regExpDomainMin = /DOMAIN_MIN +([\d.]+) +([\d.]+) +([\d.]+)/;
|
|
75
|
+
const regExpDomainMax = /DOMAIN_MAX +([\d.]+) +([\d.]+) +([\d.]+)/;
|
|
76
|
+
const regExpDataPoints = /^([\d.e+-]+) +([\d.e+-]+) +([\d.e+-]+) *$/gm;
|
|
77
|
+
|
|
78
|
+
let result = regExpTitle.exec( input );
|
|
79
|
+
const title = ( result !== null ) ? result[ 1 ] : null;
|
|
80
|
+
|
|
81
|
+
result = regExpSize.exec( input );
|
|
82
|
+
|
|
83
|
+
if ( result === null ) {
|
|
84
|
+
|
|
85
|
+
throw new Error( 'LUTCubeLoader: Missing LUT_3D_SIZE information' );
|
|
86
|
+
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const size = Number( result[ 1 ] );
|
|
90
|
+
const length = size ** 3 * 4;
|
|
91
|
+
const data = this.type === UnsignedByteType ? new Uint8Array( length ) : new Float32Array( length );
|
|
54
92
|
|
|
55
|
-
let title = null;
|
|
56
|
-
let size = null;
|
|
57
93
|
const domainMin = new Vector3( 0, 0, 0 );
|
|
58
94
|
const domainMax = new Vector3( 1, 1, 1 );
|
|
59
95
|
|
|
60
|
-
|
|
61
|
-
let data = null;
|
|
62
|
-
|
|
63
|
-
let currIndex = 0;
|
|
64
|
-
for ( let i = 0, l = lines.length; i < l; i ++ ) {
|
|
65
|
-
|
|
66
|
-
const line = lines[ i ].trim();
|
|
67
|
-
const split = line.split( /\s/g );
|
|
68
|
-
|
|
69
|
-
switch ( split[ 0 ] ) {
|
|
70
|
-
|
|
71
|
-
case 'TITLE':
|
|
72
|
-
title = line.substring( 7, line.length - 1 );
|
|
73
|
-
break;
|
|
74
|
-
case 'LUT_3D_SIZE':
|
|
75
|
-
// TODO: A .CUBE LUT file specifies floating point values and could be represented with
|
|
76
|
-
// more precision than can be captured with Uint8Array.
|
|
77
|
-
const sizeToken = split[ 1 ];
|
|
78
|
-
size = parseFloat( sizeToken );
|
|
79
|
-
data = new Uint8Array( size * size * size * 4 );
|
|
80
|
-
break;
|
|
81
|
-
case 'DOMAIN_MIN':
|
|
82
|
-
domainMin.x = parseFloat( split[ 1 ] );
|
|
83
|
-
domainMin.y = parseFloat( split[ 2 ] );
|
|
84
|
-
domainMin.z = parseFloat( split[ 3 ] );
|
|
85
|
-
break;
|
|
86
|
-
case 'DOMAIN_MAX':
|
|
87
|
-
domainMax.x = parseFloat( split[ 1 ] );
|
|
88
|
-
domainMax.y = parseFloat( split[ 2 ] );
|
|
89
|
-
domainMax.z = parseFloat( split[ 3 ] );
|
|
90
|
-
break;
|
|
91
|
-
default:
|
|
92
|
-
const r = parseFloat( split[ 0 ] );
|
|
93
|
-
const g = parseFloat( split[ 1 ] );
|
|
94
|
-
const b = parseFloat( split[ 2 ] );
|
|
95
|
-
|
|
96
|
-
if (
|
|
97
|
-
r > 1.0 || r < 0.0 ||
|
|
98
|
-
g > 1.0 || g < 0.0 ||
|
|
99
|
-
b > 1.0 || b < 0.0
|
|
100
|
-
) {
|
|
101
|
-
|
|
102
|
-
throw new Error( 'LUTCubeLoader : Non normalized values not supported.' );
|
|
103
|
-
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
data[ currIndex + 0 ] = r * 255;
|
|
107
|
-
data[ currIndex + 1 ] = g * 255;
|
|
108
|
-
data[ currIndex + 2 ] = b * 255;
|
|
109
|
-
data[ currIndex + 3 ] = 255;
|
|
110
|
-
currIndex += 4;
|
|
96
|
+
result = regExpDomainMin.exec( input );
|
|
111
97
|
|
|
112
|
-
|
|
98
|
+
if ( result !== null ) {
|
|
99
|
+
|
|
100
|
+
domainMin.set( Number( result[ 1 ] ), Number( result[ 2 ] ), Number( result[ 3 ] ) );
|
|
101
|
+
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
result = regExpDomainMax.exec( input );
|
|
105
|
+
|
|
106
|
+
if ( result !== null ) {
|
|
107
|
+
|
|
108
|
+
domainMax.set( Number( result[ 1 ] ), Number( result[ 2 ] ), Number( result[ 3 ] ) );
|
|
109
|
+
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if ( domainMin.x > domainMax.x || domainMin.y > domainMax.y || domainMin.z > domainMax.z ) {
|
|
113
|
+
|
|
114
|
+
throw new Error( 'LUTCubeLoader: Invalid input domain' );
|
|
115
|
+
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const scale = this.type === UnsignedByteType ? 255 : 1;
|
|
119
|
+
let i = 0;
|
|
120
|
+
|
|
121
|
+
while ( ( result = regExpDataPoints.exec( input ) ) !== null ) {
|
|
122
|
+
|
|
123
|
+
data[ i ++ ] = Number( result[ 1 ] ) * scale;
|
|
124
|
+
data[ i ++ ] = Number( result[ 2 ] ) * scale;
|
|
125
|
+
data[ i ++ ] = Number( result[ 3 ] ) * scale;
|
|
126
|
+
data[ i ++ ] = scale;
|
|
113
127
|
|
|
114
128
|
}
|
|
115
129
|
|
|
@@ -117,7 +131,7 @@ export class LUTCubeLoader extends Loader {
|
|
|
117
131
|
texture.image.data = data;
|
|
118
132
|
texture.image.width = size;
|
|
119
133
|
texture.image.height = size * size;
|
|
120
|
-
texture.type =
|
|
134
|
+
texture.type = this.type;
|
|
121
135
|
texture.magFilter = LinearFilter;
|
|
122
136
|
texture.minFilter = LinearFilter;
|
|
123
137
|
texture.wrapS = ClampToEdgeWrapping;
|
|
@@ -130,7 +144,7 @@ export class LUTCubeLoader extends Loader {
|
|
|
130
144
|
texture3D.image.width = size;
|
|
131
145
|
texture3D.image.height = size;
|
|
132
146
|
texture3D.image.depth = size;
|
|
133
|
-
texture3D.type =
|
|
147
|
+
texture3D.type = this.type;
|
|
134
148
|
texture3D.magFilter = LinearFilter;
|
|
135
149
|
texture3D.minFilter = LinearFilter;
|
|
136
150
|
texture3D.wrapS = ClampToEdgeWrapping;
|
|
@@ -12,9 +12,10 @@ import {
|
|
|
12
12
|
export class LUTImageLoader extends Loader {
|
|
13
13
|
|
|
14
14
|
constructor( flipVertical = false ) {
|
|
15
|
-
|
|
15
|
+
|
|
16
|
+
//The NeutralLUT.png has green at the bottom for Unreal ang green at the top for Unity URP Color Lookup
|
|
16
17
|
//post-processing. If you're using lut image strips from a Unity pipeline then pass true to the constructor
|
|
17
|
-
|
|
18
|
+
|
|
18
19
|
super();
|
|
19
20
|
|
|
20
21
|
this.flip = flipVertical;
|
|
@@ -6,9 +6,10 @@ import {
|
|
|
6
6
|
} from 'three';
|
|
7
7
|
|
|
8
8
|
import {
|
|
9
|
-
MeshPhysicalNodeMaterial,
|
|
9
|
+
MeshBasicNodeMaterial, MeshPhysicalNodeMaterial,
|
|
10
10
|
float, bool, int, vec2, vec3, vec4, color, texture,
|
|
11
|
-
positionLocal,
|
|
11
|
+
positionLocal, positionWorld, uv, vertexColor,
|
|
12
|
+
normalLocal, normalWorld, tangentLocal, tangentWorld,
|
|
12
13
|
add, sub, mul, div, mod, abs, sign, floor, ceil, round, pow, sin, cos, tan,
|
|
13
14
|
asin, acos, atan2, sqrt, exp, clamp, min, max, normalize, length, dot, cross, normalMap,
|
|
14
15
|
remap, smoothstep, luminance, mx_rgbtohsv, mx_hsvtorgb,
|
|
@@ -39,26 +40,34 @@ class MXElement {
|
|
|
39
40
|
|
|
40
41
|
// Ref: https://github.com/mrdoob/three.js/issues/24674
|
|
41
42
|
|
|
43
|
+
const mx_add = ( in1, in2 = float( 0 ) ) => add( in1, in2 );
|
|
44
|
+
const mx_subtract = ( in1, in2 = float( 0 ) ) => sub( in1, in2 );
|
|
45
|
+
const mx_multiply = ( in1, in2 = float( 1 ) ) => mul( in1, in2 );
|
|
46
|
+
const mx_divide = ( in1, in2 = float( 1 ) ) => div( in1, in2 );
|
|
47
|
+
const mx_modulo = ( in1, in2 = float( 1 ) ) => mod( in1, in2 );
|
|
48
|
+
const mx_power = ( in1, in2 = float( 1 ) ) => pow( in1, in2 );
|
|
49
|
+
const mx_atan2 = ( in1 = float( 0 ), in2 = float( 1 ) ) => atan2( in1, in2 );
|
|
50
|
+
|
|
42
51
|
const MXElements = [
|
|
43
52
|
|
|
44
53
|
// << Math >>
|
|
45
|
-
new MXElement( 'add',
|
|
46
|
-
new MXElement( 'subtract',
|
|
47
|
-
new MXElement( 'multiply',
|
|
48
|
-
new MXElement( 'divide',
|
|
49
|
-
new MXElement( 'modulo',
|
|
54
|
+
new MXElement( 'add', mx_add, [ 'in1', 'in2' ] ),
|
|
55
|
+
new MXElement( 'subtract', mx_subtract, [ 'in1', 'in2' ] ),
|
|
56
|
+
new MXElement( 'multiply', mx_multiply, [ 'in1', 'in2' ] ),
|
|
57
|
+
new MXElement( 'divide', mx_divide, [ 'in1', 'in2' ] ),
|
|
58
|
+
new MXElement( 'modulo', mx_modulo, [ 'in1', 'in2' ] ),
|
|
50
59
|
new MXElement( 'absval', abs, [ 'in1', 'in2' ] ),
|
|
51
60
|
new MXElement( 'sign', sign, [ 'in1', 'in2' ] ),
|
|
52
61
|
new MXElement( 'floor', floor, [ 'in1', 'in2' ] ),
|
|
53
62
|
new MXElement( 'ceil', ceil, [ 'in1', 'in2' ] ),
|
|
54
63
|
new MXElement( 'round', round, [ 'in1', 'in2' ] ),
|
|
55
|
-
new MXElement( 'power',
|
|
64
|
+
new MXElement( 'power', mx_power, [ 'in1', 'in2' ] ),
|
|
56
65
|
new MXElement( 'sin', sin, [ 'in' ] ),
|
|
57
66
|
new MXElement( 'cos', cos, [ 'in' ] ),
|
|
58
67
|
new MXElement( 'tan', tan, [ 'in' ] ),
|
|
59
68
|
new MXElement( 'asin', asin, [ 'in' ] ),
|
|
60
69
|
new MXElement( 'acos', acos, [ 'in' ] ),
|
|
61
|
-
new MXElement( 'atan2',
|
|
70
|
+
new MXElement( 'atan2', mx_atan2, [ 'in1', 'in2' ] ),
|
|
62
71
|
new MXElement( 'sqrt', sqrt, [ 'in' ] ),
|
|
63
72
|
//new MtlXElement( 'ln', ... ),
|
|
64
73
|
new MXElement( 'exp', exp, [ 'in' ] ),
|
|
@@ -141,6 +150,20 @@ class MaterialXLoader extends Loader {
|
|
|
141
150
|
|
|
142
151
|
load( url, onLoad, onProgress, onError ) {
|
|
143
152
|
|
|
153
|
+
const _onError = function ( e ) {
|
|
154
|
+
|
|
155
|
+
if ( onError ) {
|
|
156
|
+
|
|
157
|
+
onError( e );
|
|
158
|
+
|
|
159
|
+
} else {
|
|
160
|
+
|
|
161
|
+
console.error( e );
|
|
162
|
+
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
};
|
|
166
|
+
|
|
144
167
|
new FileLoader( this.manager )
|
|
145
168
|
.setPath( this.path )
|
|
146
169
|
.load( url, async ( text ) => {
|
|
@@ -151,11 +174,11 @@ class MaterialXLoader extends Loader {
|
|
|
151
174
|
|
|
152
175
|
} catch ( e ) {
|
|
153
176
|
|
|
154
|
-
|
|
177
|
+
_onError( e );
|
|
155
178
|
|
|
156
179
|
}
|
|
157
180
|
|
|
158
|
-
}, onProgress,
|
|
181
|
+
}, onProgress, _onError );
|
|
159
182
|
|
|
160
183
|
return this;
|
|
161
184
|
|
|
@@ -312,7 +335,17 @@ class MaterialXNode {
|
|
|
312
335
|
|
|
313
336
|
const filePrefix = this.getRecursiveAttribute( 'fileprefix' ) || '';
|
|
314
337
|
|
|
315
|
-
|
|
338
|
+
let loader = this.materialX.textureLoader;
|
|
339
|
+
const uri = filePrefix + this.value;
|
|
340
|
+
|
|
341
|
+
if ( uri ) {
|
|
342
|
+
|
|
343
|
+
const handler = this.materialX.manager.getHandler( uri );
|
|
344
|
+
if ( handler !== null ) loader = handler;
|
|
345
|
+
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
const texture = loader.load( uri );
|
|
316
349
|
texture.wrapS = texture.wrapT = RepeatWrapping;
|
|
317
350
|
texture.flipY = false;
|
|
318
351
|
|
|
@@ -376,7 +409,32 @@ class MaterialXNode {
|
|
|
376
409
|
|
|
377
410
|
} else if ( element === 'position' ) {
|
|
378
411
|
|
|
379
|
-
|
|
412
|
+
const space = this.getAttribute( 'space' );
|
|
413
|
+
node = space === 'world' ? positionWorld : positionLocal;
|
|
414
|
+
|
|
415
|
+
} else if ( element === 'normal' ) {
|
|
416
|
+
|
|
417
|
+
const space = this.getAttribute( 'space' );
|
|
418
|
+
node = space === 'world' ? normalWorld : normalLocal;
|
|
419
|
+
|
|
420
|
+
} else if ( element === 'tangent' ) {
|
|
421
|
+
|
|
422
|
+
const space = this.getAttribute( 'space' );
|
|
423
|
+
node = space === 'world' ? tangentWorld : tangentLocal;
|
|
424
|
+
|
|
425
|
+
} else if ( element === 'texcoord' ) {
|
|
426
|
+
|
|
427
|
+
const indexNode = this.getChildByName( 'index' );
|
|
428
|
+
const index = indexNode ? parseInt( indexNode.value ) : 0;
|
|
429
|
+
|
|
430
|
+
node = uv( index );
|
|
431
|
+
|
|
432
|
+
} else if ( element === 'geomcolor' ) {
|
|
433
|
+
|
|
434
|
+
const indexNode = this.getChildByName( 'index' );
|
|
435
|
+
const index = indexNode ? parseInt( indexNode.value ) : 0;
|
|
436
|
+
|
|
437
|
+
node = vertexColor( index );
|
|
380
438
|
|
|
381
439
|
} else if ( element === 'tiledimage' ) {
|
|
382
440
|
|
|
@@ -597,7 +655,7 @@ class MaterialXNode {
|
|
|
597
655
|
let emissiveNode = null;
|
|
598
656
|
|
|
599
657
|
if ( inputs.emission ) emissiveNode = inputs.emission;
|
|
600
|
-
if ( inputs.emissionColor )
|
|
658
|
+
if ( inputs.emissionColor ) {
|
|
601
659
|
|
|
602
660
|
emissiveNode = emissiveNode ? mul( emissiveNode, inputs.emissionColor ) : emissiveNode;
|
|
603
661
|
|
|
@@ -639,7 +697,28 @@ class MaterialXNode {
|
|
|
639
697
|
|
|
640
698
|
}
|
|
641
699
|
|
|
642
|
-
|
|
700
|
+
toBasicMaterial() {
|
|
701
|
+
|
|
702
|
+
const material = new MeshBasicNodeMaterial();
|
|
703
|
+
material.name = this.name;
|
|
704
|
+
|
|
705
|
+
for ( const nodeX of this.children.toReversed() ) {
|
|
706
|
+
|
|
707
|
+
if ( nodeX.name === 'out' ) {
|
|
708
|
+
|
|
709
|
+
material.colorNode = nodeX.getNode();
|
|
710
|
+
|
|
711
|
+
break;
|
|
712
|
+
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
return material;
|
|
718
|
+
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
toPhysicalMaterial() {
|
|
643
722
|
|
|
644
723
|
const material = new MeshPhysicalNodeMaterial();
|
|
645
724
|
material.name = this.name;
|
|
@@ -659,14 +738,34 @@ class MaterialXNode {
|
|
|
659
738
|
|
|
660
739
|
const materials = {};
|
|
661
740
|
|
|
741
|
+
let isUnlit = true;
|
|
742
|
+
|
|
662
743
|
for ( const nodeX of this.children ) {
|
|
663
744
|
|
|
664
745
|
if ( nodeX.element === 'surfacematerial' ) {
|
|
665
746
|
|
|
666
|
-
const material = nodeX.
|
|
747
|
+
const material = nodeX.toPhysicalMaterial();
|
|
667
748
|
|
|
668
749
|
materials[ material.name ] = material;
|
|
669
750
|
|
|
751
|
+
isUnlit = false;
|
|
752
|
+
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
if ( isUnlit ) {
|
|
758
|
+
|
|
759
|
+
for ( const nodeX of this.children ) {
|
|
760
|
+
|
|
761
|
+
if ( nodeX.element === 'nodegraph' ) {
|
|
762
|
+
|
|
763
|
+
const material = nodeX.toBasicMaterial();
|
|
764
|
+
|
|
765
|
+
materials[ material.name ] = material;
|
|
766
|
+
|
|
767
|
+
}
|
|
768
|
+
|
|
670
769
|
}
|
|
671
770
|
|
|
672
771
|
}
|
|
@@ -2924,8 +2924,8 @@ class SVGLoader extends Loader {
|
|
|
2924
2924
|
addVertex( currentPointL, u1, 0 );
|
|
2925
2925
|
|
|
2926
2926
|
addVertex( lastPointR, u0, 1 );
|
|
2927
|
-
addVertex( currentPointL, u1,
|
|
2928
|
-
addVertex( currentPointR, u1,
|
|
2927
|
+
addVertex( currentPointL, u1, 0 );
|
|
2928
|
+
addVertex( currentPointR, u1, 1 );
|
|
2929
2929
|
|
|
2930
2930
|
}
|
|
2931
2931
|
|
|
@@ -3082,7 +3082,8 @@ class SVGLoader extends Loader {
|
|
|
3082
3082
|
} else {
|
|
3083
3083
|
|
|
3084
3084
|
tempV2_3.toArray( vertices, 1 * 3 );
|
|
3085
|
-
|
|
3085
|
+
// using tempV2_4 to update 3rd vertex if the uv.y of 3rd vertex is 1
|
|
3086
|
+
uvs[ 3 * 2 + 1 ] === 1 ? tempV2_4.toArray( vertices, 3 * 3 ) : tempV2_3.toArray( vertices, 3 * 3 );
|
|
3086
3087
|
tempV2_4.toArray( vertices, 0 * 3 );
|
|
3087
3088
|
|
|
3088
3089
|
}
|
|
@@ -126,7 +126,7 @@ class VRMLLoader extends Loader {
|
|
|
126
126
|
// from http://gun.teipir.gr/VRML-amgem/spec/part1/concepts.html#SyntaxBasics
|
|
127
127
|
|
|
128
128
|
const RouteIdentifier = createToken( { name: 'RouteIdentifier', pattern: /[^\x30-\x39\0-\x20\x22\x27\x23\x2b\x2c\x2d\x2e\x5b\x5d\x5c\x7b\x7d][^\0-\x20\x22\x27\x23\x2b\x2c\x2d\x2e\x5b\x5d\x5c\x7b\x7d]*[\.][^\x30-\x39\0-\x20\x22\x27\x23\x2b\x2c\x2d\x2e\x5b\x5d\x5c\x7b\x7d][^\0-\x20\x22\x27\x23\x2b\x2c\x2d\x2e\x5b\x5d\x5c\x7b\x7d]*/ } );
|
|
129
|
-
const Identifier = createToken( { name: 'Identifier', pattern: /[^\x30-\x39\0-\x20\x22\x27\x23\x2b\x2c\x2d\x2e\x5b\x5d\x5c\x7b\x7d][^\0-\x20\x22\x27\x23\x2b\x2c\
|
|
129
|
+
const Identifier = createToken( { name: 'Identifier', pattern: /[^\x30-\x39\0-\x20\x22\x27\x23\x2b\x2c\x2d\x2e\x5b\x5d\x5c\x7b\x7d]([^\0-\x20\x22\x27\x23\x2b\x2c\x2e\x5b\x5d\x5c\x7b\x7d])*/, longer_alt: RouteIdentifier } );
|
|
130
130
|
|
|
131
131
|
// from http://gun.teipir.gr/VRML-amgem/spec/part1/nodesRef.html
|
|
132
132
|
|