@plastic-software/three 0.167.0 → 0.167.2
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 +6 -16
- package/build/three.module.js +6 -21
- package/build/three.module.min.js +1 -1
- package/build/three.webgpu.js +510 -354
- package/build/three.webgpu.min.js +1 -1
- package/examples/jsm/controls/Controls.js +32 -0
- package/examples/jsm/controls/DragControls.js +260 -132
- package/examples/jsm/transpiler/TSLEncoder.js +8 -8
- package/package.json +1 -1
- package/src/loaders/ObjectLoader.js +3 -3
- package/src/nodes/Nodes.js +3 -2
- package/src/nodes/accessors/BatchNode.js +2 -2
- package/src/nodes/accessors/ClippingNode.js +8 -8
- package/src/nodes/accessors/MorphNode.js +4 -4
- package/src/nodes/accessors/TangentNode.js +2 -2
- package/src/nodes/accessors/Texture3DNode.js +8 -8
- package/src/nodes/accessors/UniformArrayNode.js +5 -3
- package/src/nodes/core/StackNode.js +22 -6
- package/src/nodes/display/AfterImageNode.js +3 -3
- package/src/nodes/display/AnamorphicNode.js +4 -4
- package/src/nodes/display/BleachBypassNode.js +2 -2
- package/src/nodes/display/BlendModeNode.js +8 -8
- package/src/nodes/display/BloomNode.js +9 -9
- package/src/nodes/display/BumpMapNode.js +3 -3
- package/src/nodes/display/ColorAdjustmentNode.js +4 -4
- package/src/nodes/display/ColorSpaceNode.js +3 -3
- package/src/nodes/display/DenoiseNode.js +8 -8
- package/src/nodes/display/DepthOfFieldNode.js +2 -2
- package/src/nodes/display/DotScreenNode.js +3 -3
- package/src/nodes/display/FXAANode.js +11 -11
- package/src/nodes/display/FilmNode.js +2 -2
- package/src/nodes/display/GTAONode.js +9 -9
- package/src/nodes/display/GaussianBlurNode.js +2 -2
- package/src/nodes/display/Lut3DNode.js +2 -2
- package/src/nodes/display/NormalMapNode.js +2 -2
- package/src/nodes/display/PassNode.js +71 -3
- package/src/nodes/display/PixelationPassNode.js +3 -3
- package/src/nodes/display/RGBShiftNode.js +2 -2
- package/src/nodes/display/SepiaNode.js +2 -2
- package/src/nodes/display/SobelOperatorNode.js +2 -2
- package/src/nodes/display/ToneMappingNode.js +13 -13
- package/src/nodes/display/TransitionNode.js +3 -3
- package/src/nodes/functions/BSDF/BRDF_GGX.js +2 -2
- package/src/nodes/functions/BSDF/BRDF_Lambert.js +2 -2
- package/src/nodes/functions/BSDF/BRDF_Sheen.js +4 -4
- package/src/nodes/functions/BSDF/DFGApprox.js +2 -2
- package/src/nodes/functions/BSDF/D_GGX.js +2 -2
- package/src/nodes/functions/BSDF/D_GGX_Anisotropic.js +2 -2
- package/src/nodes/functions/BSDF/EnvironmentBRDF.js +2 -2
- package/src/nodes/functions/BSDF/F_Schlick.js +2 -2
- package/src/nodes/functions/BSDF/LTC.js +6 -6
- package/src/nodes/functions/BSDF/Schlick_to_F0.js +2 -2
- package/src/nodes/functions/BSDF/V_GGX_SmithCorrelated.js +2 -2
- package/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.js +2 -2
- package/src/nodes/functions/PhongLightingModel.js +3 -3
- package/src/nodes/functions/PhysicalLightingModel.js +18 -18
- package/src/nodes/functions/ToonLightingModel.js +2 -2
- package/src/nodes/functions/material/getGeometryRoughness.js +2 -2
- package/src/nodes/functions/material/getRoughness.js +2 -2
- package/src/nodes/lighting/AnalyticLightNode.js +5 -5
- package/src/nodes/lighting/BasicEnvironmentNode.js +2 -1
- package/src/nodes/lighting/LightProbeNode.js +80 -0
- package/src/nodes/lighting/LightUtils.js +3 -3
- package/src/nodes/materials/InstancedPointsNodeMaterial.js +3 -3
- package/src/nodes/materials/Line2NodeMaterial.js +17 -17
- package/src/nodes/materials/MeshPhysicalNodeMaterial.js +1 -1
- package/src/nodes/materials/VolumeNodeMaterial.js +5 -5
- package/src/nodes/materialx/lib/mx_hsv.js +12 -12
- package/src/nodes/materialx/lib/mx_noise.js +80 -80
- package/src/nodes/materialx/lib/mx_transform_color.js +2 -2
- package/src/nodes/math/CondNode.js +13 -2
- package/src/nodes/math/MathNode.js +2 -2
- package/src/nodes/math/TriNoise3D.js +6 -6
- package/src/nodes/pmrem/PMREMUtils.js +34 -34
- package/src/nodes/procedural/CheckerNode.js +2 -2
- package/src/nodes/shadernode/ShaderNode.js +11 -4
- package/src/nodes/utils/CubeMapNode.js +157 -0
- package/src/nodes/utils/LoopNode.js +10 -4
- package/src/nodes/utils/SpriteUtils.js +2 -2
- package/src/nodes/utils/UVUtils.js +3 -3
- package/src/nodes/utils/ViewportUtils.js +3 -3
- package/src/renderers/WebGLRenderer.js +8 -0
- package/src/renderers/common/RenderContext.js +24 -0
- package/src/renderers/common/RenderObject.js +1 -1
- package/src/renderers/shaders/ShaderChunk/batching_pars_vertex.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/batching_vertex.glsl.js +1 -1
- package/src/renderers/shaders/ShaderLib/linedashed.glsl.js +0 -2
- package/src/renderers/shaders/ShaderLib/points.glsl.js +0 -2
- package/src/renderers/webgl/WebGLPrograms.js +2 -1
- package/src/renderers/webgl-fallback/WebGLBackend.js +31 -27
- package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +12 -8
- package/src/renderers/webgpu/WebGPUBackend.js +10 -14
- package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +30 -2
- package/src/renderers/webgpu/utils/WebGPUConstants.js +2 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import DFGApprox from './DFGApprox.js';
|
|
2
|
-
import {
|
|
2
|
+
import { Fn } from '../../shadernode/ShaderNode.js';
|
|
3
3
|
|
|
4
|
-
const EnvironmentBRDF =
|
|
4
|
+
const EnvironmentBRDF = Fn( ( inputs ) => {
|
|
5
5
|
|
|
6
6
|
const { dotNV, specularColor, specularF90, roughness } = inputs;
|
|
7
7
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Fn } from '../../shadernode/ShaderNode.js';
|
|
2
2
|
|
|
3
|
-
const F_Schlick =
|
|
3
|
+
const F_Schlick = Fn( ( { f0, f90, dotVH } ) => {
|
|
4
4
|
|
|
5
5
|
// Original approximation by Christophe Schlick '94
|
|
6
6
|
// float fresnel = pow( 1.0 - dotVH, 5.0 );
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Fn, If, mat3, vec2, vec3 } from '../../shadernode/ShaderNode.js';
|
|
2
2
|
import { max } from '../../math/MathNode.js';
|
|
3
3
|
|
|
4
4
|
// Rect Area Light
|
|
@@ -7,7 +7,7 @@ import { max } from '../../math/MathNode.js';
|
|
|
7
7
|
// by Eric Heitz, Jonathan Dupuy, Stephen Hill and David Neubelt
|
|
8
8
|
// code: https://github.com/selfshadow/ltc_code/
|
|
9
9
|
|
|
10
|
-
const LTC_Uv =
|
|
10
|
+
const LTC_Uv = Fn( ( { N, V, roughness } ) => {
|
|
11
11
|
|
|
12
12
|
const LUT_SIZE = 64.0;
|
|
13
13
|
const LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;
|
|
@@ -32,7 +32,7 @@ const LTC_Uv = tslFn( ( { N, V, roughness } ) => {
|
|
|
32
32
|
]
|
|
33
33
|
} );
|
|
34
34
|
|
|
35
|
-
const LTC_ClippedSphereFormFactor =
|
|
35
|
+
const LTC_ClippedSphereFormFactor = Fn( ( { f } ) => {
|
|
36
36
|
|
|
37
37
|
// Real-Time Area Lighting: a Journey from Research to Production (p.102)
|
|
38
38
|
// An approximation of the form factor of a horizon-clipped rectangle.
|
|
@@ -49,7 +49,7 @@ const LTC_ClippedSphereFormFactor = tslFn( ( { f } ) => {
|
|
|
49
49
|
]
|
|
50
50
|
} );
|
|
51
51
|
|
|
52
|
-
const LTC_EdgeVectorFormFactor =
|
|
52
|
+
const LTC_EdgeVectorFormFactor = Fn( ( { v1, v2 } ) => {
|
|
53
53
|
|
|
54
54
|
const x = v1.dot( v2 );
|
|
55
55
|
const y = x.abs().toVar();
|
|
@@ -59,7 +59,7 @@ const LTC_EdgeVectorFormFactor = tslFn( ( { v1, v2 } ) => {
|
|
|
59
59
|
const b = y.add( 4.1616724 ).mul( y ).add( 3.4175940 ).toVar();
|
|
60
60
|
const v = a.div( b );
|
|
61
61
|
|
|
62
|
-
const theta_sintheta = x.greaterThan( 0.0 ).
|
|
62
|
+
const theta_sintheta = x.greaterThan( 0.0 ).select( v, max( x.mul( x ).oneMinus(), 1e-7 ).inverseSqrt().mul( 0.5 ).sub( v ) );
|
|
63
63
|
|
|
64
64
|
return v1.cross( v2 ).mul( theta_sintheta );
|
|
65
65
|
|
|
@@ -72,7 +72,7 @@ const LTC_EdgeVectorFormFactor = tslFn( ( { v1, v2 } ) => {
|
|
|
72
72
|
]
|
|
73
73
|
} );
|
|
74
74
|
|
|
75
|
-
const LTC_Evaluate =
|
|
75
|
+
const LTC_Evaluate = Fn( ( { N, V, P, mInv, p0, p1, p2, p3 } ) => {
|
|
76
76
|
|
|
77
77
|
// bail if point is on back side of plane of light
|
|
78
78
|
// assumes ccw winding order of light vertices
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Fn, vec3 } from '../../shadernode/ShaderNode.js';
|
|
2
2
|
|
|
3
|
-
const Schlick_to_F0 =
|
|
3
|
+
const Schlick_to_F0 = Fn( ( { f, f90, dotVH } ) => {
|
|
4
4
|
|
|
5
5
|
const x = dotVH.oneMinus().saturate();
|
|
6
6
|
const x2 = x.mul( x );
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { div } from '../../math/OperatorNode.js';
|
|
2
2
|
import { EPSILON } from '../../math/MathNode.js';
|
|
3
|
-
import {
|
|
3
|
+
import { Fn } from '../../shadernode/ShaderNode.js';
|
|
4
4
|
|
|
5
5
|
// Moving Frostbite to Physically Based Rendering 3.0 - page 12, listing 2
|
|
6
6
|
// https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf
|
|
7
|
-
const V_GGX_SmithCorrelated =
|
|
7
|
+
const V_GGX_SmithCorrelated = Fn( ( { alpha, dotNL, dotNV } ) => {
|
|
8
8
|
|
|
9
9
|
const a2 = alpha.pow2();
|
|
10
10
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { div } from '../../math/OperatorNode.js';
|
|
2
|
-
import {
|
|
2
|
+
import { Fn, vec3 } from '../../shadernode/ShaderNode.js';
|
|
3
3
|
|
|
4
4
|
// https://google.github.io/filament/Filament.md.html#materialsystem/anisotropicmodel/anisotropicspecularbrdf
|
|
5
5
|
|
|
6
|
-
const V_GGX_SmithCorrelated_Anisotropic =
|
|
6
|
+
const V_GGX_SmithCorrelated_Anisotropic = Fn( ( { alphaT, alphaB, dotTV, dotBV, dotTL, dotBL, dotNV, dotNL } ) => {
|
|
7
7
|
|
|
8
8
|
const gv = dotNL.mul( vec3( alphaT.mul( dotTV ), alphaB.mul( dotBV ), dotNV ).length() );
|
|
9
9
|
const gl = dotNV.mul( vec3( alphaT.mul( dotTL ), alphaB.mul( dotBL ), dotNL ).length() );
|
|
@@ -6,17 +6,17 @@ import { transformedNormalView } from '../accessors/NormalNode.js';
|
|
|
6
6
|
import { materialSpecularStrength } from '../accessors/MaterialNode.js';
|
|
7
7
|
import { shininess, specularColor } from '../core/PropertyNode.js';
|
|
8
8
|
import { positionViewDirection } from '../accessors/PositionNode.js';
|
|
9
|
-
import {
|
|
9
|
+
import { Fn, float } from '../shadernode/ShaderNode.js';
|
|
10
10
|
|
|
11
11
|
const G_BlinnPhong_Implicit = () => float( 0.25 );
|
|
12
12
|
|
|
13
|
-
const D_BlinnPhong =
|
|
13
|
+
const D_BlinnPhong = Fn( ( { dotNH } ) => {
|
|
14
14
|
|
|
15
15
|
return shininess.mul( float( 0.5 ) ).add( 1.0 ).mul( float( 1 / Math.PI ) ).mul( dotNH.pow( shininess ) );
|
|
16
16
|
|
|
17
17
|
} );
|
|
18
18
|
|
|
19
|
-
const BRDF_BlinnPhong =
|
|
19
|
+
const BRDF_BlinnPhong = Fn( ( { lightDirection } ) => {
|
|
20
20
|
|
|
21
21
|
const halfDir = lightDirection.add( positionViewDirection ).normalize();
|
|
22
22
|
|
|
@@ -10,21 +10,21 @@ import LightingModel from '../core/LightingModel.js';
|
|
|
10
10
|
import { diffuseColor, specularColor, specularF90, roughness, clearcoat, clearcoatRoughness, sheen, sheenRoughness, iridescence, iridescenceIOR, iridescenceThickness, ior, thickness, transmission, attenuationDistance, attenuationColor, dispersion } from '../core/PropertyNode.js';
|
|
11
11
|
import { transformedNormalView, transformedClearcoatNormalView, transformedNormalWorld } from '../accessors/NormalNode.js';
|
|
12
12
|
import { positionViewDirection, positionView, positionWorld } from '../accessors/PositionNode.js';
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
13
|
+
import { Fn, float, vec2, vec3, vec4, mat3, If } from '../shadernode/ShaderNode.js';
|
|
14
|
+
import { select } from '../math/CondNode.js';
|
|
15
15
|
import { mix, normalize, refract, length, clamp, log2, log, exp, smoothstep } from '../math/MathNode.js';
|
|
16
16
|
import { div } from '../math/OperatorNode.js';
|
|
17
17
|
import { cameraPosition, cameraProjectionMatrix, cameraViewMatrix } from '../accessors/CameraNode.js';
|
|
18
18
|
import { modelWorldMatrix } from '../accessors/ModelNode.js';
|
|
19
19
|
import { viewportResolution } from '../display/ViewportNode.js';
|
|
20
20
|
import { viewportMipTexture } from '../display/ViewportTextureNode.js';
|
|
21
|
-
import {
|
|
21
|
+
import { Loop } from '../utils/LoopNode.js';
|
|
22
22
|
|
|
23
23
|
//
|
|
24
24
|
// Transmission
|
|
25
25
|
//
|
|
26
26
|
|
|
27
|
-
const getVolumeTransmissionRay =
|
|
27
|
+
const getVolumeTransmissionRay = Fn( ( [ n, v, thickness, ior, modelMatrix ] ) => {
|
|
28
28
|
|
|
29
29
|
// Direction of refracted light.
|
|
30
30
|
const refractionVector = vec3( refract( v.negate(), normalize( n ), div( 1.0, ior ) ) );
|
|
@@ -51,7 +51,7 @@ const getVolumeTransmissionRay = tslFn( ( [ n, v, thickness, ior, modelMatrix ]
|
|
|
51
51
|
]
|
|
52
52
|
} );
|
|
53
53
|
|
|
54
|
-
const applyIorToRoughness =
|
|
54
|
+
const applyIorToRoughness = Fn( ( [ roughness, ior ] ) => {
|
|
55
55
|
|
|
56
56
|
// Scale roughness with IOR so that an IOR of 1.0 results in no microfacet refraction and
|
|
57
57
|
// an IOR of 1.5 results in the default amount of microfacet refraction.
|
|
@@ -68,7 +68,7 @@ const applyIorToRoughness = tslFn( ( [ roughness, ior ] ) => {
|
|
|
68
68
|
|
|
69
69
|
const singleViewportMipTexture = viewportMipTexture();
|
|
70
70
|
|
|
71
|
-
const getTransmissionSample =
|
|
71
|
+
const getTransmissionSample = Fn( ( [ fragCoord, roughness, ior ] ) => {
|
|
72
72
|
|
|
73
73
|
const transmissionSample = singleViewportMipTexture.uv( fragCoord );
|
|
74
74
|
//const transmissionSample = viewportMipTexture( fragCoord );
|
|
@@ -79,7 +79,7 @@ const getTransmissionSample = tslFn( ( [ fragCoord, roughness, ior ] ) => {
|
|
|
79
79
|
|
|
80
80
|
} );
|
|
81
81
|
|
|
82
|
-
const volumeAttenuation =
|
|
82
|
+
const volumeAttenuation = Fn( ( [ transmissionDistance, attenuationColor, attenuationDistance ] ) => {
|
|
83
83
|
|
|
84
84
|
If( attenuationDistance.notEqual( 0 ), () => {
|
|
85
85
|
|
|
@@ -104,7 +104,7 @@ const volumeAttenuation = tslFn( ( [ transmissionDistance, attenuationColor, att
|
|
|
104
104
|
]
|
|
105
105
|
} );
|
|
106
106
|
|
|
107
|
-
const getIBLVolumeRefraction =
|
|
107
|
+
const getIBLVolumeRefraction = Fn( ( [ n, v, roughness, diffuseColor, specularColor, specularF90, position, modelMatrix, viewMatrix, projMatrix, ior, thickness, attenuationColor, attenuationDistance, dispersion ] ) => {
|
|
108
108
|
|
|
109
109
|
let transmittedLight, transmittance;
|
|
110
110
|
|
|
@@ -116,7 +116,7 @@ const getIBLVolumeRefraction = tslFn( ( [ n, v, roughness, diffuseColor, specula
|
|
|
116
116
|
const halfSpread = ior.sub( 1.0 ).mul( dispersion.mul( 0.025 ) );
|
|
117
117
|
const iors = vec3( ior.sub( halfSpread ), ior, ior.add( halfSpread ) );
|
|
118
118
|
|
|
119
|
-
|
|
119
|
+
Loop( { start: 0, end: 3 }, ( { i } ) => {
|
|
120
120
|
|
|
121
121
|
const ior = iors.element( i );
|
|
122
122
|
|
|
@@ -227,7 +227,7 @@ const evalSensitivity = ( OPD, shift ) => {
|
|
|
227
227
|
|
|
228
228
|
};
|
|
229
229
|
|
|
230
|
-
const evalIridescence =
|
|
230
|
+
const evalIridescence = Fn( ( { outsideIOR, eta2, cosTheta1, thinFilmThickness, baseF0 } ) => {
|
|
231
231
|
|
|
232
232
|
// Force iridescenceIOR -> outsideIOR when thinFilmThickness -> 0.0
|
|
233
233
|
const iridescenceIOR = mix( outsideIOR, eta2, smoothstep( 0.0, 0.03, thinFilmThickness ) );
|
|
@@ -249,7 +249,7 @@ const evalIridescence = tslFn( ( { outsideIOR, eta2, cosTheta1, thinFilmThicknes
|
|
|
249
249
|
const R12 = F_Schlick( { f0: R0, f90: 1.0, dotVH: cosTheta1 } );
|
|
250
250
|
//const R21 = R12;
|
|
251
251
|
const T121 = R12.oneMinus();
|
|
252
|
-
const phi12 = iridescenceIOR.lessThan( outsideIOR ).
|
|
252
|
+
const phi12 = iridescenceIOR.lessThan( outsideIOR ).select( Math.PI, 0.0 );
|
|
253
253
|
const phi21 = float( Math.PI ).sub( phi12 );
|
|
254
254
|
|
|
255
255
|
// Second interface
|
|
@@ -257,9 +257,9 @@ const evalIridescence = tslFn( ( { outsideIOR, eta2, cosTheta1, thinFilmThicknes
|
|
|
257
257
|
const R1 = IorToFresnel0( baseIOR, iridescenceIOR.toVec3() );
|
|
258
258
|
const R23 = F_Schlick( { f0: R1, f90: 1.0, dotVH: cosTheta2 } );
|
|
259
259
|
const phi23 = vec3(
|
|
260
|
-
baseIOR.x.lessThan( iridescenceIOR ).
|
|
261
|
-
baseIOR.y.lessThan( iridescenceIOR ).
|
|
262
|
-
baseIOR.z.lessThan( iridescenceIOR ).
|
|
260
|
+
baseIOR.x.lessThan( iridescenceIOR ).select( Math.PI, 0.0 ),
|
|
261
|
+
baseIOR.y.lessThan( iridescenceIOR ).select( Math.PI, 0.0 ),
|
|
262
|
+
baseIOR.z.lessThan( iridescenceIOR ).select( Math.PI, 0.0 )
|
|
263
263
|
);
|
|
264
264
|
|
|
265
265
|
// Phase shift
|
|
@@ -307,25 +307,25 @@ const evalIridescence = tslFn( ( { outsideIOR, eta2, cosTheta1, thinFilmThicknes
|
|
|
307
307
|
// This is a curve-fit approxmation to the "Charlie sheen" BRDF integrated over the hemisphere from
|
|
308
308
|
// Estevez and Kulla 2017, "Production Friendly Microfacet Sheen BRDF". The analysis can be found
|
|
309
309
|
// in the Sheen section of https://drive.google.com/file/d/1T0D1VSyR4AllqIJTQAraEIzjlb5h4FKH/view?usp=sharing
|
|
310
|
-
const IBLSheenBRDF =
|
|
310
|
+
const IBLSheenBRDF = Fn( ( { normal, viewDir, roughness } ) => {
|
|
311
311
|
|
|
312
312
|
const dotNV = normal.dot( viewDir ).saturate();
|
|
313
313
|
|
|
314
314
|
const r2 = roughness.pow2();
|
|
315
315
|
|
|
316
|
-
const a =
|
|
316
|
+
const a = select(
|
|
317
317
|
roughness.lessThan( 0.25 ),
|
|
318
318
|
float( - 339.2 ).mul( r2 ).add( float( 161.4 ).mul( roughness ) ).sub( 25.9 ),
|
|
319
319
|
float( - 8.48 ).mul( r2 ).add( float( 14.3 ).mul( roughness ) ).sub( 9.95 )
|
|
320
320
|
);
|
|
321
321
|
|
|
322
|
-
const b =
|
|
322
|
+
const b = select(
|
|
323
323
|
roughness.lessThan( 0.25 ),
|
|
324
324
|
float( 44.0 ).mul( r2 ).sub( float( 23.7 ).mul( roughness ) ).add( 3.26 ),
|
|
325
325
|
float( 1.97 ).mul( r2 ).sub( float( 3.27 ).mul( roughness ) ).add( 0.72 )
|
|
326
326
|
);
|
|
327
327
|
|
|
328
|
-
const DG =
|
|
328
|
+
const DG = select( roughness.lessThan( 0.25 ), 0.0, float( 0.1 ).mul( roughness ).sub( 0.025 ) ).add( a.mul( dotNV ).add( b ).exp() );
|
|
329
329
|
|
|
330
330
|
return DG.mul( 1.0 / Math.PI ).saturate();
|
|
331
331
|
|
|
@@ -2,11 +2,11 @@ import LightingModel from '../core/LightingModel.js';
|
|
|
2
2
|
import BRDF_Lambert from './BSDF/BRDF_Lambert.js';
|
|
3
3
|
import { diffuseColor } from '../core/PropertyNode.js';
|
|
4
4
|
import { normalGeometry } from '../accessors/NormalNode.js';
|
|
5
|
-
import {
|
|
5
|
+
import { Fn, float, vec2, vec3 } from '../shadernode/ShaderNode.js';
|
|
6
6
|
import { mix, smoothstep } from '../math/MathNode.js';
|
|
7
7
|
import { materialReference } from '../accessors/MaterialReferenceNode.js';
|
|
8
8
|
|
|
9
|
-
const getGradientIrradiance =
|
|
9
|
+
const getGradientIrradiance = Fn( ( { normal, lightDirection, builder } ) => {
|
|
10
10
|
|
|
11
11
|
// dotNL will be from -1.0 to 1.0
|
|
12
12
|
const dotNL = normal.dot( lightDirection );
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { normalGeometry } from '../../accessors/NormalNode.js';
|
|
2
|
-
import {
|
|
2
|
+
import { Fn } from '../../shadernode/ShaderNode.js';
|
|
3
3
|
|
|
4
|
-
const getGeometryRoughness =
|
|
4
|
+
const getGeometryRoughness = Fn( () => {
|
|
5
5
|
|
|
6
6
|
const dxy = normalGeometry.dFdx().abs().max( normalGeometry.dFdy().abs() );
|
|
7
7
|
const geometryRoughness = dxy.x.max( dxy.y ).max( dxy.z );
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import getGeometryRoughness from './getGeometryRoughness.js';
|
|
2
|
-
import {
|
|
2
|
+
import { Fn } from '../../shadernode/ShaderNode.js';
|
|
3
3
|
|
|
4
|
-
const getRoughness =
|
|
4
|
+
const getRoughness = Fn( ( inputs ) => {
|
|
5
5
|
|
|
6
6
|
const { roughness } = inputs;
|
|
7
7
|
|
|
@@ -11,16 +11,16 @@ import { mix, fract } from '../math/MathNode.js';
|
|
|
11
11
|
import { add } from '../math/OperatorNode.js';
|
|
12
12
|
import { Color } from '../../math/Color.js';
|
|
13
13
|
import { DepthTexture } from '../../textures/DepthTexture.js';
|
|
14
|
-
import {
|
|
14
|
+
import { Fn } from '../shadernode/ShaderNode.js';
|
|
15
15
|
import { LessCompare, WebGPUCoordinateSystem } from '../../constants.js';
|
|
16
16
|
|
|
17
|
-
const BasicShadowMap =
|
|
17
|
+
const BasicShadowMap = Fn( ( { depthTexture, shadowCoord } ) => {
|
|
18
18
|
|
|
19
19
|
return texture( depthTexture, shadowCoord.xy ).compare( shadowCoord.z );
|
|
20
20
|
|
|
21
21
|
} );
|
|
22
22
|
|
|
23
|
-
const PCFShadowMap =
|
|
23
|
+
const PCFShadowMap = Fn( ( { depthTexture, shadowCoord, shadow } ) => {
|
|
24
24
|
|
|
25
25
|
const depthCompare = ( uv, compare ) => texture( depthTexture, uv ).compare( compare );
|
|
26
26
|
|
|
@@ -59,7 +59,7 @@ const PCFShadowMap = tslFn( ( { depthTexture, shadowCoord, shadow } ) => {
|
|
|
59
59
|
|
|
60
60
|
} );
|
|
61
61
|
|
|
62
|
-
const PCFSoftShadowMap =
|
|
62
|
+
const PCFSoftShadowMap = Fn( ( { depthTexture, shadowCoord, shadow } ) => {
|
|
63
63
|
|
|
64
64
|
const depthCompare = ( uv, compare ) => texture( depthTexture, uv ).compare( compare );
|
|
65
65
|
|
|
@@ -223,7 +223,7 @@ class AnalyticLightNode extends LightingNode {
|
|
|
223
223
|
}
|
|
224
224
|
|
|
225
225
|
const shadowColor = texture( shadowMap.texture, shadowCoord );
|
|
226
|
-
const shadowNode = frustumTest.
|
|
226
|
+
const shadowNode = frustumTest.select( filterFn( { depthTexture, shadowCoord, shadow } ), float( 1 ) );
|
|
227
227
|
|
|
228
228
|
this.shadowMap = shadowMap;
|
|
229
229
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import LightingNode from './LightingNode.js';
|
|
2
2
|
import { addNodeClass } from '../core/Node.js';
|
|
3
|
+
import { cubeMapNode } from '../utils/CubeMapNode.js';
|
|
3
4
|
|
|
4
5
|
class BasicEnvironmentNode extends LightingNode {
|
|
5
6
|
|
|
@@ -15,7 +16,7 @@ class BasicEnvironmentNode extends LightingNode {
|
|
|
15
16
|
|
|
16
17
|
// environment property is used in the finish() method of BasicLightingModel
|
|
17
18
|
|
|
18
|
-
builder.context.environment = this.envNode;
|
|
19
|
+
builder.context.environment = cubeMapNode( this.envNode );
|
|
19
20
|
|
|
20
21
|
}
|
|
21
22
|
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import AnalyticLightNode from './AnalyticLightNode.js';
|
|
2
|
+
import { addLightNode } from './LightsNode.js';
|
|
3
|
+
import { normalWorld } from '../accessors/NormalNode.js';
|
|
4
|
+
import { addNodeClass } from '../core/Node.js';
|
|
5
|
+
import { LightProbe } from '../../lights/LightProbe.js';
|
|
6
|
+
import { uniformArray } from '../accessors/UniformArrayNode.js';
|
|
7
|
+
import { Fn } from '../shadernode/ShaderNode.js';
|
|
8
|
+
import { mul } from '../math/OperatorNode.js';
|
|
9
|
+
import { Vector3 } from '../../math/Vector3.js';
|
|
10
|
+
|
|
11
|
+
class LightProbeNode extends AnalyticLightNode {
|
|
12
|
+
|
|
13
|
+
constructor( light = null ) {
|
|
14
|
+
|
|
15
|
+
super( light );
|
|
16
|
+
|
|
17
|
+
const array = [];
|
|
18
|
+
|
|
19
|
+
for ( let i = 0; i < 9; i ++ ) array.push( new Vector3() );
|
|
20
|
+
|
|
21
|
+
this.lightProbe = uniformArray( array );
|
|
22
|
+
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
update( frame ) {
|
|
26
|
+
|
|
27
|
+
const { light } = this;
|
|
28
|
+
|
|
29
|
+
super.update( frame );
|
|
30
|
+
|
|
31
|
+
//
|
|
32
|
+
|
|
33
|
+
for ( let i = 0; i < 9; i ++ ) {
|
|
34
|
+
|
|
35
|
+
this.lightProbe.array[ i ].copy( light.sh.coefficients[ i ] ).multiplyScalar( light.intensity );
|
|
36
|
+
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
setup( builder ) {
|
|
42
|
+
|
|
43
|
+
const irradiance = shGetIrradianceAt( normalWorld, this.lightProbe );
|
|
44
|
+
|
|
45
|
+
builder.context.irradiance.addAssign( irradiance );
|
|
46
|
+
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const shGetIrradianceAt = Fn( ( [ normal, shCoefficients ] ) => {
|
|
52
|
+
|
|
53
|
+
// normal is assumed to have unit length
|
|
54
|
+
|
|
55
|
+
const x = normal.x, y = normal.y, z = normal.z;
|
|
56
|
+
|
|
57
|
+
// band 0
|
|
58
|
+
const result = shCoefficients.element( 0 ).mul( 0.886227 );
|
|
59
|
+
|
|
60
|
+
// band 1
|
|
61
|
+
result.addAssign( shCoefficients.element( 1 ).mul( 2.0 * 0.511664 ).mul( y ) );
|
|
62
|
+
result.addAssign( shCoefficients.element( 2 ).mul( 2.0 * 0.511664 ).mul( z ) );
|
|
63
|
+
result.addAssign( shCoefficients.element( 3 ).mul( 2.0 * 0.511664 ).mul( x ) );
|
|
64
|
+
|
|
65
|
+
// band 2
|
|
66
|
+
result.addAssign( shCoefficients.element( 4 ).mul( 2.0 * 0.429043 ).mul( x ).mul( y ) );
|
|
67
|
+
result.addAssign( shCoefficients.element( 5 ).mul( 2.0 * 0.429043 ).mul( y ).mul( z ) );
|
|
68
|
+
result.addAssign( shCoefficients.element( 6 ).mul( z.mul( z ).mul( 0.743125 ).sub( 0.247708 ) ) );
|
|
69
|
+
result.addAssign( shCoefficients.element( 7 ).mul( 2.0 * 0.429043 ).mul( x ).mul( z ) );
|
|
70
|
+
result.addAssign( shCoefficients.element( 8 ).mul( 0.429043 ).mul( mul( x, x ).sub( mul( y, y ) ) ) );
|
|
71
|
+
|
|
72
|
+
return result;
|
|
73
|
+
|
|
74
|
+
} );
|
|
75
|
+
|
|
76
|
+
export default LightProbeNode;
|
|
77
|
+
|
|
78
|
+
addNodeClass( 'LightProbeNode', LightProbeNode );
|
|
79
|
+
|
|
80
|
+
addLightNode( LightProbe, LightProbeNode );
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Fn } from '../shadernode/ShaderNode.js';
|
|
2
2
|
|
|
3
|
-
export const getDistanceAttenuation =
|
|
3
|
+
export const getDistanceAttenuation = Fn( ( inputs ) => {
|
|
4
4
|
|
|
5
5
|
const { lightDistance, cutoffDistance, decayExponent } = inputs;
|
|
6
6
|
|
|
@@ -9,7 +9,7 @@ export const getDistanceAttenuation = tslFn( ( inputs ) => {
|
|
|
9
9
|
// https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf
|
|
10
10
|
const distanceFalloff = lightDistance.pow( decayExponent ).max( 0.01 ).reciprocal();
|
|
11
11
|
|
|
12
|
-
return cutoffDistance.greaterThan( 0 ).
|
|
12
|
+
return cutoffDistance.greaterThan( 0 ).select(
|
|
13
13
|
distanceFalloff.mul( lightDistance.div( cutoffDistance ).pow4().oneMinus().clamp().pow2() ),
|
|
14
14
|
distanceFalloff
|
|
15
15
|
);
|
|
@@ -7,7 +7,7 @@ import { materialColor, materialPointWidth } from '../accessors/MaterialNode.js'
|
|
|
7
7
|
import { modelViewMatrix } from '../accessors/ModelNode.js';
|
|
8
8
|
import { positionGeometry } from '../accessors/PositionNode.js';
|
|
9
9
|
import { smoothstep } from '../math/MathNode.js';
|
|
10
|
-
import {
|
|
10
|
+
import { Fn, vec2, vec4 } from '../shadernode/ShaderNode.js';
|
|
11
11
|
import { uv } from '../accessors/UVNode.js';
|
|
12
12
|
import { viewport } from '../display/ViewportNode.js';
|
|
13
13
|
|
|
@@ -46,7 +46,7 @@ class InstancedPointsNodeMaterial extends NodeMaterial {
|
|
|
46
46
|
const useAlphaToCoverage = this.alphaToCoverage;
|
|
47
47
|
const useColor = this.useColor;
|
|
48
48
|
|
|
49
|
-
this.vertexNode =
|
|
49
|
+
this.vertexNode = Fn( () => {
|
|
50
50
|
|
|
51
51
|
//vUv = uv;
|
|
52
52
|
varying( vec2(), 'vUv' ).assign( uv() ); // @TODO: Analyze other way to do this
|
|
@@ -81,7 +81,7 @@ class InstancedPointsNodeMaterial extends NodeMaterial {
|
|
|
81
81
|
|
|
82
82
|
} )();
|
|
83
83
|
|
|
84
|
-
this.fragmentNode =
|
|
84
|
+
this.fragmentNode = Fn( () => {
|
|
85
85
|
|
|
86
86
|
const vUv = varying( vec2(), 'vUv' );
|
|
87
87
|
|
|
@@ -8,7 +8,7 @@ import { materialColor, materialLineScale, materialLineDashSize, materialLineGap
|
|
|
8
8
|
import { modelViewMatrix } from '../accessors/ModelNode.js';
|
|
9
9
|
import { positionGeometry } from '../accessors/PositionNode.js';
|
|
10
10
|
import { mix, smoothstep } from '../math/MathNode.js';
|
|
11
|
-
import {
|
|
11
|
+
import { Fn, float, vec2, vec3, vec4, If } from '../shadernode/ShaderNode.js';
|
|
12
12
|
import { uv } from '../accessors/UVNode.js';
|
|
13
13
|
import { viewport } from '../display/ViewportNode.js';
|
|
14
14
|
import { dashSize, gapSize } from '../core/PropertyNode.js';
|
|
@@ -62,7 +62,7 @@ class Line2NodeMaterial extends NodeMaterial {
|
|
|
62
62
|
const useDash = this.dashed;
|
|
63
63
|
const useWorldUnits = this.worldUnits;
|
|
64
64
|
|
|
65
|
-
const trimSegment =
|
|
65
|
+
const trimSegment = Fn( ( { start, end } ) => {
|
|
66
66
|
|
|
67
67
|
const a = cameraProjectionMatrix.element( 2 ).element( 2 ); // 3nd entry in 3th column
|
|
68
68
|
const b = cameraProjectionMatrix.element( 3 ).element( 2 ); // 3nd entry in 4th column
|
|
@@ -74,7 +74,7 @@ class Line2NodeMaterial extends NodeMaterial {
|
|
|
74
74
|
|
|
75
75
|
} );
|
|
76
76
|
|
|
77
|
-
this.vertexNode =
|
|
77
|
+
this.vertexNode = Fn( () => {
|
|
78
78
|
|
|
79
79
|
varyingProperty( 'vec2', 'vUv' ).assign( uv() );
|
|
80
80
|
|
|
@@ -111,7 +111,7 @@ class Line2NodeMaterial extends NodeMaterial {
|
|
|
111
111
|
|
|
112
112
|
end.assign( trimSegment( { start: start, end: end } ) );
|
|
113
113
|
|
|
114
|
-
} ).
|
|
114
|
+
} ).ElseIf( end.z.lessThan( 0.0 ).and( start.z.greaterThanEqual( 0.0 ) ), () => {
|
|
115
115
|
|
|
116
116
|
start.assign( trimSegment( { start: end, end: start } ) );
|
|
117
117
|
|
|
@@ -147,18 +147,18 @@ class Line2NodeMaterial extends NodeMaterial {
|
|
|
147
147
|
|
|
148
148
|
const worldPos = varyingProperty( 'vec4', 'worldPos' );
|
|
149
149
|
|
|
150
|
-
worldPos.assign( positionGeometry.y.lessThan( 0.5 ).
|
|
150
|
+
worldPos.assign( positionGeometry.y.lessThan( 0.5 ).select( start, end ) );
|
|
151
151
|
|
|
152
152
|
// height offset
|
|
153
153
|
const hw = materialLineWidth.mul( 0.5 );
|
|
154
|
-
worldPos.addAssign( vec4( positionGeometry.x.lessThan( 0.0 ).
|
|
154
|
+
worldPos.addAssign( vec4( positionGeometry.x.lessThan( 0.0 ).select( worldUp.mul( hw ), worldUp.mul( hw ).negate() ), 0 ) );
|
|
155
155
|
|
|
156
156
|
// don't extend the line if we're rendering dashes because we
|
|
157
157
|
// won't be rendering the endcaps
|
|
158
158
|
if ( ! useDash ) {
|
|
159
159
|
|
|
160
160
|
// cap extension
|
|
161
|
-
worldPos.addAssign( vec4( positionGeometry.y.lessThan( 0.5 ).
|
|
161
|
+
worldPos.addAssign( vec4( positionGeometry.y.lessThan( 0.5 ).select( worldDir.mul( hw ).negate(), worldDir.mul( hw ) ), 0 ) );
|
|
162
162
|
|
|
163
163
|
// add width to the box
|
|
164
164
|
worldPos.addAssign( vec4( worldFwd.mul( hw ), 0 ) );
|
|
@@ -179,7 +179,7 @@ class Line2NodeMaterial extends NodeMaterial {
|
|
|
179
179
|
// segments overlap neatly
|
|
180
180
|
const clipPose = temp( vec3() );
|
|
181
181
|
|
|
182
|
-
clipPose.assign( positionGeometry.y.lessThan( 0.5 ).
|
|
182
|
+
clipPose.assign( positionGeometry.y.lessThan( 0.5 ).select( ndcStart, ndcEnd ) );
|
|
183
183
|
clip.z.assign( clipPose.z.mul( clip.w ) );
|
|
184
184
|
|
|
185
185
|
} else {
|
|
@@ -193,14 +193,14 @@ class Line2NodeMaterial extends NodeMaterial {
|
|
|
193
193
|
offset.x.assign( offset.x.div( aspect ) );
|
|
194
194
|
|
|
195
195
|
// sign flip
|
|
196
|
-
offset.assign( positionGeometry.x.lessThan( 0.0 ).
|
|
196
|
+
offset.assign( positionGeometry.x.lessThan( 0.0 ).select( offset.negate(), offset ) );
|
|
197
197
|
|
|
198
198
|
// endcaps
|
|
199
199
|
If( positionGeometry.y.lessThan( 0.0 ), () => {
|
|
200
200
|
|
|
201
201
|
offset.assign( offset.sub( dir ) );
|
|
202
202
|
|
|
203
|
-
} ).
|
|
203
|
+
} ).ElseIf( positionGeometry.y.greaterThan( 1.0 ), () => {
|
|
204
204
|
|
|
205
205
|
offset.assign( offset.add( dir ) );
|
|
206
206
|
|
|
@@ -213,7 +213,7 @@ class Line2NodeMaterial extends NodeMaterial {
|
|
|
213
213
|
offset.assign( offset.div( viewport.w ) );
|
|
214
214
|
|
|
215
215
|
// select end
|
|
216
|
-
clip.assign( positionGeometry.y.lessThan( 0.5 ).
|
|
216
|
+
clip.assign( positionGeometry.y.lessThan( 0.5 ).select( clipStart, clipEnd ) );
|
|
217
217
|
|
|
218
218
|
// back to clip space
|
|
219
219
|
offset.assign( offset.mul( clip.w ) );
|
|
@@ -226,7 +226,7 @@ class Line2NodeMaterial extends NodeMaterial {
|
|
|
226
226
|
|
|
227
227
|
} )();
|
|
228
228
|
|
|
229
|
-
const closestLineToLine =
|
|
229
|
+
const closestLineToLine = Fn( ( { p1, p2, p3, p4 } ) => {
|
|
230
230
|
|
|
231
231
|
const p13 = p1.sub( p3 );
|
|
232
232
|
const p43 = p4.sub( p3 );
|
|
@@ -249,7 +249,7 @@ class Line2NodeMaterial extends NodeMaterial {
|
|
|
249
249
|
|
|
250
250
|
} );
|
|
251
251
|
|
|
252
|
-
this.fragmentNode =
|
|
252
|
+
this.fragmentNode = Fn( () => {
|
|
253
253
|
|
|
254
254
|
const vUv = varyingProperty( 'vec2', 'vUv' );
|
|
255
255
|
|
|
@@ -266,7 +266,7 @@ class Line2NodeMaterial extends NodeMaterial {
|
|
|
266
266
|
const instanceDistanceStart = attribute( 'instanceDistanceStart' );
|
|
267
267
|
const instanceDistanceEnd = attribute( 'instanceDistanceEnd' );
|
|
268
268
|
|
|
269
|
-
const lineDistance = positionGeometry.y.lessThan( 0.5 ).
|
|
269
|
+
const lineDistance = positionGeometry.y.lessThan( 0.5 ).select( dashScaleNode.mul( instanceDistanceStart ), materialLineScale.mul( instanceDistanceEnd ) );
|
|
270
270
|
|
|
271
271
|
const vLineDistance = varying( lineDistance.add( materialLineDashOffset ) );
|
|
272
272
|
const vLineDistanceOffset = offsetNode ? vLineDistance.add( offsetNode ) : vLineDistance;
|
|
@@ -318,7 +318,7 @@ class Line2NodeMaterial extends NodeMaterial {
|
|
|
318
318
|
if ( useAlphaToCoverage ) {
|
|
319
319
|
|
|
320
320
|
const a = vUv.x;
|
|
321
|
-
const b = vUv.y.greaterThan( 0.0 ).
|
|
321
|
+
const b = vUv.y.greaterThan( 0.0 ).select( vUv.y.sub( 1.0 ), vUv.y.add( 1.0 ) );
|
|
322
322
|
|
|
323
323
|
const len2 = a.mul( a ).add( b.mul( b ) );
|
|
324
324
|
|
|
@@ -337,7 +337,7 @@ class Line2NodeMaterial extends NodeMaterial {
|
|
|
337
337
|
If( vUv.y.abs().greaterThan( 1.0 ), () => {
|
|
338
338
|
|
|
339
339
|
const a = vUv.x;
|
|
340
|
-
const b = vUv.y.greaterThan( 0.0 ).
|
|
340
|
+
const b = vUv.y.greaterThan( 0.0 ).select( vUv.y.sub( 1.0 ), vUv.y.add( 1.0 ) );
|
|
341
341
|
const len2 = a.mul( a ).add( b.mul( b ) );
|
|
342
342
|
|
|
343
343
|
len2.greaterThan( 1.0 ).discard();
|
|
@@ -361,7 +361,7 @@ class Line2NodeMaterial extends NodeMaterial {
|
|
|
361
361
|
const instanceColorStart = attribute( 'instanceColorStart' );
|
|
362
362
|
const instanceColorEnd = attribute( 'instanceColorEnd' );
|
|
363
363
|
|
|
364
|
-
const instanceColor = positionGeometry.y.lessThan( 0.5 ).
|
|
364
|
+
const instanceColor = positionGeometry.y.lessThan( 0.5 ).select( instanceColorStart, instanceColorEnd );
|
|
365
365
|
|
|
366
366
|
lineColorNode = instanceColor.mul( materialColor );
|
|
367
367
|
|
|
@@ -156,7 +156,7 @@ class MeshPhysicalNodeMaterial extends MeshStandardNodeMaterial {
|
|
|
156
156
|
|
|
157
157
|
anisotropyV.assign( vec2( 1.0, 0.0 ) );
|
|
158
158
|
|
|
159
|
-
} ).
|
|
159
|
+
} ).Else( () => {
|
|
160
160
|
|
|
161
161
|
anisotropyV.divAssign( vec2( anisotropy ) );
|
|
162
162
|
anisotropy.assign( anisotropy.saturate() );
|