super-three 0.169.1 → 0.170.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 +974 -562
- package/build/three.module.js +975 -559
- package/build/three.module.min.js +1 -1
- package/build/three.webgpu.js +8398 -9842
- package/build/three.webgpu.min.js +1 -1
- package/build/three.webgpu.nodes.js +8398 -9842
- package/build/three.webgpu.nodes.min.js +1 -1
- package/examples/jsm/Addons.js +3 -3
- package/examples/jsm/animation/MMDAnimationHelper.js +2 -0
- package/examples/jsm/animation/MMDPhysics.js +2 -0
- package/examples/jsm/controls/TransformControls.js +22 -6
- package/examples/jsm/csm/CSM.js +2 -2
- package/examples/jsm/csm/CSMFrustum.js +7 -4
- package/examples/jsm/csm/CSMHelper.js +2 -0
- package/examples/jsm/csm/CSMShadowNode.js +435 -0
- package/examples/jsm/curves/NURBSCurve.js +34 -3
- package/examples/jsm/exporters/GLTFExporter.js +138 -71
- package/examples/jsm/exporters/KTX2Exporter.js +35 -12
- package/examples/jsm/exporters/MMDExporter.js +6 -0
- package/examples/jsm/exporters/USDZExporter.js +21 -3
- package/examples/jsm/geometries/DecalGeometry.js +65 -20
- package/examples/jsm/geometries/InstancedPointsGeometry.js +2 -0
- package/examples/jsm/helpers/TextureHelperGPU.js +175 -0
- package/examples/jsm/interactive/HTMLMesh.js +1 -0
- package/examples/jsm/lighting/TiledLighting.js +18 -0
- package/examples/jsm/lights/RectAreaLightTexturesLib.js +1 -1
- package/examples/jsm/lines/LineMaterial.js +7 -2
- package/examples/jsm/lines/LineSegmentsGeometry.js +2 -0
- package/examples/jsm/lines/webgpu/LineSegments2.js +0 -15
- package/examples/jsm/lines/webgpu/Wireframe.js +56 -0
- package/examples/jsm/loaders/3DMLoader.js +1 -0
- package/examples/jsm/loaders/3MFLoader.js +91 -0
- package/examples/jsm/loaders/FBXLoader.js +12 -2
- package/examples/jsm/loaders/GLTFLoader.js +2 -0
- package/examples/jsm/loaders/KTX2Loader.js +140 -49
- package/examples/jsm/loaders/LDrawLoader.js +22 -136
- package/examples/jsm/loaders/LottieLoader.js +1 -0
- package/examples/jsm/loaders/MMDLoader.js +9 -2
- package/examples/jsm/materials/LDrawConditionalLineMaterial.js +143 -0
- package/examples/jsm/materials/LDrawConditionalLineNodeMaterial.js +114 -0
- package/examples/jsm/materials/MeshGouraudMaterial.js +6 -2
- package/examples/jsm/math/ColorSpaces.js +76 -0
- package/examples/jsm/misc/ProgressiveLightMap.js +52 -40
- package/examples/jsm/misc/ProgressiveLightMapGPU.js +293 -0
- package/examples/jsm/misc/VolumeSlice.js +1 -0
- package/examples/jsm/objects/WaterMesh.js +8 -8
- package/examples/jsm/postprocessing/AfterimagePass.js +14 -3
- package/examples/jsm/postprocessing/SSRPass.js +6 -0
- package/examples/jsm/renderers/CSS2DRenderer.js +6 -3
- package/examples/jsm/renderers/CSS3DRenderer.js +7 -4
- package/examples/jsm/shaders/FXAAShader.js +225 -224
- package/examples/jsm/transpiler/ShaderToyDecoder.js +1 -1
- package/{src/nodes → examples/jsm/tsl}/display/AfterImageNode.js +17 -20
- package/{src/nodes → examples/jsm/tsl}/display/AnaglyphPassNode.js +2 -6
- package/{src/nodes → examples/jsm/tsl}/display/AnamorphicNode.js +12 -18
- package/{src/nodes → examples/jsm/tsl}/display/BleachBypass.js +1 -3
- package/{src/nodes → examples/jsm/tsl}/display/BloomNode.js +11 -40
- package/{src/nodes → examples/jsm/tsl}/display/DenoiseNode.js +18 -41
- package/{src/nodes → examples/jsm/tsl}/display/DepthOfFieldNode.js +2 -8
- package/{src/nodes → examples/jsm/tsl}/display/DotScreenNode.js +2 -9
- package/examples/jsm/tsl/display/FXAANode.js +316 -0
- package/{src/nodes → examples/jsm/tsl}/display/FilmNode.js +2 -6
- package/{src/nodes → examples/jsm/tsl}/display/GTAONode.js +30 -70
- package/{src/nodes → examples/jsm/tsl}/display/GaussianBlurNode.js +74 -36
- package/examples/jsm/tsl/display/LensflareNode.js +161 -0
- package/{src/nodes → examples/jsm/tsl}/display/Lut3DNode.js +1 -4
- package/{src/nodes → examples/jsm/tsl}/display/MotionBlur.js +2 -3
- package/examples/jsm/tsl/display/OutlineNode.js +434 -0
- package/{src/nodes → examples/jsm/tsl}/display/ParallaxBarrierPassNode.js +1 -5
- package/{src/nodes → examples/jsm/tsl}/display/PixelationPassNode.js +3 -15
- package/{src/nodes → examples/jsm/tsl}/display/RGBShiftNode.js +1 -6
- package/examples/jsm/tsl/display/SMAANode.js +620 -0
- package/{src/nodes → examples/jsm/tsl}/display/SSAAPassNode.js +10 -25
- package/examples/jsm/tsl/display/SSRNode.js +343 -0
- package/{src/nodes → examples/jsm/tsl}/display/Sepia.js +1 -2
- package/{src/nodes → examples/jsm/tsl}/display/SobelOperatorNode.js +3 -11
- package/{src/nodes → examples/jsm/tsl}/display/StereoCompositePassNode.js +9 -11
- package/{src/nodes → examples/jsm/tsl}/display/StereoPassNode.js +10 -11
- package/examples/jsm/tsl/display/TRAAPassNode.js +355 -0
- package/{src/nodes → examples/jsm/tsl}/display/TransitionNode.js +1 -6
- package/examples/jsm/tsl/display/hashBlur.js +24 -0
- package/examples/jsm/tsl/lighting/TiledLightsNode.js +392 -0
- package/examples/jsm/utils/{TextureUtilsGPU.js → WebGPUTextureUtils.js} +2 -1
- package/examples/jsm/webxr/OculusHandPointerModel.js +21 -21
- package/examples/jsm/webxr/Text2D.js +6 -6
- package/package.json +2 -2
- package/src/Three.WebGPU.Nodes.js +4 -0
- package/src/Three.WebGPU.js +4 -0
- package/src/constants.js +1 -6
- package/src/core/BufferGeometry.js +44 -6
- package/src/geometries/CylinderGeometry.js +2 -2
- package/src/materials/LineBasicMaterial.js +6 -2
- package/src/materials/LineDashedMaterial.js +6 -2
- package/src/materials/Material.js +14 -1
- package/src/materials/MeshBasicMaterial.js +6 -2
- package/src/materials/MeshDepthMaterial.js +6 -2
- package/src/materials/MeshDistanceMaterial.js +6 -2
- package/src/materials/MeshLambertMaterial.js +6 -2
- package/src/materials/MeshMatcapMaterial.js +6 -2
- package/src/materials/MeshNormalMaterial.js +6 -2
- package/src/materials/MeshPhongMaterial.js +6 -2
- package/src/materials/MeshPhysicalMaterial.js +6 -2
- package/src/materials/MeshStandardMaterial.js +6 -2
- package/src/materials/MeshToonMaterial.js +6 -2
- package/src/materials/PointsMaterial.js +6 -2
- package/src/materials/RawShaderMaterial.js +6 -2
- package/src/materials/ShaderMaterial.js +6 -2
- package/src/materials/ShadowMaterial.js +6 -2
- package/src/materials/SpriteMaterial.js +6 -2
- package/src/materials/nodes/NodeMaterial.js +31 -9
- package/src/materials/nodes/SpriteNodeMaterial.js +11 -2
- package/src/materials/nodes/manager/NodeMaterialObserver.js +111 -2
- package/src/math/ColorManagement.js +118 -85
- package/src/math/Vector4.js +11 -0
- package/src/nodes/Nodes.js +1 -21
- package/src/nodes/TSL.js +6 -24
- package/src/nodes/accessors/Camera.js +0 -1
- package/src/nodes/accessors/SceneNode.js +35 -1
- package/src/nodes/accessors/StorageBufferNode.js +32 -10
- package/src/nodes/accessors/VelocityNode.js +13 -3
- package/src/nodes/code/FunctionCallNode.js +16 -5
- package/src/nodes/code/ScriptableNode.js +4 -4
- package/src/nodes/core/Node.js +1 -0
- package/src/nodes/core/NodeBuilder.js +29 -5
- package/src/nodes/core/VarNode.js +15 -3
- package/src/nodes/display/ColorAdjustment.js +53 -4
- package/src/nodes/display/ColorSpaceFunctions.js +5 -5
- package/src/nodes/display/ColorSpaceNode.js +27 -39
- package/src/nodes/display/PassNode.js +6 -4
- package/src/nodes/display/ToneMappingNode.js +1 -1
- package/src/nodes/display/ViewportDepthNode.js +33 -1
- package/src/nodes/functions/PhysicalLightingModel.js +21 -15
- package/src/nodes/functions/material/getAlphaHashThreshold.js +64 -0
- package/src/nodes/functions/material/getGeometryRoughness.js +8 -2
- package/src/nodes/functions/material/getParallaxCorrectNormal.js +22 -0
- package/src/nodes/gpgpu/ComputeNode.js +9 -1
- package/src/nodes/lighting/AnalyticLightNode.js +12 -416
- package/src/nodes/lighting/LightsNode.js +24 -12
- package/src/nodes/lighting/PointLightNode.js +36 -26
- package/src/nodes/lighting/RectAreaLightNode.js +3 -0
- package/src/nodes/lighting/ShadowNode.js +484 -0
- package/src/nodes/utils/LoopNode.js +2 -2
- package/src/nodes/utils/Oscillators.js +6 -0
- package/src/nodes/utils/PostProcessingUtils.js +89 -0
- package/src/nodes/utils/ReflectorNode.js +101 -15
- package/src/nodes/utils/Timer.js +29 -0
- package/src/objects/BatchedMesh.js +458 -241
- package/src/renderers/WebGLRenderer.js +120 -117
- package/src/renderers/common/Attributes.js +4 -0
- package/src/renderers/common/Backend.js +2 -0
- package/src/renderers/common/Background.js +14 -4
- package/src/renderers/common/Bindings.js +3 -2
- package/src/renderers/common/Constants.js +2 -1
- package/src/renderers/common/Geometries.js +20 -0
- package/src/renderers/common/IndirectStorageBufferAttribute.js +15 -0
- package/src/renderers/common/Lighting.js +45 -0
- package/src/renderers/common/PostProcessingUtils.js +86 -0
- package/src/renderers/common/RenderList.js +39 -11
- package/src/renderers/common/RenderLists.js +4 -2
- package/src/renderers/common/RenderObject.js +18 -1
- package/src/renderers/common/Renderer.js +165 -26
- package/src/renderers/common/Textures.js +30 -14
- package/src/renderers/common/nodes/NodeLibrary.js +1 -14
- package/src/renderers/common/nodes/Nodes.js +2 -2
- package/src/renderers/shaders/ShaderChunk/colorspace_pars_fragment.glsl.js +4 -24
- package/src/renderers/shaders/ShaderChunk/emissivemap_fragment.glsl.js +8 -0
- package/src/renderers/shaders/ShaderChunk/map_fragment.glsl.js +2 -2
- package/src/renderers/webgl/WebGLBufferRenderer.js +2 -6
- package/src/renderers/webgl/WebGLCapabilities.js +0 -7
- package/src/renderers/webgl/WebGLIndexedBufferRenderer.js +2 -6
- package/src/renderers/webgl/WebGLProgram.js +24 -28
- package/src/renderers/webgl/WebGLPrograms.js +5 -2
- package/src/renderers/webgl/WebGLState.js +37 -1
- package/src/renderers/webgl/WebGLTextures.js +29 -12
- package/src/renderers/webgl-fallback/WebGLBackend.js +98 -31
- package/src/renderers/webgl-fallback/WebGLBufferRenderer.js +2 -7
- package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +33 -8
- package/src/renderers/webgpu/WebGPUBackend.js +105 -25
- package/src/renderers/webgpu/WebGPURenderer.Nodes.js +1 -1
- package/src/renderers/webgpu/WebGPURenderer.js +1 -1
- package/src/renderers/webgpu/nodes/BasicNodeLibrary.js +0 -8
- package/src/renderers/webgpu/nodes/StandardNodeLibrary.js +0 -8
- package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +10 -20
- package/src/renderers/webgpu/nodes/WGSLNodeFunction.js +12 -4
- package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +29 -9
- package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +24 -6
- package/src/renderers/webgpu/utils/WebGPUUtils.js +0 -1
- package/src/renderers/webxr/WebXRManager.js +4 -4
- package/examples/jsm/cameras/CinematicCamera.js +0 -208
- package/src/nodes/display/FXAANode.js +0 -332
- package/src/nodes/utils/OscNode.js +0 -85
- package/src/nodes/utils/TimerNode.js +0 -97
- /package/examples/jsm/utils/{TextureUtils.js → WebGLTextureUtils.js} +0 -0
|
@@ -23,6 +23,8 @@ class VelocityNode extends TempNode {
|
|
|
23
23
|
|
|
24
24
|
super( 'vec2' );
|
|
25
25
|
|
|
26
|
+
this.projectionMatrix = null;
|
|
27
|
+
|
|
26
28
|
this.updateType = NodeUpdateType.OBJECT;
|
|
27
29
|
this.updateAfterType = NodeUpdateType.OBJECT;
|
|
28
30
|
|
|
@@ -32,6 +34,12 @@ class VelocityNode extends TempNode {
|
|
|
32
34
|
|
|
33
35
|
}
|
|
34
36
|
|
|
37
|
+
setProjectionMatrix( projectionMatrix ) {
|
|
38
|
+
|
|
39
|
+
this.projectionMatrix = projectionMatrix;
|
|
40
|
+
|
|
41
|
+
}
|
|
42
|
+
|
|
35
43
|
update( { frameId, camera, object } ) {
|
|
36
44
|
|
|
37
45
|
const previousModelMatrix = getPreviousMatrix( object );
|
|
@@ -54,7 +62,7 @@ class VelocityNode extends TempNode {
|
|
|
54
62
|
cameraData.currentProjectionMatrix = new Matrix4();
|
|
55
63
|
cameraData.currentCameraViewMatrix = new Matrix4();
|
|
56
64
|
|
|
57
|
-
cameraData.previousProjectionMatrix.copy( camera.projectionMatrix );
|
|
65
|
+
cameraData.previousProjectionMatrix.copy( this.projectionMatrix || camera.projectionMatrix );
|
|
58
66
|
cameraData.previousCameraViewMatrix.copy( camera.matrixWorldInverse );
|
|
59
67
|
|
|
60
68
|
} else {
|
|
@@ -64,7 +72,7 @@ class VelocityNode extends TempNode {
|
|
|
64
72
|
|
|
65
73
|
}
|
|
66
74
|
|
|
67
|
-
cameraData.currentProjectionMatrix.copy( camera.projectionMatrix );
|
|
75
|
+
cameraData.currentProjectionMatrix.copy( this.projectionMatrix || camera.projectionMatrix );
|
|
68
76
|
cameraData.currentCameraViewMatrix.copy( camera.matrixWorldInverse );
|
|
69
77
|
|
|
70
78
|
this.previousProjectionMatrix.value.copy( cameraData.previousProjectionMatrix );
|
|
@@ -82,9 +90,11 @@ class VelocityNode extends TempNode {
|
|
|
82
90
|
|
|
83
91
|
setup( /*builder*/ ) {
|
|
84
92
|
|
|
93
|
+
const projectionMatrix = ( this.projectionMatrix === null ) ? cameraProjectionMatrix : uniform( this.projectionMatrix );
|
|
94
|
+
|
|
85
95
|
const previousModelViewMatrix = this.previousCameraViewMatrix.mul( this.previousModelWorldMatrix );
|
|
86
96
|
|
|
87
|
-
const clipPositionCurrent =
|
|
97
|
+
const clipPositionCurrent = projectionMatrix.mul( modelViewMatrix ).mul( positionLocal );
|
|
88
98
|
const clipPositionPrevious = this.previousProjectionMatrix.mul( previousModelViewMatrix ).mul( positionPrevious );
|
|
89
99
|
|
|
90
100
|
const ndcPositionCurrent = clipPositionCurrent.xy.div( clipPositionCurrent.w );
|
|
@@ -47,14 +47,25 @@ class FunctionCallNode extends TempNode {
|
|
|
47
47
|
const inputs = functionNode.getInputs( builder );
|
|
48
48
|
const parameters = this.parameters;
|
|
49
49
|
|
|
50
|
+
const generateInput = ( node, inputNode ) => {
|
|
51
|
+
|
|
52
|
+
const type = inputNode.type;
|
|
53
|
+
const pointer = type === 'pointer';
|
|
54
|
+
|
|
55
|
+
let output;
|
|
56
|
+
|
|
57
|
+
if ( pointer ) output = '&' + node.build( builder );
|
|
58
|
+
else output = node.build( builder, type );
|
|
59
|
+
|
|
60
|
+
return output;
|
|
61
|
+
|
|
62
|
+
};
|
|
63
|
+
|
|
50
64
|
if ( Array.isArray( parameters ) ) {
|
|
51
65
|
|
|
52
66
|
for ( let i = 0; i < parameters.length; i ++ ) {
|
|
53
67
|
|
|
54
|
-
|
|
55
|
-
const node = parameters[ i ];
|
|
56
|
-
|
|
57
|
-
params.push( node.build( builder, inputNode.type ) );
|
|
68
|
+
params.push( generateInput( parameters[ i ], inputs[ i ] ) );
|
|
58
69
|
|
|
59
70
|
}
|
|
60
71
|
|
|
@@ -66,7 +77,7 @@ class FunctionCallNode extends TempNode {
|
|
|
66
77
|
|
|
67
78
|
if ( node !== undefined ) {
|
|
68
79
|
|
|
69
|
-
params.push(
|
|
80
|
+
params.push( generateInput( node, inputNode ) );
|
|
70
81
|
|
|
71
82
|
} else {
|
|
72
83
|
|
|
@@ -58,7 +58,7 @@ class Parameters {
|
|
|
58
58
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
export const
|
|
61
|
+
export const ScriptableNodeResources = new Resources();
|
|
62
62
|
|
|
63
63
|
class ScriptableNode extends Node {
|
|
64
64
|
|
|
@@ -299,11 +299,11 @@ class ScriptableNode extends Node {
|
|
|
299
299
|
|
|
300
300
|
const parameters = new Parameters( this );
|
|
301
301
|
|
|
302
|
-
const THREE =
|
|
303
|
-
const TSL =
|
|
302
|
+
const THREE = ScriptableNodeResources.get( 'THREE' );
|
|
303
|
+
const TSL = ScriptableNodeResources.get( 'TSL' );
|
|
304
304
|
|
|
305
305
|
const method = this.getMethod( this.codeNode );
|
|
306
|
-
const params = [ parameters, this._local,
|
|
306
|
+
const params = [ parameters, this._local, ScriptableNodeResources, refresh, setOutput, THREE, TSL ];
|
|
307
307
|
|
|
308
308
|
this._object = method( ...params );
|
|
309
309
|
|
package/src/nodes/core/Node.js
CHANGED
|
@@ -55,9 +55,17 @@ const typeFromArray = new Map( [
|
|
|
55
55
|
|
|
56
56
|
const toFloat = ( value ) => {
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
if ( /e/g.test( value ) ) {
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
return String( value ).replace( /\+/g, '' );
|
|
61
|
+
|
|
62
|
+
} else {
|
|
63
|
+
|
|
64
|
+
value = Number( value );
|
|
65
|
+
|
|
66
|
+
return value + ( value % 1 ? '' : '.0' );
|
|
67
|
+
|
|
68
|
+
}
|
|
61
69
|
|
|
62
70
|
};
|
|
63
71
|
|
|
@@ -74,6 +82,7 @@ class NodeBuilder {
|
|
|
74
82
|
this.camera = null;
|
|
75
83
|
|
|
76
84
|
this.nodes = [];
|
|
85
|
+
this.sequentialNodes = [];
|
|
77
86
|
this.updateNodes = [];
|
|
78
87
|
this.updateBeforeNodes = [];
|
|
79
88
|
this.updateAfterNodes = [];
|
|
@@ -312,13 +321,21 @@ class NodeBuilder {
|
|
|
312
321
|
|
|
313
322
|
}
|
|
314
323
|
|
|
324
|
+
addSequentialNode( node ) {
|
|
325
|
+
|
|
326
|
+
if ( this.sequentialNodes.includes( node ) === false ) {
|
|
327
|
+
|
|
328
|
+
this.sequentialNodes.push( node );
|
|
329
|
+
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
}
|
|
333
|
+
|
|
315
334
|
buildUpdateNodes() {
|
|
316
335
|
|
|
317
336
|
for ( const node of this.nodes ) {
|
|
318
337
|
|
|
319
338
|
const updateType = node.getUpdateType();
|
|
320
|
-
const updateBeforeType = node.getUpdateBeforeType();
|
|
321
|
-
const updateAfterType = node.getUpdateAfterType();
|
|
322
339
|
|
|
323
340
|
if ( updateType !== NodeUpdateType.NONE ) {
|
|
324
341
|
|
|
@@ -326,6 +343,13 @@ class NodeBuilder {
|
|
|
326
343
|
|
|
327
344
|
}
|
|
328
345
|
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
for ( const node of this.sequentialNodes ) {
|
|
349
|
+
|
|
350
|
+
const updateBeforeType = node.getUpdateBeforeType();
|
|
351
|
+
const updateAfterType = node.getUpdateAfterType();
|
|
352
|
+
|
|
329
353
|
if ( updateBeforeType !== NodeUpdateType.NONE ) {
|
|
330
354
|
|
|
331
355
|
this.updateBeforeNodes.push( node.getSelf() );
|
|
@@ -1300,7 +1324,7 @@ class NodeBuilder {
|
|
|
1300
1324
|
|
|
1301
1325
|
if ( material !== null ) {
|
|
1302
1326
|
|
|
1303
|
-
let nodeMaterial = renderer.
|
|
1327
|
+
let nodeMaterial = renderer.library.fromMaterial( material );
|
|
1304
1328
|
|
|
1305
1329
|
if ( nodeMaterial === null ) {
|
|
1306
1330
|
|
|
@@ -54,7 +54,19 @@ class VarNode extends Node {
|
|
|
54
54
|
|
|
55
55
|
export default VarNode;
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
const createVar = /*@__PURE__*/ nodeProxy( VarNode );
|
|
58
|
+
|
|
59
|
+
addMethodChaining( 'toVar', ( ...params ) => createVar( ...params ).append() );
|
|
60
|
+
|
|
61
|
+
// Deprecated
|
|
62
|
+
|
|
63
|
+
export const temp = ( node ) => { // @deprecated, r170
|
|
64
|
+
|
|
65
|
+
console.warn( 'TSL: "temp" is deprecated. Use ".toVar()" instead.' );
|
|
66
|
+
|
|
67
|
+
return createVar( node );
|
|
68
|
+
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
addMethodChaining( 'temp', temp );
|
|
58
72
|
|
|
59
|
-
addMethodChaining( 'temp', temp ); // @TODO: Will be removed in the future
|
|
60
|
-
addMethodChaining( 'toVar', ( ...params ) => temp( ...params ).append() );
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { dot, mix } from '../math/MathNode.js';
|
|
1
|
+
import { dot, max, mix } from '../math/MathNode.js';
|
|
2
2
|
import { add } from '../math/OperatorNode.js';
|
|
3
|
-
import { Fn, float, vec3 } from '../tsl/TSLBase.js';
|
|
3
|
+
import { Fn, If, float, vec3, vec4 } from '../tsl/TSLBase.js';
|
|
4
4
|
import { ColorManagement } from '../../math/ColorManagement.js';
|
|
5
5
|
import { Vector3 } from '../../math/Vector3.js';
|
|
6
|
+
import { LinearSRGBColorSpace } from '../../constants.js';
|
|
6
7
|
|
|
7
8
|
export const grayscale = /*@__PURE__*/ Fn( ( [ color ] ) => {
|
|
8
9
|
|
|
@@ -37,10 +38,58 @@ export const hue = /*@__PURE__*/ Fn( ( [ color, adjustment = float( 1 ) ] ) => {
|
|
|
37
38
|
|
|
38
39
|
} );
|
|
39
40
|
|
|
40
|
-
const _luminanceCoefficients = /*@__PURE__*/ new Vector3();
|
|
41
41
|
export const luminance = (
|
|
42
42
|
color,
|
|
43
|
-
luminanceCoefficients = vec3(
|
|
43
|
+
luminanceCoefficients = vec3( ColorManagement.getLuminanceCoefficients( new Vector3() ) )
|
|
44
44
|
) => dot( color, luminanceCoefficients );
|
|
45
45
|
|
|
46
46
|
export const threshold = ( color, threshold ) => mix( vec3( 0.0 ), color, luminance( color ).sub( threshold ).max( 0 ) );
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Color Decision List (CDL) v1.2
|
|
50
|
+
*
|
|
51
|
+
* Compact representation of color grading information, defined by slope, offset, power, and
|
|
52
|
+
* saturation. The CDL should be typically be given input in a log space (such as LogC, ACEScc,
|
|
53
|
+
* or AgX Log), and will return output in the same space. Output may require clamping >=0.
|
|
54
|
+
*
|
|
55
|
+
* @param {vec4} color Input (-Infinity < input < +Infinity)
|
|
56
|
+
* @param {number | vec3} slope Slope (0 ≤ slope < +Infinity)
|
|
57
|
+
* @param {number | vec3} offset Offset (-Infinity < offset < +Infinity; typically -1 < offset < 1)
|
|
58
|
+
* @param {number | vec3} power Power (0 < power < +Infinity)
|
|
59
|
+
* @param {number} saturation Saturation (0 ≤ saturation < +Infinity; typically 0 ≤ saturation < 4)
|
|
60
|
+
* @param {vec3} luminanceCoefficients Luminance coefficients for saturation term, typically Rec. 709
|
|
61
|
+
* @return Output, -Infinity < output < +Infinity
|
|
62
|
+
*
|
|
63
|
+
* References:
|
|
64
|
+
* - ASC CDL v1.2
|
|
65
|
+
* - https://blender.stackexchange.com/a/55239/43930
|
|
66
|
+
* - https://docs.acescentral.com/specifications/acescc/
|
|
67
|
+
*/
|
|
68
|
+
export const cdl = /*@__PURE__*/ Fn( ( [
|
|
69
|
+
color,
|
|
70
|
+
slope = vec3( 1 ),
|
|
71
|
+
offset = vec3( 0 ),
|
|
72
|
+
power = vec3( 1 ),
|
|
73
|
+
saturation = float( 1 ),
|
|
74
|
+
// ASC CDL v1.2 explicitly requires Rec. 709 luminance coefficients.
|
|
75
|
+
luminanceCoefficients = vec3( ColorManagement.getLuminanceCoefficients( new Vector3(), LinearSRGBColorSpace ) )
|
|
76
|
+
] ) => {
|
|
77
|
+
|
|
78
|
+
// NOTE: The ASC CDL v1.2 defines a [0, 1] clamp on the slope+offset term, and another on the
|
|
79
|
+
// saturation term. Per the ACEScc specification and Filament, limits may be omitted to support
|
|
80
|
+
// values outside [0, 1], requiring a workaround for negative values in the power expression.
|
|
81
|
+
|
|
82
|
+
const luma = color.rgb.dot( vec3( luminanceCoefficients ) );
|
|
83
|
+
|
|
84
|
+
const v = max( color.rgb.mul( slope ).add( offset ), 0.0 ).toVar();
|
|
85
|
+
const pv = v.pow( power ).toVar();
|
|
86
|
+
|
|
87
|
+
If( v.r.greaterThan( 0.0 ), () => { v.r.assign( pv.r ); } ); // eslint-disable-line
|
|
88
|
+
If( v.g.greaterThan( 0.0 ), () => { v.g.assign( pv.g ); } ); // eslint-disable-line
|
|
89
|
+
If( v.b.greaterThan( 0.0 ), () => { v.b.assign( pv.b ); } ); // eslint-disable-line
|
|
90
|
+
|
|
91
|
+
v.assign( luma.add( v.sub( luma ).mul( saturation ) ) );
|
|
92
|
+
|
|
93
|
+
return vec4( v.rgb, color.a );
|
|
94
|
+
|
|
95
|
+
} );
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { mix } from '../math/MathNode.js';
|
|
2
|
-
import { Fn } from '../tsl/
|
|
2
|
+
import { Fn } from '../tsl/TSLCore.js';
|
|
3
3
|
|
|
4
|
-
export const
|
|
4
|
+
export const sRGBTransferEOTF = /*@__PURE__*/ Fn( ( [ color ] ) => {
|
|
5
5
|
|
|
6
6
|
const a = color.mul( 0.9478672986 ).add( 0.0521327014 ).pow( 2.4 );
|
|
7
7
|
const b = color.mul( 0.0773993808 );
|
|
@@ -12,14 +12,14 @@ export const sRGBToLinearSRGB = /*@__PURE__*/ Fn( ( [ color ] ) => {
|
|
|
12
12
|
return rgbResult;
|
|
13
13
|
|
|
14
14
|
} ).setLayout( {
|
|
15
|
-
name: '
|
|
15
|
+
name: 'sRGBTransferEOTF',
|
|
16
16
|
type: 'vec3',
|
|
17
17
|
inputs: [
|
|
18
18
|
{ name: 'color', type: 'vec3' }
|
|
19
19
|
]
|
|
20
20
|
} );
|
|
21
21
|
|
|
22
|
-
export const
|
|
22
|
+
export const sRGBTransferOETF = /*@__PURE__*/ Fn( ( [ color ] ) => {
|
|
23
23
|
|
|
24
24
|
const a = color.pow( 0.41666 ).mul( 1.055 ).sub( 0.055 );
|
|
25
25
|
const b = color.mul( 12.92 );
|
|
@@ -30,7 +30,7 @@ export const linearSRGBTosRGB = /*@__PURE__*/ Fn( ( [ color ] ) => {
|
|
|
30
30
|
return rgbResult;
|
|
31
31
|
|
|
32
32
|
} ).setLayout( {
|
|
33
|
-
name: '
|
|
33
|
+
name: 'sRGBTransferOETF',
|
|
34
34
|
type: 'vec3',
|
|
35
35
|
inputs: [
|
|
36
36
|
{ name: 'color', type: 'vec3' }
|
|
@@ -1,36 +1,14 @@
|
|
|
1
1
|
import TempNode from '../core/TempNode.js';
|
|
2
|
-
import { addMethodChaining, nodeObject, vec4 } from '../tsl/TSLCore.js';
|
|
2
|
+
import { addMethodChaining, mat3, nodeObject, vec4 } from '../tsl/TSLCore.js';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { SRGBTransfer } from '../../constants.js';
|
|
5
5
|
import { ColorManagement } from '../../math/ColorManagement.js';
|
|
6
|
+
import { sRGBTransferEOTF, sRGBTransferOETF } from './ColorSpaceFunctions.js';
|
|
7
|
+
import { Matrix3 } from '../../math/Matrix3.js';
|
|
6
8
|
|
|
7
9
|
const WORKING_COLOR_SPACE = 'WorkingColorSpace';
|
|
8
10
|
const OUTPUT_COLOR_SPACE = 'OutputColorSpace';
|
|
9
11
|
|
|
10
|
-
function getColorSpaceName( colorSpace ) {
|
|
11
|
-
|
|
12
|
-
let method = null;
|
|
13
|
-
|
|
14
|
-
if ( colorSpace === LinearSRGBColorSpace ) {
|
|
15
|
-
|
|
16
|
-
method = 'Linear';
|
|
17
|
-
|
|
18
|
-
} else if ( colorSpace === SRGBColorSpace ) {
|
|
19
|
-
|
|
20
|
-
method = 'sRGB';
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
return method;
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export function getColorSpaceMethod( source, target ) {
|
|
29
|
-
|
|
30
|
-
return getColorSpaceName( source ) + 'To' + getColorSpaceName( target );
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
|
|
34
12
|
class ColorSpaceNode extends TempNode {
|
|
35
13
|
|
|
36
14
|
static get type() {
|
|
@@ -49,7 +27,7 @@ class ColorSpaceNode extends TempNode {
|
|
|
49
27
|
|
|
50
28
|
}
|
|
51
29
|
|
|
52
|
-
|
|
30
|
+
resolveColorSpace( builder, colorSpace ) {
|
|
53
31
|
|
|
54
32
|
if ( colorSpace === WORKING_COLOR_SPACE ) {
|
|
55
33
|
|
|
@@ -67,29 +45,37 @@ class ColorSpaceNode extends TempNode {
|
|
|
67
45
|
|
|
68
46
|
setup( builder ) {
|
|
69
47
|
|
|
70
|
-
const { renderer } = builder;
|
|
71
48
|
const { colorNode } = this;
|
|
72
49
|
|
|
73
|
-
const source = this.
|
|
74
|
-
const target = this.
|
|
50
|
+
const source = this.resolveColorSpace( builder, this.source );
|
|
51
|
+
const target = this.resolveColorSpace( builder, this.target );
|
|
75
52
|
|
|
76
|
-
|
|
53
|
+
let outputNode = colorNode;
|
|
77
54
|
|
|
78
|
-
|
|
55
|
+
if ( ColorManagement.enabled === false || source === target || ! source || ! target ) {
|
|
79
56
|
|
|
80
|
-
|
|
57
|
+
return outputNode;
|
|
81
58
|
|
|
82
|
-
|
|
59
|
+
}
|
|
83
60
|
|
|
84
|
-
if (
|
|
61
|
+
if ( ColorManagement.getTransfer( source ) === SRGBTransfer ) {
|
|
85
62
|
|
|
86
|
-
outputNode = vec4(
|
|
63
|
+
outputNode = vec4( sRGBTransferEOTF( outputNode.rgb ), outputNode.a );
|
|
87
64
|
|
|
88
|
-
}
|
|
65
|
+
}
|
|
89
66
|
|
|
90
|
-
|
|
67
|
+
if ( ColorManagement.getPrimaries( source ) !== ColorManagement.getPrimaries( target ) ) {
|
|
91
68
|
|
|
92
|
-
outputNode =
|
|
69
|
+
outputNode = vec4(
|
|
70
|
+
mat3( ColorManagement._getMatrix( new Matrix3(), source, target ) ).mul( outputNode.rgb ),
|
|
71
|
+
outputNode.a
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if ( ColorManagement.getTransfer( target ) === SRGBTransfer ) {
|
|
77
|
+
|
|
78
|
+
outputNode = vec4( sRGBTransferOETF( outputNode.rgb ), outputNode.a );
|
|
93
79
|
|
|
94
80
|
}
|
|
95
81
|
|
|
@@ -107,6 +93,8 @@ export const toWorkingColorSpace = ( node ) => nodeObject( new ColorSpaceNode( n
|
|
|
107
93
|
export const workingToColorSpace = ( node, colorSpace ) => nodeObject( new ColorSpaceNode( nodeObject( node ), WORKING_COLOR_SPACE, colorSpace ) );
|
|
108
94
|
export const colorSpaceToWorking = ( node, colorSpace ) => nodeObject( new ColorSpaceNode( nodeObject( node ), colorSpace, WORKING_COLOR_SPACE ) );
|
|
109
95
|
|
|
96
|
+
export const convertColorSpace = ( node, sourceColorSpace, targetColorSpace ) => nodeObject( new ColorSpaceNode( nodeObject( node ), sourceColorSpace, targetColorSpace ) );
|
|
97
|
+
|
|
110
98
|
addMethodChaining( 'toOutputColorSpace', toOutputColorSpace );
|
|
111
99
|
addMethodChaining( 'toWorkingColorSpace', toWorkingColorSpace );
|
|
112
100
|
|
|
@@ -226,8 +226,9 @@ class PassNode extends TempNode {
|
|
|
226
226
|
|
|
227
227
|
if ( textureNode === undefined ) {
|
|
228
228
|
|
|
229
|
-
|
|
230
|
-
|
|
229
|
+
textureNode = nodeObject( new PassMultipleTextureNode( this, name ) );
|
|
230
|
+
textureNode.updateTexture();
|
|
231
|
+
this._textureNodes[ name ] = textureNode;
|
|
231
232
|
|
|
232
233
|
}
|
|
233
234
|
|
|
@@ -243,8 +244,9 @@ class PassNode extends TempNode {
|
|
|
243
244
|
|
|
244
245
|
if ( this._textureNodes[ name ] === undefined ) this.getTextureNode( name );
|
|
245
246
|
|
|
246
|
-
|
|
247
|
-
|
|
247
|
+
textureNode = nodeObject( new PassMultipleTextureNode( this, name, true ) );
|
|
248
|
+
textureNode.updateTexture();
|
|
249
|
+
this._previousTextureNodes[ name ] = textureNode;
|
|
248
250
|
|
|
249
251
|
}
|
|
250
252
|
|
|
@@ -39,7 +39,7 @@ class ToneMappingNode extends TempNode {
|
|
|
39
39
|
|
|
40
40
|
let outputNode = null;
|
|
41
41
|
|
|
42
|
-
const toneMappingFn = builder.renderer.
|
|
42
|
+
const toneMappingFn = builder.renderer.library.getToneMappingFunction( toneMapping );
|
|
43
43
|
|
|
44
44
|
if ( toneMappingFn !== null ) {
|
|
45
45
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Node from '../core/Node.js';
|
|
2
|
-
import { nodeImmutable, nodeProxy } from '../tsl/TSLBase.js';
|
|
2
|
+
import { log2, nodeImmutable, nodeProxy } from '../tsl/TSLBase.js';
|
|
3
3
|
import { cameraNear, cameraFar } from '../accessors/Camera.js';
|
|
4
4
|
import { positionView } from '../accessors/Position.js';
|
|
5
5
|
import { viewportDepthTexture } from './ViewportDepthTextureNode.js';
|
|
@@ -116,6 +116,38 @@ export const viewZToPerspectiveDepth = ( viewZ, near, far ) => near.add( viewZ )
|
|
|
116
116
|
// maps perspective depth in [ 0, 1 ] to viewZ
|
|
117
117
|
export const perspectiveDepthToViewZ = ( depth, near, far ) => near.mul( far ).div( far.sub( near ).mul( depth ).sub( far ) );
|
|
118
118
|
|
|
119
|
+
export const perspectiveDepthToLogarithmicDepth = ( perspectiveW, near, far ) => {
|
|
120
|
+
|
|
121
|
+
// The final logarithmic depth formula used here is adapted from one described in an
|
|
122
|
+
// article by Thatcher Ulrich (see http://tulrich.com/geekstuff/log_depth_buffer.txt),
|
|
123
|
+
// which was an improvement upon an earlier formula one described in an
|
|
124
|
+
// Outerra article (https://outerra.blogspot.com/2009/08/logarithmic-z-buffer.html).
|
|
125
|
+
// Ulrich's formula is the following:
|
|
126
|
+
// z = K * log( w / cameraNear ) / log( cameraFar / cameraNear )
|
|
127
|
+
// where K = 2^k - 1, and k is the number of bits in the depth buffer.
|
|
128
|
+
// The Outerra variant ignored the camera near plane (it assumed it was 0) and instead
|
|
129
|
+
// opted for a "C-constant" for resolution adjustment of objects near the camera.
|
|
130
|
+
// Outerra states: "Notice that the 'C' variant doesn’t use a near plane distance, it has it
|
|
131
|
+
// set at 0" (quote from https://outerra.blogspot.com/2012/11/maximizing-depth-buffer-range-and.html).
|
|
132
|
+
// Ulrich's variant has the benefit of constant relative precision over the whole near-far range.
|
|
133
|
+
// It was debated here whether Outerra's "C-constant" or Ulrich's "near plane" variant should
|
|
134
|
+
// be used, and ultimately Ulrich's "near plane" version was chosen.
|
|
135
|
+
// Outerra eventually made another improvement to their original "C-constant" variant,
|
|
136
|
+
// but it still does not incorporate the camera near plane (for this version,
|
|
137
|
+
// see https://outerra.blogspot.com/2013/07/logarithmic-depth-buffer-optimizations.html).
|
|
138
|
+
// Here we make 4 changes to Ulrich's formula:
|
|
139
|
+
// 1. Clamp the camera near plane so we don't divide by 0.
|
|
140
|
+
// 2. Use log2 instead of log to avoid an extra multiply (shaders implement log using log2).
|
|
141
|
+
// 3. Assume K is 1 (K = maximum value in depth buffer; see Ulrich's formula above).
|
|
142
|
+
// 4. Add 1 to each division by cameraNear to ensure the depth curve is shifted to the left as cameraNear increases.
|
|
143
|
+
// For visual representation of this depth curve, see https://www.desmos.com/calculator/lz5rqfysih
|
|
144
|
+
near = near.max( 1e-6 ).toVar();
|
|
145
|
+
const numerator = log2( perspectiveW.div( near ).add( 1 ) );
|
|
146
|
+
const denominator = log2( far.div( near ).add( 1 ) );
|
|
147
|
+
return numerator.div( denominator );
|
|
148
|
+
|
|
149
|
+
};
|
|
150
|
+
|
|
119
151
|
const depthBase = /*@__PURE__*/ nodeProxy( ViewportDepthNode, ViewportDepthNode.DEPTH_BASE );
|
|
120
152
|
|
|
121
153
|
export const depth = /*@__PURE__*/ nodeImmutable( ViewportDepthNode, ViewportDepthNode.DEPTH );
|
|
@@ -20,6 +20,7 @@ import { screenSize } from '../display/ScreenNode.js';
|
|
|
20
20
|
import { viewportMipTexture } from '../display/ViewportTextureNode.js';
|
|
21
21
|
import { textureBicubic } from '../accessors/TextureBicubic.js';
|
|
22
22
|
import { Loop } from '../utils/LoopNode.js';
|
|
23
|
+
import { BackSide } from '../../constants.js';
|
|
23
24
|
|
|
24
25
|
//
|
|
25
26
|
// Transmission
|
|
@@ -67,14 +68,17 @@ const applyIorToRoughness = /*@__PURE__*/ Fn( ( [ roughness, ior ] ) => {
|
|
|
67
68
|
]
|
|
68
69
|
} );
|
|
69
70
|
|
|
70
|
-
const
|
|
71
|
+
const viewportBackSideTexture = /*@__PURE__*/ viewportMipTexture();
|
|
72
|
+
const viewportFrontSideTexture = /*@__PURE__*/ viewportMipTexture();
|
|
71
73
|
|
|
72
|
-
const getTransmissionSample = /*@__PURE__*/ Fn( ( [ fragCoord, roughness, ior ] ) => {
|
|
74
|
+
const getTransmissionSample = /*@__PURE__*/ Fn( ( [ fragCoord, roughness, ior ], { material } ) => {
|
|
73
75
|
|
|
74
|
-
const
|
|
76
|
+
const vTexture = material.side == BackSide ? viewportBackSideTexture : viewportFrontSideTexture;
|
|
77
|
+
|
|
78
|
+
const transmissionSample = vTexture.uv( fragCoord );
|
|
75
79
|
//const transmissionSample = viewportMipTexture( fragCoord );
|
|
76
80
|
|
|
77
|
-
const lod = log2(
|
|
81
|
+
const lod = log2( screenSize.x ).mul( applyIorToRoughness( roughness, ior ) );
|
|
78
82
|
|
|
79
83
|
return textureBicubic( transmissionSample, lod );
|
|
80
84
|
|
|
@@ -233,15 +237,16 @@ const evalIridescence = /*@__PURE__*/ Fn( ( { outsideIOR, eta2, cosTheta1, thinF
|
|
|
233
237
|
// Force iridescenceIOR -> outsideIOR when thinFilmThickness -> 0.0
|
|
234
238
|
const iridescenceIOR = mix( outsideIOR, eta2, smoothstep( 0.0, 0.03, thinFilmThickness ) );
|
|
235
239
|
// Evaluate the cosTheta on the base layer (Snell law)
|
|
236
|
-
const sinTheta2Sq = outsideIOR.div( iridescenceIOR ).pow2().mul(
|
|
240
|
+
const sinTheta2Sq = outsideIOR.div( iridescenceIOR ).pow2().mul( cosTheta1.pow2().oneMinus() );
|
|
237
241
|
|
|
238
242
|
// Handle TIR:
|
|
239
|
-
const cosTheta2Sq =
|
|
240
|
-
|
|
243
|
+
const cosTheta2Sq = sinTheta2Sq.oneMinus();
|
|
244
|
+
|
|
245
|
+
If( cosTheta2Sq.lessThan( 0 ), () => {
|
|
241
246
|
|
|
242
|
-
|
|
247
|
+
return vec3( 1.0 );
|
|
243
248
|
|
|
244
|
-
}
|
|
249
|
+
} );
|
|
245
250
|
|
|
246
251
|
const cosTheta2 = cosTheta2Sq.sqrt();
|
|
247
252
|
|
|
@@ -274,17 +279,18 @@ const evalIridescence = /*@__PURE__*/ Fn( ( { outsideIOR, eta2, cosTheta1, thinF
|
|
|
274
279
|
|
|
275
280
|
// Reflectance term for m = 0 (DC term amplitude)
|
|
276
281
|
const C0 = R12.add( Rs );
|
|
277
|
-
|
|
282
|
+
const I = C0.toVar();
|
|
278
283
|
|
|
279
284
|
// Reflectance term for m > 0 (pairs of diracs)
|
|
280
|
-
|
|
281
|
-
for ( let m = 1; m <= 2; ++ m ) {
|
|
285
|
+
const Cm = Rs.sub( T121 ).toVar();
|
|
282
286
|
|
|
283
|
-
|
|
287
|
+
Loop( { start: 1, end: 2, condition: '<=', name: 'm' }, ( { m } ) => {
|
|
288
|
+
|
|
289
|
+
Cm.mulAssign( r123 );
|
|
284
290
|
const Sm = evalSensitivity( float( m ).mul( OPD ), float( m ).mul( phi ) ).mul( 2.0 );
|
|
285
|
-
I
|
|
291
|
+
I.addAssign( Cm.mul( Sm ) );
|
|
286
292
|
|
|
287
|
-
}
|
|
293
|
+
} );
|
|
288
294
|
|
|
289
295
|
// Since out of gamut colors might be produced, negative color values are clamped to 0.
|
|
290
296
|
return I.max( vec3( 0.0 ) );
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { abs, add, ceil, clamp, dFdx, dFdy, exp2, float, floor, Fn, fract, length, log2, max, min, mul, sin, sub, vec2, vec3 } from '../../tsl/TSLBase.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* See: https://casual-effects.com/research/Wyman2017Hashed/index.html
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const ALPHA_HASH_SCALE = 0.05; // Derived from trials only, and may be changed.
|
|
8
|
+
|
|
9
|
+
const hash2D = /*@__PURE__*/ Fn( ( [ value ] ) => {
|
|
10
|
+
|
|
11
|
+
return fract( mul( 1.0e4, sin( mul( 17.0, value.x ).add( mul( 0.1, value.y ) ) ) ).mul( add( 0.1, abs( sin( mul( 13.0, value.y ).add( value.x ) ) ) ) ) );
|
|
12
|
+
|
|
13
|
+
} );
|
|
14
|
+
|
|
15
|
+
const hash3D = /*@__PURE__*/ Fn( ( [ value ] ) => {
|
|
16
|
+
|
|
17
|
+
return hash2D( vec2( hash2D( value.xy ), value.z ) );
|
|
18
|
+
|
|
19
|
+
} );
|
|
20
|
+
|
|
21
|
+
const getAlphaHashThreshold = /*@__PURE__*/ Fn( ( [ position ] ) => {
|
|
22
|
+
|
|
23
|
+
// Find the discretized derivatives of our coordinates
|
|
24
|
+
const maxDeriv = max(
|
|
25
|
+
length( dFdx( position.xyz ) ),
|
|
26
|
+
length( dFdy( position.xyz ) )
|
|
27
|
+
).toVar( 'maxDeriv' );
|
|
28
|
+
|
|
29
|
+
const pixScale = float( 1 ).div( float( ALPHA_HASH_SCALE ).mul( maxDeriv ) ).toVar( 'pixScale' );
|
|
30
|
+
|
|
31
|
+
// Find two nearest log-discretized noise scales
|
|
32
|
+
const pixScales = vec2(
|
|
33
|
+
exp2( floor( log2( pixScale ) ) ),
|
|
34
|
+
exp2( ceil( log2( pixScale ) ) )
|
|
35
|
+
).toVar( 'pixScales' );
|
|
36
|
+
|
|
37
|
+
// Compute alpha thresholds at our two noise scales
|
|
38
|
+
const alpha = vec2(
|
|
39
|
+
hash3D( floor( pixScales.x.mul( position.xyz ) ) ),
|
|
40
|
+
hash3D( floor( pixScales.y.mul( position.xyz ) ) ),
|
|
41
|
+
).toVar( 'alpha' );
|
|
42
|
+
|
|
43
|
+
// Factor to interpolate lerp with
|
|
44
|
+
const lerpFactor = fract( log2( pixScale ) ).toVar( 'lerpFactor' );
|
|
45
|
+
|
|
46
|
+
// Interpolate alpha threshold from noise at two scales
|
|
47
|
+
const x = add( mul( lerpFactor.oneMinus(), alpha.x ), mul( lerpFactor, alpha.y ) ).toVar( 'x' );
|
|
48
|
+
|
|
49
|
+
// Pass into CDF to compute uniformly distrib threshold
|
|
50
|
+
const a = min( lerpFactor, lerpFactor.oneMinus() ).toVar( 'a' );
|
|
51
|
+
const cases = vec3(
|
|
52
|
+
x.mul( x ).div( mul( 2.0, a ).mul( sub( 1.0, a ) ) ),
|
|
53
|
+
x.sub( mul( 0.5, a ) ).div( sub( 1.0, a ) ),
|
|
54
|
+
sub( 1.0, sub( 1.0, x ).mul( sub( 1.0, x ) ).div( mul( 2.0, a ).mul( sub( 1.0, a ) ) ) ) ).toVar( 'cases' );
|
|
55
|
+
|
|
56
|
+
// Find our final, uniformly distributed alpha threshold (ατ)
|
|
57
|
+
const threshold = x.lessThan( a.oneMinus() ).select( x.lessThan( a ).select( cases.x, cases.y ), cases.z );
|
|
58
|
+
|
|
59
|
+
// Avoids ατ == 0. Could also do ατ =1-ατ
|
|
60
|
+
return clamp( threshold, 1.0e-6, 1.0 );
|
|
61
|
+
|
|
62
|
+
} );
|
|
63
|
+
|
|
64
|
+
export default getAlphaHashThreshold;
|