super-three 0.154.1 → 0.155.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/three.cjs +256 -38
- package/build/three.js +256 -38
- package/build/three.min.js +1 -1
- package/build/three.module.js +255 -39
- package/build/three.module.min.js +1 -1
- package/examples/jsm/controls/OrbitControls.js +143 -21
- package/examples/jsm/environments/RoomEnvironment.js +1 -1
- package/examples/jsm/exporters/USDZExporter.js +1 -0
- package/examples/jsm/interactive/SelectionHelper.js +7 -0
- package/examples/jsm/loaders/FBXLoader.js +1 -1
- package/examples/jsm/loaders/GLTFLoader.js +8 -3
- package/examples/jsm/loaders/KTX2Loader.js +4 -4
- package/examples/jsm/loaders/LDrawLoader.js +1 -1
- package/examples/jsm/loaders/NRRDLoader.js +3 -3
- package/examples/jsm/loaders/PLYLoader.js +1 -1
- package/examples/jsm/loaders/TGALoader.js +10 -10
- package/examples/jsm/loaders/VRMLLoader.js +1 -1
- package/examples/jsm/misc/GPUComputationRenderer.js +0 -9
- package/examples/jsm/misc/Volume.js +4 -6
- package/examples/jsm/nodes/Nodes.js +5 -6
- package/examples/jsm/nodes/accessors/BufferAttributeNode.js +1 -1
- package/examples/jsm/nodes/accessors/CubeTextureNode.js +2 -0
- package/examples/jsm/nodes/accessors/ExtendedMaterialNode.js +14 -1
- package/examples/jsm/nodes/accessors/InstanceNode.js +8 -8
- package/examples/jsm/nodes/accessors/MaterialNode.js +34 -44
- package/examples/jsm/nodes/accessors/SceneNode.js +6 -0
- package/examples/jsm/nodes/accessors/TextureNode.js +48 -7
- package/examples/jsm/nodes/core/LightingModel.js +7 -9
- package/examples/jsm/nodes/core/Node.js +11 -2
- package/examples/jsm/nodes/core/PropertyNode.js +4 -0
- package/examples/jsm/nodes/display/BumpMapNode.js +77 -0
- package/examples/jsm/nodes/display/NormalMapNode.js +2 -2
- package/examples/jsm/nodes/functions/BSDF/BRDF_GGX.js +10 -2
- package/examples/jsm/nodes/functions/BSDF/Schlick_to_F0.js +13 -0
- package/examples/jsm/nodes/functions/PhongLightingModel.js +53 -14
- package/examples/jsm/nodes/functions/PhysicalLightingModel.js +236 -97
- package/examples/jsm/nodes/geometry/RangeNode.js +2 -2
- package/examples/jsm/nodes/gpgpu/ComputeNode.js +13 -0
- package/examples/jsm/nodes/lighting/AONode.js +1 -1
- package/examples/jsm/nodes/lighting/AnalyticLightNode.js +58 -20
- package/examples/jsm/nodes/lighting/DirectionalLightNode.js +7 -10
- package/examples/jsm/nodes/lighting/EnvironmentNode.js +22 -12
- package/examples/jsm/nodes/lighting/HemisphereLightNode.js +1 -1
- package/examples/jsm/nodes/lighting/LightingContextNode.js +12 -9
- package/examples/jsm/nodes/lighting/PointLightNode.js +7 -10
- package/examples/jsm/nodes/lighting/SpotLightNode.js +7 -10
- package/examples/jsm/nodes/materials/Materials.js +1 -0
- package/examples/jsm/nodes/materials/MeshLambertNodeMaterial.js +34 -0
- package/examples/jsm/nodes/materials/MeshNormalNodeMaterial.js +2 -0
- package/examples/jsm/nodes/materials/MeshPhongNodeMaterial.js +2 -2
- package/examples/jsm/nodes/materials/MeshPhysicalNodeMaterial.js +19 -2
- package/examples/jsm/nodes/materials/MeshStandardNodeMaterial.js +2 -2
- package/examples/jsm/nodes/materials/NodeMaterial.js +50 -24
- package/examples/jsm/nodes/materials/SpriteNodeMaterial.js +2 -2
- package/examples/jsm/nodes/shadernode/ShaderNode.js +2 -2
- package/examples/jsm/objects/Reflector.js +1 -9
- package/examples/jsm/objects/Refractor.js +0 -8
- package/examples/jsm/offscreen/scene.js +0 -1
- package/examples/jsm/postprocessing/MaskPass.js +4 -1
- package/examples/jsm/postprocessing/OutputPass.js +33 -14
- package/examples/jsm/postprocessing/UnrealBloomPass.js +21 -17
- package/examples/jsm/renderers/common/Background.js +22 -20
- package/examples/jsm/renderers/common/Binding.js +8 -0
- package/examples/jsm/renderers/common/Bindings.js +2 -6
- package/examples/jsm/renderers/common/Geometries.js +1 -1
- package/examples/jsm/renderers/common/Pipelines.js +94 -45
- package/examples/jsm/renderers/common/RenderContext.js +1 -0
- package/examples/jsm/renderers/common/RenderContexts.js +16 -5
- package/examples/jsm/renderers/common/RenderObject.js +20 -4
- package/examples/jsm/renderers/common/RenderObjects.js +10 -7
- package/examples/jsm/renderers/common/Renderer.js +70 -39
- package/examples/jsm/renderers/common/Textures.js +20 -8
- package/examples/jsm/renderers/common/nodes/Nodes.js +15 -4
- package/examples/jsm/renderers/webgpu/WebGPUBackend.js +51 -54
- package/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js +33 -9
- package/examples/jsm/renderers/webgpu/utils/WebGPUAttributeUtils.js +55 -36
- package/examples/jsm/renderers/webgpu/utils/WebGPUBindingUtils.js +83 -5
- package/examples/jsm/renderers/webgpu/utils/WebGPUConstants.js +24 -22
- package/examples/jsm/renderers/webgpu/utils/WebGPUPipelineUtils.js +83 -130
- package/examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js +35 -8
- package/examples/jsm/renderers/webgpu/utils/WebGPUUtils.js +1 -1
- package/examples/jsm/shaders/OutputShader.js +19 -2
- package/examples/jsm/utils/BufferGeometryUtils.js +13 -4
- package/examples/jsm/webxr/OculusHandPointerModel.js +2 -2
- package/package.json +2 -2
- package/src/Three.js +2 -0
- package/src/animation/PropertyBinding.js +1 -1
- package/src/cameras/CubeCamera.js +1 -4
- package/src/constants.js +1 -1
- package/src/core/BufferAttribute.js +20 -0
- package/src/core/Object3D.js +1 -1
- package/src/core/RenderTarget.js +122 -0
- package/src/geometries/CapsuleGeometry.js +1 -1
- package/src/loaders/DataTextureLoader.js +21 -2
- package/src/renderers/WebGLMultipleRenderTargets.js +0 -2
- package/src/renderers/WebGLRenderTarget.js +3 -110
- package/src/renderers/WebGLRenderer.js +62 -8
- package/src/renderers/shaders/ShaderChunk/iridescence_fragment.glsl.js +1 -2
- package/src/renderers/webgl/WebGLGeometries.js +5 -1
- package/src/renderers/webgl/WebGLMaterials.js +1 -1
- package/src/renderers/webgl/WebGLPrograms.js +14 -2
- package/src/renderers/webgl/WebGLTextures.js +97 -12
- package/src/textures/CompressedCubeTexture.js +19 -0
- package/examples/jsm/nodes/functions/BSDF/BRDF_BlinnPhong.js +0 -30
- package/examples/jsm/renderers/common/RenderTarget.js +0 -15
- package/examples/jsm/renderers/common/nodes/NodeRender.js +0 -302
|
@@ -3,16 +3,129 @@ import BRDF_GGX from './BSDF/BRDF_GGX.js';
|
|
|
3
3
|
import DFGApprox from './BSDF/DFGApprox.js';
|
|
4
4
|
import EnvironmentBRDF from './BSDF/EnvironmentBRDF.js';
|
|
5
5
|
import F_Schlick from './BSDF/F_Schlick.js';
|
|
6
|
+
import Schlick_to_F0 from './BSDF/Schlick_to_F0.js';
|
|
6
7
|
import BRDF_Sheen from './BSDF/BRDF_Sheen.js';
|
|
7
|
-
import
|
|
8
|
-
import { diffuseColor, specularColor, roughness, clearcoat, clearcoatRoughness, sheen, sheenRoughness } from '../core/PropertyNode.js';
|
|
8
|
+
import LightingModel from '../core/LightingModel.js';
|
|
9
|
+
import { diffuseColor, specularColor, roughness, clearcoat, clearcoatRoughness, sheen, sheenRoughness, iridescence, iridescenceIOR, iridescenceThickness } from '../core/PropertyNode.js';
|
|
9
10
|
import { transformedNormalView, transformedClearcoatNormalView } from '../accessors/NormalNode.js';
|
|
10
11
|
import { positionViewDirection } from '../accessors/PositionNode.js';
|
|
11
|
-
import {
|
|
12
|
+
import { float, vec3, mat3 } from '../shadernode/ShaderNode.js';
|
|
12
13
|
import { cond } from '../math/CondNode.js';
|
|
14
|
+
import { mix, smoothstep } from '../math/MathNode.js';
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
//
|
|
17
|
+
// Iridescence
|
|
18
|
+
//
|
|
19
|
+
|
|
20
|
+
// XYZ to linear-sRGB color space
|
|
21
|
+
const XYZ_TO_REC709 = mat3(
|
|
22
|
+
3.2404542, - 0.9692660, 0.0556434,
|
|
23
|
+
- 1.5371385, 1.8760108, - 0.2040259,
|
|
24
|
+
- 0.4985314, 0.0415560, 1.0572252
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
// Assume air interface for top
|
|
28
|
+
// Note: We don't handle the case fresnel0 == 1
|
|
29
|
+
const Fresnel0ToIor = ( fresnel0 ) => {
|
|
30
|
+
|
|
31
|
+
const sqrtF0 = fresnel0.sqrt();
|
|
32
|
+
return vec3( 1.0 ).add( sqrtF0 ).div( vec3( 1.0 ).sub( sqrtF0 ) );
|
|
33
|
+
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// ior is a value between 1.0 and 3.0. 1.0 is air interface
|
|
37
|
+
const IorToFresnel0 = ( transmittedIor, incidentIor ) => {
|
|
38
|
+
|
|
39
|
+
return transmittedIor.sub( incidentIor ).div( transmittedIor.add( incidentIor ) ).pow2();
|
|
40
|
+
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// Fresnel equations for dielectric/dielectric interfaces.
|
|
44
|
+
// Ref: https://belcour.github.io/blog/research/2017/05/01/brdf-thin-film.html
|
|
45
|
+
// Evaluation XYZ sensitivity curves in Fourier space
|
|
46
|
+
const evalSensitivity = ( OPD, shift ) => {
|
|
47
|
+
|
|
48
|
+
const phase = OPD.mul( 2.0 * Math.PI * 1.0e-9 );
|
|
49
|
+
const val = vec3( 5.4856e-13, 4.4201e-13, 5.2481e-13 );
|
|
50
|
+
const pos = vec3( 1.6810e+06, 1.7953e+06, 2.2084e+06 );
|
|
51
|
+
const VAR = vec3( 4.3278e+09, 9.3046e+09, 6.6121e+09 );
|
|
52
|
+
|
|
53
|
+
const x = float( 9.7470e-14 * Math.sqrt( 2.0 * Math.PI * 4.5282e+09 ) ).mul( phase.mul( 2.2399e+06 ).add( shift.x ).cos() ).mul( phase.pow2().mul( - 4.5282e+09 ).exp() );
|
|
54
|
+
|
|
55
|
+
let xyz = val.mul( VAR.mul( 2.0 * Math.PI ).sqrt() ).mul( pos.mul( phase ).add( shift ).cos() ).mul( phase.pow2().negate().mul( VAR ).exp() );
|
|
56
|
+
xyz = vec3( xyz.x.add( x ), xyz.y, xyz.z ).div( 1.0685e-7 );
|
|
57
|
+
|
|
58
|
+
const rgb = XYZ_TO_REC709.mul( xyz );
|
|
59
|
+
return rgb;
|
|
60
|
+
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const evalIridescence = ( outsideIOR, eta2, cosTheta1, thinFilmThickness, baseF0 ) => {
|
|
64
|
+
|
|
65
|
+
// Force iridescenceIOR -> outsideIOR when thinFilmThickness -> 0.0
|
|
66
|
+
const iridescenceIOR = mix( outsideIOR, eta2, smoothstep( 0.0, 0.03, thinFilmThickness ) );
|
|
67
|
+
// Evaluate the cosTheta on the base layer (Snell law)
|
|
68
|
+
const sinTheta2Sq = outsideIOR.div( iridescenceIOR ).pow2().mul( float( 1 ).sub( cosTheta1.pow2() ) );
|
|
69
|
+
|
|
70
|
+
// Handle TIR:
|
|
71
|
+
const cosTheta2Sq = float( 1 ).sub( sinTheta2Sq );
|
|
72
|
+
/*if ( cosTheta2Sq < 0.0 ) {
|
|
73
|
+
|
|
74
|
+
return vec3( 1.0 );
|
|
75
|
+
|
|
76
|
+
}*/
|
|
77
|
+
|
|
78
|
+
const cosTheta2 = cosTheta2Sq.sqrt();
|
|
79
|
+
|
|
80
|
+
// First interface
|
|
81
|
+
const R0 = IorToFresnel0( iridescenceIOR, outsideIOR );
|
|
82
|
+
const R12 = F_Schlick( { f0: R0, f90: 1.0, dotVH: cosTheta1 } );
|
|
83
|
+
//const R21 = R12;
|
|
84
|
+
const T121 = R12.oneMinus();
|
|
85
|
+
const phi12 = iridescenceIOR.lessThan( outsideIOR ).cond( Math.PI, 0.0 );
|
|
86
|
+
const phi21 = float( Math.PI ).sub( phi12 );
|
|
87
|
+
|
|
88
|
+
// Second interface
|
|
89
|
+
const baseIOR = Fresnel0ToIor( baseF0.clamp( 0.0, 0.9999 ) ); // guard against 1.0
|
|
90
|
+
const R1 = IorToFresnel0( baseIOR, iridescenceIOR.vec3() );
|
|
91
|
+
const R23 = F_Schlick( { f0: R1, f90: 1.0, dotVH: cosTheta2 } );
|
|
92
|
+
const phi23 = vec3(
|
|
93
|
+
baseIOR.x.lessThan( iridescenceIOR ).cond( Math.PI, 0.0 ),
|
|
94
|
+
baseIOR.y.lessThan( iridescenceIOR ).cond( Math.PI, 0.0 ),
|
|
95
|
+
baseIOR.z.lessThan( iridescenceIOR ).cond( Math.PI, 0.0 )
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
// Phase shift
|
|
99
|
+
const OPD = iridescenceIOR.mul( thinFilmThickness, cosTheta2, 2.0 );
|
|
100
|
+
const phi = vec3( phi21 ).add( phi23 );
|
|
101
|
+
|
|
102
|
+
// Compound terms
|
|
103
|
+
const R123 = R12.mul( R23 ).clamp( 1e-5, 0.9999 );
|
|
104
|
+
const r123 = R123.sqrt();
|
|
105
|
+
const Rs = T121.pow2().mul( R23 ).div( vec3( 1.0 ).sub( R123 ) );
|
|
106
|
+
|
|
107
|
+
// Reflectance term for m = 0 (DC term amplitude)
|
|
108
|
+
const C0 = R12.add( Rs );
|
|
109
|
+
let I = C0;
|
|
110
|
+
|
|
111
|
+
// Reflectance term for m > 0 (pairs of diracs)
|
|
112
|
+
let Cm = Rs.sub( T121 );
|
|
113
|
+
for ( let m = 1; m <= 2; ++ m ) {
|
|
114
|
+
|
|
115
|
+
Cm = Cm.mul( r123 );
|
|
116
|
+
const Sm = evalSensitivity( float( m ).mul( OPD ), float( m ).mul( phi ) ).mul( 2.0 );
|
|
117
|
+
I = I.add( Cm.mul( Sm ) );
|
|
118
|
+
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Since out of gamut colors might be produced, negative color values are clamped to 0.
|
|
122
|
+
return I.max( vec3( 0.0 ) );
|
|
123
|
+
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
//
|
|
127
|
+
// Sheen
|
|
128
|
+
//
|
|
16
129
|
|
|
17
130
|
// This is a curve-fit approxmation to the "Charlie sheen" BRDF integrated over the hemisphere from
|
|
18
131
|
// Estevez and Kulla 2017, "Production Friendly Microfacet Sheen BRDF". The analysis can be found
|
|
@@ -41,164 +154,190 @@ const IBLSheenBRDF = ( normal, viewDir, roughness ) => {
|
|
|
41
154
|
|
|
42
155
|
};
|
|
43
156
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
// http://www.jcgt.org/published/0008/01/03/
|
|
47
|
-
const computeMultiscattering = ( singleScatter, multiScatter, specularF90 = float( 1 ) ) => {
|
|
157
|
+
const clearcoatF0 = vec3( 0.04 );
|
|
158
|
+
const clearcoatF90 = vec3( 1 );
|
|
48
159
|
|
|
49
|
-
|
|
160
|
+
//
|
|
50
161
|
|
|
51
|
-
|
|
162
|
+
class PhysicalLightingModel extends LightingModel {
|
|
52
163
|
|
|
53
|
-
|
|
54
|
-
const Ems = Ess.oneMinus();
|
|
164
|
+
constructor( clearcoat = true, sheen = true, iridescence = true ) {
|
|
55
165
|
|
|
56
|
-
|
|
57
|
-
const Fms = FssEss.mul( Favg ).div( Ems.mul( Favg ).oneMinus() );
|
|
166
|
+
super();
|
|
58
167
|
|
|
59
|
-
|
|
60
|
-
|
|
168
|
+
this.clearcoat = clearcoat;
|
|
169
|
+
this.sheen = sheen;
|
|
170
|
+
this.iridescence = iridescence;
|
|
61
171
|
|
|
62
|
-
|
|
172
|
+
this.clearcoatRadiance = null;
|
|
173
|
+
this.clearcoatSpecular = null;
|
|
174
|
+
this.sheenSpecular = null;
|
|
175
|
+
this.iridescenceFresnel = null;
|
|
176
|
+
this.iridescenceF0 = null;
|
|
63
177
|
|
|
64
|
-
|
|
178
|
+
}
|
|
65
179
|
|
|
66
|
-
|
|
180
|
+
init( { reflectedLight } ) {
|
|
67
181
|
|
|
68
|
-
|
|
69
|
-
context.reflectedLight.clearcoatSpecular = vec3().temp();
|
|
182
|
+
if ( this.clearcoat === true ) {
|
|
70
183
|
|
|
71
|
-
|
|
184
|
+
this.clearcoatRadiance = vec3().temp();
|
|
185
|
+
this.clearcoatSpecular = vec3().temp();
|
|
72
186
|
|
|
73
|
-
|
|
74
|
-
dotVH: dotNVcc,
|
|
75
|
-
f0: clearcoatF0,
|
|
76
|
-
f90: clearcoatF90
|
|
77
|
-
} );
|
|
187
|
+
const dotNVcc = transformedClearcoatNormalView.dot( positionViewDirection ).clamp();
|
|
78
188
|
|
|
79
|
-
|
|
80
|
-
|
|
189
|
+
const Fcc = F_Schlick( {
|
|
190
|
+
dotVH: dotNVcc,
|
|
191
|
+
f0: clearcoatF0,
|
|
192
|
+
f90: clearcoatF90
|
|
193
|
+
} );
|
|
81
194
|
|
|
82
|
-
|
|
195
|
+
const outgoingLight = reflectedLight.total;
|
|
196
|
+
const clearcoatLight = outgoingLight.mul( clearcoat.mul( Fcc ).oneMinus() ).add( this.clearcoatSpecular.mul( clearcoat ) );
|
|
83
197
|
|
|
84
|
-
|
|
198
|
+
outgoingLight.assign( clearcoatLight );
|
|
85
199
|
|
|
86
|
-
|
|
200
|
+
}
|
|
87
201
|
|
|
88
|
-
|
|
202
|
+
if ( this.sheen === true ) {
|
|
89
203
|
|
|
90
|
-
|
|
204
|
+
this.sheenSpecular = vec3().temp();
|
|
91
205
|
|
|
92
|
-
|
|
93
|
-
const sheenLight = outgoingLight.mul( sheenEnergyComp ).add( context.reflectedLight.sheenSpecular );
|
|
206
|
+
const outgoingLight = reflectedLight.total;
|
|
94
207
|
|
|
95
|
-
|
|
208
|
+
const sheenEnergyComp = sheen.r.max( sheen.g ).max( sheen.b ).mul( 0.157 ).oneMinus();
|
|
209
|
+
const sheenLight = outgoingLight.mul( sheenEnergyComp ).add( this.sheenSpecular );
|
|
96
210
|
|
|
97
|
-
|
|
211
|
+
outgoingLight.assign( sheenLight );
|
|
98
212
|
|
|
99
|
-
}
|
|
213
|
+
}
|
|
100
214
|
|
|
101
|
-
|
|
215
|
+
if ( this.iridescence === true ) {
|
|
102
216
|
|
|
103
|
-
|
|
217
|
+
const dotNVi = transformedNormalView.dot( positionViewDirection ).clamp();
|
|
104
218
|
|
|
105
|
-
|
|
219
|
+
this.iridescenceFresnel = evalIridescence( float( 1.0 ), iridescenceIOR, dotNVi, iridescenceThickness, specularColor );
|
|
220
|
+
this.iridescenceF0 = Schlick_to_F0( { f: this.iridescenceFresnel, f90: 1.0, dotVH: dotNVi } );
|
|
106
221
|
|
|
107
|
-
|
|
108
|
-
sheen,
|
|
109
|
-
IBLSheenBRDF( transformedNormalView, positionViewDirection, sheenRoughness )
|
|
110
|
-
) );
|
|
222
|
+
}
|
|
111
223
|
|
|
112
224
|
}
|
|
113
225
|
|
|
114
|
-
|
|
226
|
+
// Fdez-Agüera's "Multiple-Scattering Microfacet Model for Real-Time Image Based Lighting"
|
|
227
|
+
// Approximates multiscattering in order to preserve energy.
|
|
228
|
+
// http://www.jcgt.org/published/0008/01/03/
|
|
115
229
|
|
|
116
|
-
|
|
230
|
+
computeMultiscattering( singleScatter, multiScatter, specularF90 = float( 1 ) ) {
|
|
117
231
|
|
|
118
|
-
const
|
|
119
|
-
dotNV: dotNVcc,
|
|
120
|
-
specularColor: clearcoatF0,
|
|
121
|
-
specularF90: clearcoatF90,
|
|
122
|
-
roughness: clearcoatRoughness
|
|
123
|
-
} );
|
|
232
|
+
const fab = DFGApprox( { roughness } );
|
|
124
233
|
|
|
125
|
-
|
|
234
|
+
const Fr = this.iridescenceF0 ? iridescence.mix( specularColor, this.iridescenceF0 ) : specularColor;
|
|
126
235
|
|
|
127
|
-
|
|
236
|
+
const FssEss = Fr.mul( fab.x ).add( specularF90.mul( fab.y ) );
|
|
128
237
|
|
|
129
|
-
|
|
238
|
+
const Ess = fab.x.add( fab.y );
|
|
239
|
+
const Ems = Ess.oneMinus();
|
|
130
240
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
const cosineWeightedIrradiance = iblIrradiance.mul( 1 / Math.PI );
|
|
241
|
+
const Favg = specularColor.add( specularColor.oneMinus().mul( 0.047619 ) ); // 1/21
|
|
242
|
+
const Fms = FssEss.mul( Favg ).div( Ems.mul( Favg ).oneMinus() );
|
|
134
243
|
|
|
135
|
-
|
|
244
|
+
singleScatter.addAssign( FssEss );
|
|
245
|
+
multiScatter.addAssign( Fms.mul( Ems ) );
|
|
136
246
|
|
|
137
|
-
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
direct( { lightDirection, lightColor, reflectedLight } ) {
|
|
138
250
|
|
|
139
|
-
|
|
251
|
+
const dotNL = transformedNormalView.dot( lightDirection ).clamp();
|
|
252
|
+
const irradiance = dotNL.mul( lightColor );
|
|
140
253
|
|
|
141
|
-
|
|
142
|
-
reflectedLight.indirectSpecular.addAssign( multiScattering.mul( cosineWeightedIrradiance ) );
|
|
254
|
+
if ( this.sheen === true ) {
|
|
143
255
|
|
|
144
|
-
|
|
256
|
+
this.sheenSpecular.addAssign( irradiance.mul( BRDF_Sheen( { lightDirection } ) ) );
|
|
145
257
|
|
|
146
|
-
}
|
|
258
|
+
}
|
|
147
259
|
|
|
148
|
-
|
|
260
|
+
if ( this.clearcoat === true ) {
|
|
149
261
|
|
|
150
|
-
|
|
262
|
+
const dotNLcc = transformedClearcoatNormalView.dot( lightDirection ).clamp();
|
|
263
|
+
const ccIrradiance = dotNLcc.mul( lightColor );
|
|
151
264
|
|
|
152
|
-
|
|
265
|
+
this.clearcoatSpecular.addAssign( ccIrradiance.mul( BRDF_GGX( { lightDirection, f0: clearcoatF0, f90: clearcoatF90, roughness: clearcoatRoughness, normalView: transformedClearcoatNormalView } ) ) );
|
|
153
266
|
|
|
154
|
-
}
|
|
267
|
+
}
|
|
155
268
|
|
|
156
|
-
|
|
269
|
+
reflectedLight.directDiffuse.addAssign( irradiance.mul( BRDF_Lambert( { diffuseColor: diffuseColor.rgb } ) ) );
|
|
157
270
|
|
|
158
|
-
|
|
271
|
+
reflectedLight.directSpecular.addAssign( irradiance.mul( BRDF_GGX( { lightDirection, f0: specularColor, f90: 1, roughness, iridescence: this.iridescence, iridescenceFresnel: this.iridescenceFresnel } ) ) );
|
|
159
272
|
|
|
160
|
-
|
|
161
|
-
const irradiance = dotNL.mul( lightColor );
|
|
273
|
+
}
|
|
162
274
|
|
|
163
|
-
|
|
275
|
+
indirectDiffuse( { irradiance, reflectedLight } ) {
|
|
164
276
|
|
|
165
|
-
reflectedLight.
|
|
277
|
+
reflectedLight.indirectDiffuse.addAssign( irradiance.mul( BRDF_Lambert( { diffuseColor } ) ) );
|
|
166
278
|
|
|
167
279
|
}
|
|
168
280
|
|
|
169
|
-
|
|
281
|
+
indirectSpecular( { radiance, iblIrradiance, reflectedLight, } ) {
|
|
170
282
|
|
|
171
|
-
|
|
172
|
-
const ccIrradiance = dotNLcc.mul( lightColor );
|
|
283
|
+
if ( this.sheen === true ) {
|
|
173
284
|
|
|
174
|
-
|
|
285
|
+
this.sheenSpecular.addAssign( iblIrradiance.mul(
|
|
286
|
+
sheen,
|
|
287
|
+
IBLSheenBRDF( transformedNormalView, positionViewDirection, sheenRoughness )
|
|
288
|
+
) );
|
|
175
289
|
|
|
176
|
-
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
if ( this.clearcoat === true ) {
|
|
293
|
+
|
|
294
|
+
const dotNVcc = transformedClearcoatNormalView.dot( positionViewDirection ).clamp();
|
|
295
|
+
|
|
296
|
+
const clearcoatEnv = EnvironmentBRDF( {
|
|
297
|
+
dotNV: dotNVcc,
|
|
298
|
+
specularColor: clearcoatF0,
|
|
299
|
+
specularF90: clearcoatF90,
|
|
300
|
+
roughness: clearcoatRoughness
|
|
301
|
+
} );
|
|
177
302
|
|
|
178
|
-
|
|
303
|
+
this.clearcoatSpecular.addAssign( this.clearcoatRadiance.mul( clearcoatEnv ) );
|
|
179
304
|
|
|
180
|
-
|
|
305
|
+
}
|
|
181
306
|
|
|
182
|
-
|
|
307
|
+
// Both indirect specular and indirect diffuse light accumulate here
|
|
183
308
|
|
|
184
|
-
const
|
|
309
|
+
const singleScattering = vec3().temp();
|
|
310
|
+
const multiScattering = vec3().temp();
|
|
311
|
+
const cosineWeightedIrradiance = iblIrradiance.mul( 1 / Math.PI );
|
|
185
312
|
|
|
186
|
-
|
|
313
|
+
this.computeMultiscattering( singleScattering, multiScattering );
|
|
187
314
|
|
|
188
|
-
|
|
315
|
+
const totalScattering = singleScattering.add( multiScattering );
|
|
189
316
|
|
|
190
|
-
|
|
191
|
-
const aoExp = roughness.mul( - 16.0 ).oneMinus().negate().exp2();
|
|
317
|
+
const diffuse = diffuseColor.mul( totalScattering.r.max( totalScattering.g ).max( totalScattering.b ).oneMinus() );
|
|
192
318
|
|
|
193
|
-
|
|
319
|
+
reflectedLight.indirectSpecular.addAssign( radiance.mul( singleScattering ) );
|
|
320
|
+
reflectedLight.indirectSpecular.addAssign( multiScattering.mul( cosineWeightedIrradiance ) );
|
|
194
321
|
|
|
195
|
-
|
|
322
|
+
reflectedLight.indirectDiffuse.addAssign( diffuse.mul( cosineWeightedIrradiance ) );
|
|
196
323
|
|
|
197
|
-
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
ambientOcclusion( { ambientOcclusion, reflectedLight } ) {
|
|
327
|
+
|
|
328
|
+
const dotNV = transformedNormalView.dot( positionViewDirection ).clamp(); // @ TODO: Move to core dotNV
|
|
329
|
+
|
|
330
|
+
const aoNV = dotNV.add( ambientOcclusion );
|
|
331
|
+
const aoExp = roughness.mul( - 16.0 ).oneMinus().negate().exp2();
|
|
198
332
|
|
|
333
|
+
const aoNode = ambientOcclusion.sub( aoNV.pow( aoExp ).oneMinus() ).clamp();
|
|
199
334
|
|
|
200
|
-
|
|
335
|
+
reflectedLight.indirectDiffuse.mulAssign( ambientOcclusion );
|
|
336
|
+
|
|
337
|
+
reflectedLight.indirectSpecular.mulAssign( aoNode );
|
|
338
|
+
|
|
339
|
+
}
|
|
201
340
|
|
|
202
|
-
|
|
341
|
+
}
|
|
203
342
|
|
|
204
|
-
export default
|
|
343
|
+
export default PhysicalLightingModel;
|
|
@@ -44,8 +44,8 @@ class RangeNode extends Node {
|
|
|
44
44
|
|
|
45
45
|
if ( object.isInstancedMesh === true ) {
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
const minValue = this.minNode.value;
|
|
48
|
+
const maxValue = this.maxNode.value;
|
|
49
49
|
|
|
50
50
|
const minLength = builder.getTypeLength( getValueType( minValue ) );
|
|
51
51
|
const maxLength = builder.getTypeLength( getValueType( maxValue ) );
|
|
@@ -16,12 +16,25 @@ class ComputeNode extends Node {
|
|
|
16
16
|
this.workgroupSize = workgroupSize;
|
|
17
17
|
this.dispatchCount = 0;
|
|
18
18
|
|
|
19
|
+
this.version = 1;
|
|
19
20
|
this.updateType = NodeUpdateType.OBJECT;
|
|
20
21
|
|
|
21
22
|
this.updateDispatchCount();
|
|
22
23
|
|
|
23
24
|
}
|
|
24
25
|
|
|
26
|
+
dispose() {
|
|
27
|
+
|
|
28
|
+
this.dispatchEvent( { type: 'dispose' } );
|
|
29
|
+
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
set needsUpdate( value ) {
|
|
33
|
+
|
|
34
|
+
if ( value === true ) this.version ++;
|
|
35
|
+
|
|
36
|
+
}
|
|
37
|
+
|
|
25
38
|
updateDispatchCount() {
|
|
26
39
|
|
|
27
40
|
const { count, workgroupSize } = this;
|
|
@@ -14,7 +14,7 @@ class AONode extends LightingNode {
|
|
|
14
14
|
construct( builder ) {
|
|
15
15
|
|
|
16
16
|
const aoIntensity = 1;
|
|
17
|
-
const aoNode = this.aoNode.sub( 1.0 ).mul( aoIntensity ).add( 1.0 );
|
|
17
|
+
const aoNode = this.aoNode.x.sub( 1.0 ).mul( aoIntensity ).add( 1.0 );
|
|
18
18
|
|
|
19
19
|
builder.context.ambientOcclusion.mulAssign( aoNode );
|
|
20
20
|
|
|
@@ -2,14 +2,14 @@ import LightingNode from './LightingNode.js';
|
|
|
2
2
|
import { NodeUpdateType } from '../core/constants.js';
|
|
3
3
|
import { uniform } from '../core/UniformNode.js';
|
|
4
4
|
import { addNodeClass } from '../core/Node.js';
|
|
5
|
-
import { vec3 } from '../shadernode/ShaderNode.js';
|
|
5
|
+
import { /*vec2,*/ vec3 } from '../shadernode/ShaderNode.js';
|
|
6
6
|
import { reference } from '../accessors/ReferenceNode.js';
|
|
7
7
|
import { texture } from '../accessors/TextureNode.js';
|
|
8
8
|
import { positionWorld } from '../accessors/PositionNode.js';
|
|
9
|
-
|
|
10
|
-
import {
|
|
9
|
+
import { normalWorld } from '../accessors/NormalNode.js';
|
|
10
|
+
//import { add } from '../math/OperatorNode.js';
|
|
11
11
|
|
|
12
|
-
import { Color, DepthTexture, NearestFilter } from 'three';
|
|
12
|
+
import { Color, DepthTexture, NearestFilter, LessCompare } from 'three';
|
|
13
13
|
|
|
14
14
|
let depthMaterial = null;
|
|
15
15
|
|
|
@@ -53,7 +53,7 @@ class AnalyticLightNode extends LightingNode {
|
|
|
53
53
|
depthTexture.magFilter = NearestFilter;
|
|
54
54
|
depthTexture.image.width = shadow.mapSize.width;
|
|
55
55
|
depthTexture.image.height = shadow.mapSize.height;
|
|
56
|
-
|
|
56
|
+
depthTexture.compareFunction = LessCompare;
|
|
57
57
|
|
|
58
58
|
rtt.depthTexture = depthTexture;
|
|
59
59
|
|
|
@@ -62,31 +62,69 @@ class AnalyticLightNode extends LightingNode {
|
|
|
62
62
|
//
|
|
63
63
|
|
|
64
64
|
const bias = reference( 'bias', 'float', shadow );
|
|
65
|
+
const normalBias = reference( 'normalBias', 'float', shadow );
|
|
65
66
|
|
|
66
|
-
|
|
67
|
-
//bias = mix( bias, 0, diffuseFactor );
|
|
68
|
-
|
|
69
|
-
let shadowCoord = uniform( shadow.matrix ).mul( positionWorld );
|
|
67
|
+
let shadowCoord = uniform( shadow.matrix ).mul( positionWorld.add( normalWorld.mul( normalBias ) ) );
|
|
70
68
|
shadowCoord = shadowCoord.xyz.div( shadowCoord.w );
|
|
71
69
|
|
|
70
|
+
const frustumTest = shadowCoord.x.greaterThanEqual( 0 )
|
|
71
|
+
.and( shadowCoord.x.lessThanEqual( 1 ) )
|
|
72
|
+
.and( shadowCoord.y.greaterThanEqual( 0 ) )
|
|
73
|
+
.and( shadowCoord.y.lessThanEqual( 1 ) )
|
|
74
|
+
.and( shadowCoord.z.lessThanEqual( 1 ) );
|
|
75
|
+
|
|
72
76
|
shadowCoord = vec3(
|
|
73
77
|
shadowCoord.x,
|
|
74
|
-
shadowCoord.y.oneMinus(),
|
|
75
|
-
shadowCoord.z
|
|
78
|
+
shadowCoord.y.oneMinus(), // WebGPU: Flip Y
|
|
79
|
+
shadowCoord.z.add( bias ).mul( 2 ).sub( 1 ) // WebGPU: Convertion [ 0, 1 ] to [ - 1, 1 ]
|
|
76
80
|
);
|
|
77
81
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
shadowNode =
|
|
84
|
-
|
|
85
|
-
|
|
82
|
+
const textureCompare = ( depthTexture, shadowCoord, compare ) => texture( depthTexture, shadowCoord ).compare( compare );
|
|
83
|
+
//const textureCompare = ( depthTexture, shadowCoord, compare ) => compare.step( texture( depthTexture, shadowCoord ) );
|
|
84
|
+
|
|
85
|
+
// BasicShadowMap
|
|
86
|
+
|
|
87
|
+
shadowNode = textureCompare( depthTexture, shadowCoord.xy, shadowCoord.z );
|
|
88
|
+
|
|
89
|
+
// PCFShadowMap
|
|
90
|
+
/*
|
|
91
|
+
const mapSize = reference( 'mapSize', 'vec2', shadow );
|
|
92
|
+
const radius = reference( 'radius', 'float', shadow );
|
|
93
|
+
|
|
94
|
+
const texelSize = vec2( 1 ).div( mapSize );
|
|
95
|
+
const dx0 = texelSize.x.negate().mul( radius );
|
|
96
|
+
const dy0 = texelSize.y.negate().mul( radius );
|
|
97
|
+
const dx1 = texelSize.x.mul( radius );
|
|
98
|
+
const dy1 = texelSize.y.mul( radius );
|
|
99
|
+
const dx2 = dx0.mul( 2 );
|
|
100
|
+
const dy2 = dy0.mul( 2 );
|
|
101
|
+
const dx3 = dx1.mul( 2 );
|
|
102
|
+
const dy3 = dy1.mul( 2 );
|
|
103
|
+
|
|
104
|
+
shadowNode = add(
|
|
105
|
+
textureCompare( depthTexture, shadowCoord.xy.add( vec2( dx0, dy0 ) ), shadowCoord.z ),
|
|
106
|
+
textureCompare( depthTexture, shadowCoord.xy.add( vec2( 0, dy0 ) ), shadowCoord.z ),
|
|
107
|
+
textureCompare( depthTexture, shadowCoord.xy.add( vec2( dx1, dy0 ) ), shadowCoord.z ),
|
|
108
|
+
textureCompare( depthTexture, shadowCoord.xy.add( vec2( dx2, dy2 ) ), shadowCoord.z ),
|
|
109
|
+
textureCompare( depthTexture, shadowCoord.xy.add( vec2( 0, dy2 ) ), shadowCoord.z ),
|
|
110
|
+
textureCompare( depthTexture, shadowCoord.xy.add( vec2( dx3, dy2 ) ), shadowCoord.z ),
|
|
111
|
+
textureCompare( depthTexture, shadowCoord.xy.add( vec2( dx0, 0 ) ), shadowCoord.z ),
|
|
112
|
+
textureCompare( depthTexture, shadowCoord.xy.add( vec2( dx2, 0 ) ), shadowCoord.z ),
|
|
113
|
+
textureCompare( depthTexture, shadowCoord.xy, shadowCoord.z ),
|
|
114
|
+
textureCompare( depthTexture, shadowCoord.xy.add( vec2( dx3, 0 ) ), shadowCoord.z ),
|
|
115
|
+
textureCompare( depthTexture, shadowCoord.xy.add( vec2( dx1, 0 ) ), shadowCoord.z ),
|
|
116
|
+
textureCompare( depthTexture, shadowCoord.xy.add( vec2( dx2, dy3 ) ), shadowCoord.z ),
|
|
117
|
+
textureCompare( depthTexture, shadowCoord.xy.add( vec2( 0, dy3 ) ), shadowCoord.z ),
|
|
118
|
+
textureCompare( depthTexture, shadowCoord.xy.add( vec2( dx3, dy3 ) ), shadowCoord.z ),
|
|
119
|
+
textureCompare( depthTexture, shadowCoord.xy.add( vec2( dx0, dy1 ) ), shadowCoord.z ),
|
|
120
|
+
textureCompare( depthTexture, shadowCoord.xy.add( vec2( 0, dy1 ) ), shadowCoord.z ),
|
|
121
|
+
textureCompare( depthTexture, shadowCoord.xy.add( vec2( dx1, dy1 ) ), shadowCoord.z )
|
|
122
|
+
).mul( 1 / 17 );
|
|
123
|
+
*/
|
|
86
124
|
//
|
|
87
125
|
|
|
88
126
|
this.rtt = rtt;
|
|
89
|
-
this.colorNode = this.colorNode.mul( shadowNode );
|
|
127
|
+
this.colorNode = this.colorNode.mul( frustumTest.mix( 1, shadowNode ) );
|
|
90
128
|
|
|
91
129
|
this.shadowNode = shadowNode;
|
|
92
130
|
|
|
@@ -17,20 +17,17 @@ class DirectionalLightNode extends AnalyticLightNode {
|
|
|
17
17
|
|
|
18
18
|
super.construct( builder );
|
|
19
19
|
|
|
20
|
+
const lightingModel = builder.context.lightingModel;
|
|
21
|
+
|
|
20
22
|
const lightColor = this.colorNode;
|
|
21
23
|
const lightDirection = lightTargetDirection( this.light );
|
|
22
|
-
const lightingModelFunctionNode = builder.context.lightingModelNode;
|
|
23
24
|
const reflectedLight = builder.context.reflectedLight;
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
reflectedLight
|
|
31
|
-
} );
|
|
32
|
-
|
|
33
|
-
}
|
|
26
|
+
lightingModel.direct( {
|
|
27
|
+
lightDirection,
|
|
28
|
+
lightColor,
|
|
29
|
+
reflectedLight
|
|
30
|
+
} );
|
|
34
31
|
|
|
35
32
|
}
|
|
36
33
|
|