super-three 0.157.1 → 0.158.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/README.md +6 -4
- package/build/three.cjs +1013 -790
- package/build/three.js +1013 -790
- package/build/three.min.js +1 -1
- package/build/three.module.js +1008 -791
- package/build/three.module.min.js +1 -1
- package/examples/jsm/Addons.js +290 -0
- package/examples/jsm/controls/FlyControls.js +26 -0
- package/examples/jsm/controls/OrbitControls.js +12 -1
- package/examples/jsm/controls/TransformControls.js +27 -11
- package/examples/jsm/csm/CSMShader.js +1 -1
- package/examples/jsm/exporters/GLTFExporter.js +72 -2
- package/examples/jsm/geometries/InstancedPointsGeometry.js +174 -0
- package/examples/jsm/geometries/SDFGeometryGenerator.js +144 -0
- package/examples/jsm/libs/lottie_canvas.module.js +6 -1
- package/examples/jsm/libs/opentype.module.js +13 -75
- package/examples/jsm/libs/surfaceNet.js +201 -0
- package/examples/jsm/loaders/GLTFLoader.js +12 -3
- package/examples/jsm/loaders/LUTImageLoader.js +162 -0
- package/examples/jsm/loaders/lwo/IFFParser.js +89 -93
- package/examples/jsm/materials/MeshGouraudMaterial.js +2 -0
- package/examples/jsm/math/Capsule.js +0 -55
- package/examples/jsm/math/Octree.js +70 -3
- package/examples/jsm/modifiers/SimplifyModifier.js +103 -11
- package/examples/jsm/modifiers/TessellateModifier.js +3 -3
- package/examples/jsm/nodes/Nodes.js +6 -6
- package/examples/jsm/nodes/accessors/CubeTextureNode.js +3 -3
- package/examples/jsm/nodes/accessors/InstanceNode.js +3 -3
- package/examples/jsm/nodes/accessors/InstancedPointsMaterialNode.js +21 -0
- package/examples/jsm/nodes/accessors/MaterialNode.js +68 -31
- package/examples/jsm/nodes/accessors/ModelNode.js +1 -2
- package/examples/jsm/nodes/accessors/MorphNode.js +5 -5
- package/examples/jsm/nodes/accessors/NormalNode.js +1 -1
- package/examples/jsm/nodes/accessors/PositionNode.js +1 -1
- package/examples/jsm/nodes/accessors/SkinningNode.js +13 -3
- package/examples/jsm/nodes/accessors/TextureNode.js +3 -3
- package/examples/jsm/nodes/code/FunctionNode.js +1 -1
- package/examples/jsm/nodes/core/AssignNode.js +72 -0
- package/examples/jsm/nodes/core/LightingModel.js +3 -1
- package/examples/jsm/nodes/core/Node.js +7 -12
- package/examples/jsm/nodes/core/NodeBuilder.js +126 -16
- package/examples/jsm/nodes/core/NodeUtils.js +4 -2
- package/examples/jsm/nodes/core/OutputStructNode.js +1 -1
- package/examples/jsm/nodes/core/ParameterNode.js +33 -0
- package/examples/jsm/nodes/core/PropertyNode.js +4 -10
- package/examples/jsm/nodes/core/StackNode.js +7 -17
- package/examples/jsm/nodes/core/TempNode.js +1 -1
- package/examples/jsm/nodes/core/VarNode.js +6 -35
- package/examples/jsm/nodes/core/VaryingNode.js +2 -0
- package/examples/jsm/nodes/display/BumpMapNode.js +35 -13
- package/examples/jsm/nodes/display/NormalMapNode.js +3 -1
- package/examples/jsm/nodes/display/ViewportNode.js +14 -4
- package/examples/jsm/nodes/functions/BSDF/BRDF_Sheen.js +20 -6
- package/examples/jsm/nodes/functions/BSDF/DFGApprox.js +8 -7
- package/examples/jsm/nodes/functions/BSDF/D_GGX.js +8 -3
- package/examples/jsm/nodes/functions/BSDF/Schlick_to_F0.js +8 -0
- package/examples/jsm/nodes/functions/BSDF/V_GGX_SmithCorrelated.js +8 -0
- package/examples/jsm/nodes/functions/PhysicalLightingModel.js +93 -43
- package/examples/jsm/nodes/gpgpu/ComputeNode.js +2 -2
- package/examples/jsm/nodes/lighting/AmbientLightNode.js +1 -1
- package/examples/jsm/nodes/lighting/AnalyticLightNode.js +19 -5
- package/examples/jsm/nodes/lighting/DirectionalLightNode.js +1 -1
- package/examples/jsm/nodes/lighting/EnvironmentNode.js +0 -6
- package/examples/jsm/nodes/lighting/LightingContextNode.js +21 -57
- package/examples/jsm/nodes/lighting/LightsNode.js +62 -4
- package/examples/jsm/nodes/lighting/PointLightNode.js +1 -1
- package/examples/jsm/nodes/lighting/SpotLightNode.js +1 -1
- package/examples/jsm/nodes/materials/InstancedPointsNodeMaterial.js +162 -0
- package/examples/jsm/nodes/materials/Line2NodeMaterial.js +70 -71
- package/examples/jsm/nodes/materials/LineDashedNodeMaterial.js +5 -5
- package/examples/jsm/nodes/materials/Materials.js +1 -0
- package/examples/jsm/nodes/materials/MeshNormalNodeMaterial.js +2 -2
- package/examples/jsm/nodes/materials/MeshPhongNodeMaterial.js +3 -3
- package/examples/jsm/nodes/materials/MeshPhysicalNodeMaterial.js +47 -20
- package/examples/jsm/nodes/materials/MeshStandardNodeMaterial.js +6 -6
- package/examples/jsm/nodes/materials/NodeMaterial.js +17 -20
- package/examples/jsm/nodes/materialx/lib/mx_noise.js +5 -5
- package/examples/jsm/nodes/math/OperatorNode.js +5 -21
- package/examples/jsm/nodes/shadernode/ShaderNode.js +128 -9
- package/examples/jsm/nodes/utils/ArrayElementNode.js +2 -0
- package/examples/jsm/nodes/utils/DiscardNode.js +3 -2
- package/examples/jsm/nodes/utils/JoinNode.js +11 -1
- package/examples/jsm/nodes/utils/LoopNode.js +36 -24
- package/examples/jsm/nodes/utils/SplitNode.js +2 -0
- package/examples/jsm/objects/BatchedMesh.js +586 -0
- package/examples/jsm/objects/InstancedPoints.js +21 -0
- package/examples/jsm/objects/Lensflare.js +20 -0
- package/examples/jsm/objects/ReflectorForSSRPass.js +3 -0
- package/examples/jsm/objects/Refractor.js +3 -0
- package/examples/jsm/objects/Sky.js +5 -3
- package/examples/jsm/objects/Water.js +5 -2
- package/examples/jsm/objects/Water2.js +3 -0
- package/examples/jsm/physics/AmmoPhysics.js +21 -0
- package/examples/jsm/physics/RapierPhysics.js +21 -0
- package/examples/jsm/postprocessing/BokehPass.js +3 -2
- package/examples/jsm/postprocessing/LUTPass.js +2 -1
- package/examples/jsm/postprocessing/OutputPass.js +1 -0
- package/examples/jsm/postprocessing/Pass.js +14 -3
- package/examples/jsm/postprocessing/SAOPass.js +0 -1
- package/examples/jsm/postprocessing/SMAAPass.js +0 -2
- package/examples/jsm/postprocessing/TAARenderPass.js +1 -2
- package/examples/jsm/renderers/CSS3DRenderer.js +3 -9
- package/examples/jsm/renderers/SVGRenderer.js +9 -6
- package/examples/jsm/renderers/common/Bindings.js +1 -1
- package/examples/jsm/renderers/common/RenderObject.js +8 -1
- package/examples/jsm/renderers/common/RenderObjects.js +1 -1
- package/examples/jsm/renderers/common/Textures.js +4 -36
- package/examples/jsm/renderers/common/nodes/Nodes.js +53 -18
- package/examples/jsm/renderers/webgl/WebGLBackend.js +291 -50
- package/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js +88 -12
- package/examples/jsm/renderers/webgl/utils/WebGLAttributeUtils.js +40 -5
- package/examples/jsm/renderers/webgl/utils/WebGLState.js +14 -2
- package/examples/jsm/renderers/webgpu/WebGPUBackend.js +2 -0
- package/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js +36 -4
- package/examples/jsm/shaders/ACESFilmicToneMappingShader.js +2 -0
- package/examples/jsm/shaders/AfterimageShader.js +2 -0
- package/examples/jsm/shaders/BasicShader.js +2 -0
- package/examples/jsm/shaders/BlendShader.js +2 -0
- package/examples/jsm/shaders/BokehShader.js +2 -0
- package/examples/jsm/shaders/BokehShader2.js +4 -0
- package/examples/jsm/shaders/BrightnessContrastShader.js +2 -0
- package/examples/jsm/shaders/ColorCorrectionShader.js +2 -0
- package/examples/jsm/shaders/DOFMipMapShader.js +2 -0
- package/examples/jsm/shaders/DepthLimitedBlurShader.js +5 -0
- package/examples/jsm/shaders/FXAAShader.js +2 -0
- package/examples/jsm/shaders/FilmShader.js +1 -1
- package/examples/jsm/shaders/FocusShader.js +2 -0
- package/examples/jsm/shaders/FreiChenShader.js +2 -0
- package/examples/jsm/shaders/GodRaysShader.js +8 -0
- package/examples/jsm/shaders/HalftoneShader.js +2 -0
- package/examples/jsm/shaders/HorizontalTiltShiftShader.js +2 -0
- package/examples/jsm/shaders/HueSaturationShader.js +2 -0
- package/examples/jsm/shaders/KaleidoShader.js +2 -0
- package/examples/jsm/shaders/LuminosityHighPassShader.js +2 -0
- package/examples/jsm/shaders/LuminosityShader.js +2 -0
- package/examples/jsm/shaders/MMDToonShader.js +2 -0
- package/examples/jsm/shaders/MirrorShader.js +2 -0
- package/examples/jsm/shaders/NormalMapShader.js +2 -0
- package/examples/jsm/shaders/OutputShader.js +4 -5
- package/examples/jsm/shaders/SAOShader.js +5 -0
- package/examples/jsm/shaders/SMAAShader.js +6 -0
- package/examples/jsm/shaders/SSAOShader.js +6 -0
- package/examples/jsm/shaders/SSRShader.js +6 -0
- package/examples/jsm/shaders/SobelOperatorShader.js +2 -0
- package/examples/jsm/shaders/SubsurfaceScatteringShader.js +2 -0
- package/examples/jsm/shaders/TechnicolorShader.js +2 -0
- package/examples/jsm/shaders/TriangleBlurShader.js +2 -0
- package/examples/jsm/shaders/UnpackDepthRGBAShader.js +2 -0
- package/examples/jsm/shaders/VelocityShader.js +2 -0
- package/examples/jsm/shaders/VerticalTiltShiftShader.js +2 -0
- package/examples/jsm/shaders/WaterRefractionShader.js +2 -0
- package/examples/jsm/transpiler/AST.js +231 -0
- package/examples/jsm/transpiler/GLSLDecoder.js +899 -0
- package/examples/jsm/transpiler/ShaderToyDecoder.js +49 -0
- package/examples/jsm/transpiler/TSLEncoder.js +611 -0
- package/examples/jsm/transpiler/Transpiler.js +18 -0
- package/examples/jsm/webxr/VRButton.js +1 -1
- package/examples/jsm/webxr/XRButton.js +7 -5
- package/examples/jsm/webxr/XREstimatedLight.js +1 -1
- package/package.json +4 -1
- package/src/constants.js +7 -1
- package/src/extras/PMREMGenerator.js +7 -1
- package/src/loaders/MaterialLoader.js +10 -2
- package/src/materials/Material.js +27 -13
- package/src/math/Box3.js +35 -18
- package/src/math/Vector3.js +11 -12
- package/src/objects/SkinnedMesh.js +6 -7
- package/src/renderers/WebGLRenderer.js +142 -25
- package/src/renderers/shaders/ShaderChunk/aomap_fragment.glsl.js +8 -0
- package/src/renderers/shaders/ShaderChunk/bumpmap_pars_fragment.glsl.js +3 -2
- package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +8 -6
- package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +2 -2
- package/src/renderers/webgl/WebGLProgram.js +80 -50
- package/src/renderers/webgl/WebGLPrograms.js +3 -0
- package/src/renderers/webgl/WebGLState.js +25 -4
- package/examples/jsm/nodes/accessors/ExtendedMaterialNode.js +0 -76
- package/examples/jsm/nodes/accessors/LineMaterialNode.js +0 -29
|
@@ -1,26 +1,45 @@
|
|
|
1
1
|
import TempNode from '../core/TempNode.js';
|
|
2
|
-
import { texture } from '../accessors/TextureNode.js';
|
|
3
2
|
import { addNodeClass } from '../core/Node.js';
|
|
4
3
|
import { uv } from '../accessors/UVNode.js';
|
|
5
4
|
import { normalView } from '../accessors/NormalNode.js';
|
|
6
5
|
import { positionView } from '../accessors/PositionNode.js';
|
|
7
6
|
import { faceDirection } from './FrontFacingNode.js';
|
|
8
|
-
import { tslFn, nodeProxy, vec2 } from '../shadernode/ShaderNode.js';
|
|
7
|
+
import { addNodeElement, tslFn, nodeProxy, float, vec2 } from '../shadernode/ShaderNode.js';
|
|
9
8
|
|
|
10
9
|
// Bump Mapping Unparametrized Surfaces on the GPU by Morten S. Mikkelsen
|
|
11
10
|
// https://mmikk.github.io/papers3d/mm_sfgrad_bump.pdf
|
|
12
11
|
|
|
13
12
|
// Evaluate the derivative of the height w.r.t. screen-space using forward differencing (listing 2)
|
|
14
13
|
|
|
15
|
-
const dHdxy_fwd = tslFn( ( {
|
|
14
|
+
const dHdxy_fwd = tslFn( ( { textureNode, bumpScale } ) => {
|
|
16
15
|
|
|
17
|
-
|
|
16
|
+
let texNode = textureNode;
|
|
18
17
|
|
|
19
|
-
|
|
18
|
+
if ( texNode.isTextureNode !== true ) {
|
|
19
|
+
|
|
20
|
+
texNode.traverse( ( node ) => {
|
|
21
|
+
|
|
22
|
+
if ( node.isTextureNode === true ) texNode = node;
|
|
23
|
+
|
|
24
|
+
} );
|
|
25
|
+
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if ( texNode.isTextureNode !== true ) {
|
|
29
|
+
|
|
30
|
+
throw new Error( 'THREE.TSL: dHdxy_fwd() requires a TextureNode.' );
|
|
31
|
+
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const Hll = float( textureNode );
|
|
35
|
+
const uvNode = texNode.uvNode || uv();
|
|
36
|
+
|
|
37
|
+
// It's used to preserve the same TextureNode instance
|
|
38
|
+
const sampleTexture = ( uv ) => textureNode.cache().context( { getUVNode: () => uv, forceUVContext: true } );
|
|
20
39
|
|
|
21
40
|
return vec2(
|
|
22
|
-
|
|
23
|
-
|
|
41
|
+
float( sampleTexture( uvNode.add( uvNode.dFdx() ) ) ).sub( Hll ),
|
|
42
|
+
float( sampleTexture( uvNode.add( uvNode.dFdy() ) ) ).sub( Hll )
|
|
24
43
|
).mul( bumpScale );
|
|
25
44
|
|
|
26
45
|
} );
|
|
@@ -29,8 +48,9 @@ const perturbNormalArb = tslFn( ( inputs ) => {
|
|
|
29
48
|
|
|
30
49
|
const { surf_pos, surf_norm, dHdxy } = inputs;
|
|
31
50
|
|
|
32
|
-
|
|
33
|
-
const
|
|
51
|
+
// normalize is done to ensure that the bump map looks the same regardless of the texture's scale
|
|
52
|
+
const vSigmaX = surf_pos.dFdx().normalize();
|
|
53
|
+
const vSigmaY = surf_pos.dFdy().normalize();
|
|
34
54
|
const vN = surf_norm; // normalized
|
|
35
55
|
|
|
36
56
|
const R1 = vSigmaY.cross( vN );
|
|
@@ -46,11 +66,11 @@ const perturbNormalArb = tslFn( ( inputs ) => {
|
|
|
46
66
|
|
|
47
67
|
class BumpMapNode extends TempNode {
|
|
48
68
|
|
|
49
|
-
constructor(
|
|
69
|
+
constructor( textureNode, scaleNode = null ) {
|
|
50
70
|
|
|
51
71
|
super( 'vec3' );
|
|
52
72
|
|
|
53
|
-
this.
|
|
73
|
+
this.textureNode = textureNode;
|
|
54
74
|
this.scaleNode = scaleNode;
|
|
55
75
|
|
|
56
76
|
}
|
|
@@ -58,10 +78,10 @@ class BumpMapNode extends TempNode {
|
|
|
58
78
|
setup() {
|
|
59
79
|
|
|
60
80
|
const bumpScale = this.scaleNode !== null ? this.scaleNode : 1;
|
|
61
|
-
const dHdxy = dHdxy_fwd( {
|
|
81
|
+
const dHdxy = dHdxy_fwd( { textureNode: this.textureNode, bumpScale } );
|
|
62
82
|
|
|
63
83
|
return perturbNormalArb( {
|
|
64
|
-
surf_pos: positionView
|
|
84
|
+
surf_pos: positionView,
|
|
65
85
|
surf_norm: normalView,
|
|
66
86
|
dHdxy
|
|
67
87
|
} );
|
|
@@ -74,4 +94,6 @@ export default BumpMapNode;
|
|
|
74
94
|
|
|
75
95
|
export const bumpMap = nodeProxy( BumpMapNode );
|
|
76
96
|
|
|
97
|
+
addNodeElement( 'bumpMap', bumpMap );
|
|
98
|
+
|
|
77
99
|
addNodeClass( 'BumpMapNode', BumpMapNode );
|
|
@@ -8,7 +8,7 @@ import { tangentView } from '../accessors/TangentNode.js';
|
|
|
8
8
|
import { uv } from '../accessors/UVNode.js';
|
|
9
9
|
import { faceDirection } from './FrontFacingNode.js';
|
|
10
10
|
import { addNodeClass } from '../core/Node.js';
|
|
11
|
-
import { tslFn, nodeProxy, vec3, mat3 } from '../shadernode/ShaderNode.js';
|
|
11
|
+
import { addNodeElement, tslFn, nodeProxy, vec3, mat3 } from '../shadernode/ShaderNode.js';
|
|
12
12
|
|
|
13
13
|
import { TangentSpaceNormalMap, ObjectSpaceNormalMap } from 'three';
|
|
14
14
|
|
|
@@ -103,4 +103,6 @@ export const normalMap = nodeProxy( NormalMapNode );
|
|
|
103
103
|
|
|
104
104
|
export const TBNViewMatrix = mat3( tangentView, bitangentView, normalView );
|
|
105
105
|
|
|
106
|
+
addNodeElement( 'normalMap', normalMap );
|
|
107
|
+
|
|
106
108
|
addNodeClass( 'NormalMapNode', NormalMapNode );
|
|
@@ -81,9 +81,7 @@ class ViewportNode extends Node {
|
|
|
81
81
|
let outX = output.x;
|
|
82
82
|
let outY = output.y;
|
|
83
83
|
|
|
84
|
-
if ( /
|
|
85
|
-
else if ( /bottom/i.test( scope ) && builder.isFlipY() === false ) outY = outY.oneMinus();
|
|
86
|
-
|
|
84
|
+
if ( /bottom/i.test( scope ) ) outY = outY.oneMinus();
|
|
87
85
|
if ( /right/i.test( scope ) ) outX = outX.oneMinus();
|
|
88
86
|
|
|
89
87
|
output = vec2( outX, outY );
|
|
@@ -98,7 +96,19 @@ class ViewportNode extends Node {
|
|
|
98
96
|
|
|
99
97
|
if ( this.scope === ViewportNode.COORDINATE ) {
|
|
100
98
|
|
|
101
|
-
|
|
99
|
+
let coord = builder.getFragCoord();
|
|
100
|
+
|
|
101
|
+
if ( builder.isFlipY() ) {
|
|
102
|
+
|
|
103
|
+
// follow webgpu standards
|
|
104
|
+
|
|
105
|
+
const resolution = viewportResolution.build( builder );
|
|
106
|
+
|
|
107
|
+
coord = `${ builder.getType( 'vec2' ) }( ${ coord }.x, ${ resolution}.y - ${ coord }.y )`;
|
|
108
|
+
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return coord;
|
|
102
112
|
|
|
103
113
|
}
|
|
104
114
|
|
|
@@ -4,7 +4,7 @@ import { sheen, sheenRoughness } from '../../core/PropertyNode.js';
|
|
|
4
4
|
import { tslFn, float } from '../../shadernode/ShaderNode.js';
|
|
5
5
|
|
|
6
6
|
// https://github.com/google/filament/blob/master/shaders/src/brdf.fs
|
|
7
|
-
const D_Charlie = ( roughness, dotNH ) => {
|
|
7
|
+
const D_Charlie = tslFn( ( { roughness, dotNH } ) => {
|
|
8
8
|
|
|
9
9
|
const alpha = roughness.pow2();
|
|
10
10
|
|
|
@@ -15,15 +15,29 @@ const D_Charlie = ( roughness, dotNH ) => {
|
|
|
15
15
|
|
|
16
16
|
return float( 2.0 ).add( invAlpha ).mul( sin2h.pow( invAlpha.mul( 0.5 ) ) ).div( 2.0 * Math.PI );
|
|
17
17
|
|
|
18
|
-
}
|
|
18
|
+
} ).setLayout( {
|
|
19
|
+
name: 'D_Charlie',
|
|
20
|
+
type: 'float',
|
|
21
|
+
inputs: [
|
|
22
|
+
{ name: 'roughness', type: 'float' },
|
|
23
|
+
{ name: 'dotNH', type: 'float' }
|
|
24
|
+
]
|
|
25
|
+
} );
|
|
19
26
|
|
|
20
27
|
// https://github.com/google/filament/blob/master/shaders/src/brdf.fs
|
|
21
|
-
const V_Neubelt = ( dotNV, dotNL ) => {
|
|
28
|
+
const V_Neubelt = tslFn( ( { dotNV, dotNL } ) => {
|
|
22
29
|
|
|
23
30
|
// Neubelt and Pettineo 2013, "Crafting a Next-gen Material Pipeline for The Order: 1886"
|
|
24
31
|
return float( 1.0 ).div( float( 4.0 ).mul( dotNL.add( dotNV ).sub( dotNL.mul( dotNV ) ) ) );
|
|
25
32
|
|
|
26
|
-
}
|
|
33
|
+
} ).setLayout( {
|
|
34
|
+
name: 'V_Neubelt',
|
|
35
|
+
type: 'float',
|
|
36
|
+
inputs: [
|
|
37
|
+
{ name: 'dotNV', type: 'float' },
|
|
38
|
+
{ name: 'dotNL', type: 'float' }
|
|
39
|
+
]
|
|
40
|
+
} );
|
|
27
41
|
|
|
28
42
|
const BRDF_Sheen = tslFn( ( { lightDirection } ) => {
|
|
29
43
|
|
|
@@ -33,8 +47,8 @@ const BRDF_Sheen = tslFn( ( { lightDirection } ) => {
|
|
|
33
47
|
const dotNV = transformedNormalView.dot( positionViewDirection ).clamp();
|
|
34
48
|
const dotNH = transformedNormalView.dot( halfDir ).clamp();
|
|
35
49
|
|
|
36
|
-
const D = D_Charlie( sheenRoughness, dotNH );
|
|
37
|
-
const V = V_Neubelt( dotNV, dotNL );
|
|
50
|
+
const D = D_Charlie( { roughness: sheenRoughness, dotNH } );
|
|
51
|
+
const V = V_Neubelt( { dotNV, dotNL } );
|
|
38
52
|
|
|
39
53
|
return sheen.mul( D ).mul( V );
|
|
40
54
|
|
|
@@ -1,16 +1,10 @@
|
|
|
1
|
-
import { transformedNormalView } from '../../accessors/NormalNode.js';
|
|
2
|
-
import { positionViewDirection } from '../../accessors/PositionNode.js';
|
|
3
1
|
import { tslFn, vec2, vec4 } from '../../shadernode/ShaderNode.js';
|
|
4
2
|
|
|
5
3
|
// Analytical approximation of the DFG LUT, one half of the
|
|
6
4
|
// split-sum approximation used in indirect specular lighting.
|
|
7
5
|
// via 'environmentBRDF' from "Physically Based Shading on Mobile"
|
|
8
6
|
// https://www.unrealengine.com/blog/physically-based-shading-on-mobile
|
|
9
|
-
const DFGApprox = tslFn( (
|
|
10
|
-
|
|
11
|
-
const { roughness } = inputs;
|
|
12
|
-
|
|
13
|
-
const dotNV = inputs.dotNV || transformedNormalView.dot( positionViewDirection ).clamp(); // @ TODO: Move to core dotNV
|
|
7
|
+
const DFGApprox = tslFn( ( { roughness, dotNV } ) => {
|
|
14
8
|
|
|
15
9
|
const c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );
|
|
16
10
|
|
|
@@ -24,6 +18,13 @@ const DFGApprox = tslFn( ( inputs ) => {
|
|
|
24
18
|
|
|
25
19
|
return fab;
|
|
26
20
|
|
|
21
|
+
} ).setLayout( {
|
|
22
|
+
name: 'DFGApprox',
|
|
23
|
+
type: 'vec2',
|
|
24
|
+
inputs: [
|
|
25
|
+
{ name: 'roughness', type: 'float' },
|
|
26
|
+
{ name: 'dotNV', type: 'vec3' }
|
|
27
|
+
]
|
|
27
28
|
} );
|
|
28
29
|
|
|
29
30
|
export default DFGApprox;
|
|
@@ -3,9 +3,7 @@ import { tslFn } from '../../shadernode/ShaderNode.js';
|
|
|
3
3
|
// Microfacet Models for Refraction through Rough Surfaces - equation (33)
|
|
4
4
|
// http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html
|
|
5
5
|
// alpha is "roughness squared" in Disney’s reparameterization
|
|
6
|
-
const D_GGX = tslFn( (
|
|
7
|
-
|
|
8
|
-
const { alpha, dotNH } = inputs;
|
|
6
|
+
const D_GGX = tslFn( ( { alpha, dotNH } ) => {
|
|
9
7
|
|
|
10
8
|
const a2 = alpha.pow2();
|
|
11
9
|
|
|
@@ -13,6 +11,13 @@ const D_GGX = tslFn( ( inputs ) => {
|
|
|
13
11
|
|
|
14
12
|
return a2.div( denom.pow2() ).mul( 1 / Math.PI );
|
|
15
13
|
|
|
14
|
+
} ).setLayout( {
|
|
15
|
+
name: 'D_GGX',
|
|
16
|
+
type: 'float',
|
|
17
|
+
inputs: [
|
|
18
|
+
{ name: 'alpha', type: 'float' },
|
|
19
|
+
{ name: 'dotNH', type: 'float' }
|
|
20
|
+
]
|
|
16
21
|
} ); // validated
|
|
17
22
|
|
|
18
23
|
export default D_GGX;
|
|
@@ -8,6 +8,14 @@ const Schlick_to_F0 = tslFn( ( { f, f90, dotVH } ) => {
|
|
|
8
8
|
|
|
9
9
|
return f.sub( vec3( f90 ).mul( x5 ) ).div( x5.oneMinus() );
|
|
10
10
|
|
|
11
|
+
} ).setLayout( {
|
|
12
|
+
name: 'Schlick_to_F0',
|
|
13
|
+
type: 'vec3',
|
|
14
|
+
inputs: [
|
|
15
|
+
{ name: 'f', type: 'vec3' },
|
|
16
|
+
{ name: 'f90', type: 'float' },
|
|
17
|
+
{ name: 'dotVH', type: 'float' }
|
|
18
|
+
]
|
|
11
19
|
} );
|
|
12
20
|
|
|
13
21
|
export default Schlick_to_F0;
|
|
@@ -15,6 +15,14 @@ const V_GGX_SmithCorrelated = tslFn( ( inputs ) => {
|
|
|
15
15
|
|
|
16
16
|
return div( 0.5, gv.add( gl ).max( EPSILON ) );
|
|
17
17
|
|
|
18
|
+
} ).setLayout( {
|
|
19
|
+
name: 'V_GGX_SmithCorrelated',
|
|
20
|
+
type: 'float',
|
|
21
|
+
inputs: [
|
|
22
|
+
{ name: 'alpha', type: 'float' },
|
|
23
|
+
{ name: 'dotNL', type: 'float' },
|
|
24
|
+
{ name: 'dotNV', type: 'float' }
|
|
25
|
+
]
|
|
18
26
|
} ); // validated
|
|
19
27
|
|
|
20
28
|
export default V_GGX_SmithCorrelated;
|
|
@@ -9,7 +9,7 @@ import LightingModel from '../core/LightingModel.js';
|
|
|
9
9
|
import { diffuseColor, specularColor, roughness, clearcoat, clearcoatRoughness, sheen, sheenRoughness, iridescence, iridescenceIOR, iridescenceThickness } from '../core/PropertyNode.js';
|
|
10
10
|
import { transformedNormalView, transformedClearcoatNormalView } from '../accessors/NormalNode.js';
|
|
11
11
|
import { positionViewDirection } from '../accessors/PositionNode.js';
|
|
12
|
-
import { float, vec3, mat3 } from '../shadernode/ShaderNode.js';
|
|
12
|
+
import { tslFn, float, vec3, mat3 } from '../shadernode/ShaderNode.js';
|
|
13
13
|
import { cond } from '../math/CondNode.js';
|
|
14
14
|
import { mix, smoothstep } from '../math/MathNode.js';
|
|
15
15
|
|
|
@@ -56,11 +56,12 @@ const evalSensitivity = ( OPD, shift ) => {
|
|
|
56
56
|
xyz = vec3( xyz.x.add( x ), xyz.y, xyz.z ).div( 1.0685e-7 );
|
|
57
57
|
|
|
58
58
|
const rgb = XYZ_TO_REC709.mul( xyz );
|
|
59
|
+
|
|
59
60
|
return rgb;
|
|
60
61
|
|
|
61
62
|
};
|
|
62
63
|
|
|
63
|
-
const evalIridescence = ( outsideIOR, eta2, cosTheta1, thinFilmThickness, baseF0 ) => {
|
|
64
|
+
const evalIridescence = tslFn( ( { outsideIOR, eta2, cosTheta1, thinFilmThickness, baseF0 } ) => {
|
|
64
65
|
|
|
65
66
|
// Force iridescenceIOR -> outsideIOR when thinFilmThickness -> 0.0
|
|
66
67
|
const iridescenceIOR = mix( outsideIOR, eta2, smoothstep( 0.0, 0.03, thinFilmThickness ) );
|
|
@@ -121,7 +122,17 @@ const evalIridescence = ( outsideIOR, eta2, cosTheta1, thinFilmThickness, baseF0
|
|
|
121
122
|
// Since out of gamut colors might be produced, negative color values are clamped to 0.
|
|
122
123
|
return I.max( vec3( 0.0 ) );
|
|
123
124
|
|
|
124
|
-
}
|
|
125
|
+
} ).setLayout( {
|
|
126
|
+
name: 'evalIridescence',
|
|
127
|
+
type: 'vec3',
|
|
128
|
+
inputs: [
|
|
129
|
+
{ name: 'outsideIOR', type: 'float' },
|
|
130
|
+
{ name: 'eta2', type: 'float' },
|
|
131
|
+
{ name: 'cosTheta1', type: 'float' },
|
|
132
|
+
{ name: 'thinFilmThickness', type: 'float' },
|
|
133
|
+
{ name: 'baseF0', type: 'vec3' }
|
|
134
|
+
]
|
|
135
|
+
} );
|
|
125
136
|
|
|
126
137
|
//
|
|
127
138
|
// Sheen
|
|
@@ -130,7 +141,7 @@ const evalIridescence = ( outsideIOR, eta2, cosTheta1, thinFilmThickness, baseF0
|
|
|
130
141
|
// This is a curve-fit approxmation to the "Charlie sheen" BRDF integrated over the hemisphere from
|
|
131
142
|
// Estevez and Kulla 2017, "Production Friendly Microfacet Sheen BRDF". The analysis can be found
|
|
132
143
|
// in the Sheen section of https://drive.google.com/file/d/1T0D1VSyR4AllqIJTQAraEIzjlb5h4FKH/view?usp=sharing
|
|
133
|
-
const IBLSheenBRDF = ( normal, viewDir, roughness ) => {
|
|
144
|
+
const IBLSheenBRDF = tslFn( ( { normal, viewDir, roughness } ) => {
|
|
134
145
|
|
|
135
146
|
const dotNV = normal.dot( viewDir ).saturate();
|
|
136
147
|
|
|
@@ -152,7 +163,7 @@ const IBLSheenBRDF = ( normal, viewDir, roughness ) => {
|
|
|
152
163
|
|
|
153
164
|
return DG.mul( 1.0 / Math.PI ).saturate();
|
|
154
165
|
|
|
155
|
-
};
|
|
166
|
+
} );
|
|
156
167
|
|
|
157
168
|
const clearcoatF0 = vec3( 0.04 );
|
|
158
169
|
const clearcoatF90 = vec3( 1 );
|
|
@@ -161,7 +172,7 @@ const clearcoatF90 = vec3( 1 );
|
|
|
161
172
|
|
|
162
173
|
class PhysicalLightingModel extends LightingModel {
|
|
163
174
|
|
|
164
|
-
constructor( clearcoat =
|
|
175
|
+
constructor( clearcoat = false, sheen = false, iridescence = false ) {
|
|
165
176
|
|
|
166
177
|
super();
|
|
167
178
|
|
|
@@ -170,45 +181,29 @@ class PhysicalLightingModel extends LightingModel {
|
|
|
170
181
|
this.iridescence = iridescence;
|
|
171
182
|
|
|
172
183
|
this.clearcoatRadiance = null;
|
|
173
|
-
this.
|
|
174
|
-
this.
|
|
184
|
+
this.clearcoatSpecularDirect = null;
|
|
185
|
+
this.clearcoatSpecularIndirect = null;
|
|
186
|
+
this.sheenSpecularDirect = null;
|
|
187
|
+
this.sheenSpecularIndirect = null;
|
|
175
188
|
this.iridescenceFresnel = null;
|
|
176
189
|
this.iridescenceF0 = null;
|
|
177
190
|
|
|
178
191
|
}
|
|
179
192
|
|
|
180
|
-
|
|
193
|
+
start( /*context*/ ) {
|
|
181
194
|
|
|
182
195
|
if ( this.clearcoat === true ) {
|
|
183
196
|
|
|
184
|
-
this.clearcoatRadiance = vec3().temp();
|
|
185
|
-
this.
|
|
186
|
-
|
|
187
|
-
const dotNVcc = transformedClearcoatNormalView.dot( positionViewDirection ).clamp();
|
|
188
|
-
|
|
189
|
-
const Fcc = F_Schlick( {
|
|
190
|
-
dotVH: dotNVcc,
|
|
191
|
-
f0: clearcoatF0,
|
|
192
|
-
f90: clearcoatF90
|
|
193
|
-
} );
|
|
194
|
-
|
|
195
|
-
const outgoingLight = reflectedLight.total;
|
|
196
|
-
const clearcoatLight = outgoingLight.mul( clearcoat.mul( Fcc ).oneMinus() ).add( this.clearcoatSpecular.mul( clearcoat ) );
|
|
197
|
-
|
|
198
|
-
outgoingLight.assign( clearcoatLight );
|
|
197
|
+
this.clearcoatRadiance = vec3().temp( 'clearcoatRadiance' );
|
|
198
|
+
this.clearcoatSpecularDirect = vec3().temp( 'clearcoatSpecularDirect' );
|
|
199
|
+
this.clearcoatSpecularIndirect = vec3().temp( 'clearcoatSpecularIndirect' );
|
|
199
200
|
|
|
200
201
|
}
|
|
201
202
|
|
|
202
203
|
if ( this.sheen === true ) {
|
|
203
204
|
|
|
204
|
-
this.
|
|
205
|
-
|
|
206
|
-
const outgoingLight = reflectedLight.total;
|
|
207
|
-
|
|
208
|
-
const sheenEnergyComp = sheen.r.max( sheen.g ).max( sheen.b ).mul( 0.157 ).oneMinus();
|
|
209
|
-
const sheenLight = outgoingLight.mul( sheenEnergyComp ).add( this.sheenSpecular );
|
|
210
|
-
|
|
211
|
-
outgoingLight.assign( sheenLight );
|
|
205
|
+
this.sheenSpecularDirect = vec3().temp( 'sheenSpecularDirect' );
|
|
206
|
+
this.sheenSpecularIndirect = vec3().temp( 'sheenSpecularIndirect' );
|
|
212
207
|
|
|
213
208
|
}
|
|
214
209
|
|
|
@@ -216,7 +211,14 @@ class PhysicalLightingModel extends LightingModel {
|
|
|
216
211
|
|
|
217
212
|
const dotNVi = transformedNormalView.dot( positionViewDirection ).clamp();
|
|
218
213
|
|
|
219
|
-
this.iridescenceFresnel = evalIridescence(
|
|
214
|
+
this.iridescenceFresnel = evalIridescence( {
|
|
215
|
+
outsideIOR: float( 1.0 ),
|
|
216
|
+
eta2: iridescenceIOR,
|
|
217
|
+
cosTheta1: dotNVi,
|
|
218
|
+
thinFilmThickness: iridescenceThickness,
|
|
219
|
+
baseF0: specularColor
|
|
220
|
+
} );
|
|
221
|
+
|
|
220
222
|
this.iridescenceF0 = Schlick_to_F0( { f: this.iridescenceFresnel, f90: 1.0, dotVH: dotNVi } );
|
|
221
223
|
|
|
222
224
|
}
|
|
@@ -229,7 +231,9 @@ class PhysicalLightingModel extends LightingModel {
|
|
|
229
231
|
|
|
230
232
|
computeMultiscattering( singleScatter, multiScatter, specularF90 = float( 1 ) ) {
|
|
231
233
|
|
|
232
|
-
const
|
|
234
|
+
const dotNV = transformedNormalView.dot( positionViewDirection ).clamp(); // @ TODO: Move to core dotNV
|
|
235
|
+
|
|
236
|
+
const fab = DFGApprox( { roughness, dotNV } );
|
|
233
237
|
|
|
234
238
|
const Fr = this.iridescenceF0 ? iridescence.mix( specularColor, this.iridescenceF0 ) : specularColor;
|
|
235
239
|
|
|
@@ -253,7 +257,7 @@ class PhysicalLightingModel extends LightingModel {
|
|
|
253
257
|
|
|
254
258
|
if ( this.sheen === true ) {
|
|
255
259
|
|
|
256
|
-
this.
|
|
260
|
+
this.sheenSpecularDirect.addAssign( irradiance.mul( BRDF_Sheen( { lightDirection } ) ) );
|
|
257
261
|
|
|
258
262
|
}
|
|
259
263
|
|
|
@@ -262,7 +266,7 @@ class PhysicalLightingModel extends LightingModel {
|
|
|
262
266
|
const dotNLcc = transformedClearcoatNormalView.dot( lightDirection ).clamp();
|
|
263
267
|
const ccIrradiance = dotNLcc.mul( lightColor );
|
|
264
268
|
|
|
265
|
-
this.
|
|
269
|
+
this.clearcoatSpecularDirect.addAssign( ccIrradiance.mul( BRDF_GGX( { lightDirection, f0: clearcoatF0, f90: clearcoatF90, roughness: clearcoatRoughness, normalView: transformedClearcoatNormalView } ) ) );
|
|
266
270
|
|
|
267
271
|
}
|
|
268
272
|
|
|
@@ -278,13 +282,17 @@ class PhysicalLightingModel extends LightingModel {
|
|
|
278
282
|
|
|
279
283
|
}
|
|
280
284
|
|
|
281
|
-
indirectSpecular( { radiance, iblIrradiance, reflectedLight
|
|
285
|
+
indirectSpecular( { radiance, iblIrradiance, reflectedLight } ) {
|
|
282
286
|
|
|
283
287
|
if ( this.sheen === true ) {
|
|
284
288
|
|
|
285
|
-
this.
|
|
289
|
+
this.sheenSpecularIndirect.addAssign( iblIrradiance.mul(
|
|
286
290
|
sheen,
|
|
287
|
-
IBLSheenBRDF(
|
|
291
|
+
IBLSheenBRDF( {
|
|
292
|
+
normal: transformedNormalView,
|
|
293
|
+
viewDir: positionViewDirection,
|
|
294
|
+
roughness: sheenRoughness
|
|
295
|
+
} )
|
|
288
296
|
) );
|
|
289
297
|
|
|
290
298
|
}
|
|
@@ -300,14 +308,14 @@ class PhysicalLightingModel extends LightingModel {
|
|
|
300
308
|
roughness: clearcoatRoughness
|
|
301
309
|
} );
|
|
302
310
|
|
|
303
|
-
this.
|
|
311
|
+
this.clearcoatSpecularIndirect.addAssign( this.clearcoatRadiance.mul( clearcoatEnv ) );
|
|
304
312
|
|
|
305
313
|
}
|
|
306
314
|
|
|
307
315
|
// Both indirect specular and indirect diffuse light accumulate here
|
|
308
316
|
|
|
309
|
-
const singleScattering = vec3().temp();
|
|
310
|
-
const multiScattering = vec3().temp();
|
|
317
|
+
const singleScattering = vec3().temp( 'singleScattering' );
|
|
318
|
+
const multiScattering = vec3().temp( 'multiScattering' );
|
|
311
319
|
const cosineWeightedIrradiance = iblIrradiance.mul( 1 / Math.PI );
|
|
312
320
|
|
|
313
321
|
this.computeMultiscattering( singleScattering, multiScattering );
|
|
@@ -332,12 +340,54 @@ class PhysicalLightingModel extends LightingModel {
|
|
|
332
340
|
|
|
333
341
|
const aoNode = ambientOcclusion.sub( aoNV.pow( aoExp ).oneMinus() ).clamp();
|
|
334
342
|
|
|
335
|
-
|
|
343
|
+
if ( this.clearcoat === true ) {
|
|
344
|
+
|
|
345
|
+
this.clearcoatSpecularIndirect.mulAssign( ambientOcclusion );
|
|
346
|
+
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
if ( this.sheen === true ) {
|
|
350
|
+
|
|
351
|
+
this.sheenSpecularIndirect.mulAssign( ambientOcclusion );
|
|
336
352
|
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
reflectedLight.indirectDiffuse.mulAssign( ambientOcclusion );
|
|
337
356
|
reflectedLight.indirectSpecular.mulAssign( aoNode );
|
|
338
357
|
|
|
339
358
|
}
|
|
340
359
|
|
|
360
|
+
finish( context ) {
|
|
361
|
+
|
|
362
|
+
const { outgoingLight } = context;
|
|
363
|
+
|
|
364
|
+
if ( this.clearcoat === true ) {
|
|
365
|
+
|
|
366
|
+
const dotNVcc = transformedClearcoatNormalView.dot( positionViewDirection ).clamp();
|
|
367
|
+
|
|
368
|
+
const Fcc = F_Schlick( {
|
|
369
|
+
dotVH: dotNVcc,
|
|
370
|
+
f0: clearcoatF0,
|
|
371
|
+
f90: clearcoatF90
|
|
372
|
+
} );
|
|
373
|
+
|
|
374
|
+
const clearcoatLight = outgoingLight.mul( clearcoat.mul( Fcc ).oneMinus() ).add( this.clearcoatSpecularDirect, this.clearcoatSpecularIndirect ).mul( clearcoat );
|
|
375
|
+
|
|
376
|
+
outgoingLight.assign( clearcoatLight );
|
|
377
|
+
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
if ( this.sheen === true ) {
|
|
381
|
+
|
|
382
|
+
const sheenEnergyComp = sheen.r.max( sheen.g ).max( sheen.b ).mul( 0.157 ).oneMinus();
|
|
383
|
+
const sheenLight = outgoingLight.mul( sheenEnergyComp ).add( this.sheenSpecularDirect, this.sheenSpecularIndirect );
|
|
384
|
+
|
|
385
|
+
outgoingLight.assign( sheenLight );
|
|
386
|
+
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
}
|
|
390
|
+
|
|
341
391
|
}
|
|
342
392
|
|
|
343
393
|
export default PhysicalLightingModel;
|
|
@@ -17,7 +17,7 @@ class ComputeNode extends Node {
|
|
|
17
17
|
this.dispatchCount = 0;
|
|
18
18
|
|
|
19
19
|
this.version = 1;
|
|
20
|
-
this.
|
|
20
|
+
this.updateBeforeType = NodeUpdateType.OBJECT;
|
|
21
21
|
|
|
22
22
|
this.updateDispatchCount();
|
|
23
23
|
|
|
@@ -50,7 +50,7 @@ class ComputeNode extends Node {
|
|
|
50
50
|
|
|
51
51
|
onInit() { }
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
updateBefore( { renderer } ) {
|
|
54
54
|
|
|
55
55
|
renderer.compute( this );
|
|
56
56
|
|
|
@@ -7,6 +7,7 @@ import { reference } from '../accessors/ReferenceNode.js';
|
|
|
7
7
|
import { texture } from '../accessors/TextureNode.js';
|
|
8
8
|
import { positionWorld } from '../accessors/PositionNode.js';
|
|
9
9
|
import { normalWorld } from '../accessors/NormalNode.js';
|
|
10
|
+
import { WebGPUCoordinateSystem } from 'three';
|
|
10
11
|
//import { add } from '../math/OperatorNode.js';
|
|
11
12
|
|
|
12
13
|
import { Color, DepthTexture, NearestFilter, LessCompare } from 'three';
|
|
@@ -73,11 +74,24 @@ class AnalyticLightNode extends LightingNode {
|
|
|
73
74
|
.and( shadowCoord.y.lessThanEqual( 1 ) )
|
|
74
75
|
.and( shadowCoord.z.lessThanEqual( 1 ) );
|
|
75
76
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
shadowCoord
|
|
80
|
-
|
|
77
|
+
|
|
78
|
+
if ( builder.renderer.coordinateSystem === WebGPUCoordinateSystem ) {
|
|
79
|
+
|
|
80
|
+
shadowCoord = vec3(
|
|
81
|
+
shadowCoord.x,
|
|
82
|
+
shadowCoord.y.oneMinus(), // WebGPU: Flip Y
|
|
83
|
+
shadowCoord.z.add( bias ).mul( 2 ).sub( 1 ) // WebGPU: Convertion [ 0, 1 ] to [ - 1, 1 ]
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
} else {
|
|
87
|
+
|
|
88
|
+
shadowCoord = vec3(
|
|
89
|
+
shadowCoord.x,
|
|
90
|
+
shadowCoord.y,
|
|
91
|
+
shadowCoord.z.add( bias )
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
}
|
|
81
95
|
|
|
82
96
|
const textureCompare = ( depthTexture, shadowCoord, compare ) => texture( depthTexture, shadowCoord ).compare( compare );
|
|
83
97
|
//const textureCompare = ( depthTexture, shadowCoord, compare ) => compare.step( texture( depthTexture, shadowCoord ) );
|
|
@@ -27,7 +27,6 @@ class EnvironmentNode extends LightingNode {
|
|
|
27
27
|
setup( builder ) {
|
|
28
28
|
|
|
29
29
|
let envNode = this.envNode;
|
|
30
|
-
const properties = builder.getNodeProperties( this );
|
|
31
30
|
|
|
32
31
|
if ( envNode.isTextureNode && envNode.value.isCubeTexture !== true ) {
|
|
33
32
|
|
|
@@ -79,11 +78,6 @@ class EnvironmentNode extends LightingNode {
|
|
|
79
78
|
|
|
80
79
|
}
|
|
81
80
|
|
|
82
|
-
//
|
|
83
|
-
|
|
84
|
-
properties.radiance = isolateRadiance;
|
|
85
|
-
properties.irradiance = irradiance;
|
|
86
|
-
|
|
87
81
|
}
|
|
88
82
|
|
|
89
83
|
}
|