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
|
@@ -1,49 +1,68 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
RawShaderMaterial,
|
|
3
3
|
UniformsUtils,
|
|
4
|
-
NoToneMapping,
|
|
5
4
|
LinearToneMapping,
|
|
6
5
|
ReinhardToneMapping,
|
|
7
6
|
CineonToneMapping,
|
|
8
|
-
ACESFilmicToneMapping
|
|
7
|
+
ACESFilmicToneMapping,
|
|
8
|
+
SRGBColorSpace
|
|
9
9
|
} from 'three';
|
|
10
10
|
import { Pass, FullScreenQuad } from './Pass.js';
|
|
11
11
|
import { OutputShader } from '../shaders/OutputShader.js';
|
|
12
12
|
|
|
13
13
|
class OutputPass extends Pass {
|
|
14
14
|
|
|
15
|
-
constructor(
|
|
15
|
+
constructor() {
|
|
16
16
|
|
|
17
17
|
super();
|
|
18
18
|
|
|
19
|
-
this.toneMapping = toneMapping;
|
|
20
|
-
this.toneMappingExposure = toneMappingExposure;
|
|
21
|
-
|
|
22
19
|
//
|
|
23
20
|
|
|
24
21
|
const shader = OutputShader;
|
|
25
22
|
|
|
26
23
|
this.uniforms = UniformsUtils.clone( shader.uniforms );
|
|
27
24
|
|
|
28
|
-
this.material = new
|
|
25
|
+
this.material = new RawShaderMaterial( {
|
|
29
26
|
uniforms: this.uniforms,
|
|
30
27
|
vertexShader: shader.vertexShader,
|
|
31
28
|
fragmentShader: shader.fragmentShader
|
|
32
29
|
} );
|
|
33
30
|
|
|
34
|
-
if ( toneMapping === LinearToneMapping ) this.material.defines.LINEAR_TONE_MAPPING = '';
|
|
35
|
-
else if ( toneMapping === ReinhardToneMapping ) this.material.defines.REINHARD_TONE_MAPPING = '';
|
|
36
|
-
else if ( toneMapping === CineonToneMapping ) this.material.defines.CINEON_TONE_MAPPING = '';
|
|
37
|
-
else if ( toneMapping === ACESFilmicToneMapping ) this.material.defines.ACES_FILMIC_TONE_MAPPING = '';
|
|
38
|
-
|
|
39
31
|
this.fsQuad = new FullScreenQuad( this.material );
|
|
40
32
|
|
|
33
|
+
// internal cache
|
|
34
|
+
|
|
35
|
+
this._outputColorSpace = null;
|
|
36
|
+
this._toneMapping = null;
|
|
37
|
+
|
|
41
38
|
}
|
|
42
39
|
|
|
43
40
|
render( renderer, writeBuffer, readBuffer/*, deltaTime, maskActive */ ) {
|
|
44
41
|
|
|
45
42
|
this.uniforms[ 'tDiffuse' ].value = readBuffer.texture;
|
|
46
|
-
this.uniforms[ 'toneMappingExposure' ].value =
|
|
43
|
+
this.uniforms[ 'toneMappingExposure' ].value = renderer.toneMappingExposure;
|
|
44
|
+
|
|
45
|
+
// rebuild defines if required
|
|
46
|
+
|
|
47
|
+
if ( this._outputColorSpace !== renderer.outputColorSpace || this._toneMapping !== renderer.toneMapping ) {
|
|
48
|
+
|
|
49
|
+
this._outputColorSpace = renderer.outputColorSpace;
|
|
50
|
+
this._toneMapping = renderer.toneMapping;
|
|
51
|
+
|
|
52
|
+
this.material.defines = {};
|
|
53
|
+
|
|
54
|
+
if ( this._outputColorSpace == SRGBColorSpace ) this.material.defines.SRGB_COLOR_SPACE = '';
|
|
55
|
+
|
|
56
|
+
if ( this._toneMapping === LinearToneMapping ) this.material.defines.LINEAR_TONE_MAPPING = '';
|
|
57
|
+
else if ( this._toneMapping === ReinhardToneMapping ) this.material.defines.REINHARD_TONE_MAPPING = '';
|
|
58
|
+
else if ( this._toneMapping === CineonToneMapping ) this.material.defines.CINEON_TONE_MAPPING = '';
|
|
59
|
+
else if ( this._toneMapping === ACESFilmicToneMapping ) this.material.defines.ACES_FILMIC_TONE_MAPPING = '';
|
|
60
|
+
|
|
61
|
+
this.material.needsUpdate = true;
|
|
62
|
+
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
//
|
|
47
66
|
|
|
48
67
|
if ( this.renderToScreen === true ) {
|
|
49
68
|
|
|
@@ -94,7 +94,7 @@ class UnrealBloomPass extends Pass {
|
|
|
94
94
|
|
|
95
95
|
this.separableBlurMaterials.push( this.getSeperableBlurMaterial( kernelSizeArray[ i ] ) );
|
|
96
96
|
|
|
97
|
-
this.separableBlurMaterials[ i ].uniforms[ '
|
|
97
|
+
this.separableBlurMaterials[ i ].uniforms[ 'invSize' ].value = new Vector2( 1 / resx, 1 / resy );
|
|
98
98
|
|
|
99
99
|
resx = Math.round( resx / 2 );
|
|
100
100
|
|
|
@@ -192,7 +192,7 @@ class UnrealBloomPass extends Pass {
|
|
|
192
192
|
this.renderTargetsHorizontal[ i ].setSize( resx, resy );
|
|
193
193
|
this.renderTargetsVertical[ i ].setSize( resx, resy );
|
|
194
194
|
|
|
195
|
-
this.separableBlurMaterials[ i ].uniforms[ '
|
|
195
|
+
this.separableBlurMaterials[ i ].uniforms[ 'invSize' ].value = new Vector2( 1 / resx, 1 / resy );
|
|
196
196
|
|
|
197
197
|
resx = Math.round( resx / 2 );
|
|
198
198
|
resy = Math.round( resy / 2 );
|
|
@@ -298,17 +298,25 @@ class UnrealBloomPass extends Pass {
|
|
|
298
298
|
|
|
299
299
|
getSeperableBlurMaterial( kernelRadius ) {
|
|
300
300
|
|
|
301
|
+
const coefficients = [];
|
|
302
|
+
|
|
303
|
+
for ( let i = 0; i < kernelRadius; i ++ ) {
|
|
304
|
+
|
|
305
|
+
coefficients.push( 0.39894 * Math.exp( - 0.5 * i * i / ( kernelRadius * kernelRadius ) ) / kernelRadius );
|
|
306
|
+
|
|
307
|
+
}
|
|
308
|
+
|
|
301
309
|
return new ShaderMaterial( {
|
|
302
310
|
|
|
303
311
|
defines: {
|
|
304
|
-
'KERNEL_RADIUS': kernelRadius
|
|
305
|
-
'SIGMA': kernelRadius
|
|
312
|
+
'KERNEL_RADIUS': kernelRadius
|
|
306
313
|
},
|
|
307
314
|
|
|
308
315
|
uniforms: {
|
|
309
316
|
'colorTexture': { value: null },
|
|
310
|
-
'
|
|
311
|
-
'direction': { value: new Vector2( 0.5, 0.5 ) }
|
|
317
|
+
'invSize': { value: new Vector2( 0.5, 0.5 ) }, // inverse texture size
|
|
318
|
+
'direction': { value: new Vector2( 0.5, 0.5 ) },
|
|
319
|
+
'gaussianCoefficients': { value: coefficients } // precomputed Gaussian coefficients
|
|
312
320
|
},
|
|
313
321
|
|
|
314
322
|
vertexShader:
|
|
@@ -322,23 +330,19 @@ class UnrealBloomPass extends Pass {
|
|
|
322
330
|
`#include <common>
|
|
323
331
|
varying vec2 vUv;
|
|
324
332
|
uniform sampler2D colorTexture;
|
|
325
|
-
uniform vec2
|
|
333
|
+
uniform vec2 invSize;
|
|
326
334
|
uniform vec2 direction;
|
|
335
|
+
uniform float gaussianCoefficients[KERNEL_RADIUS];
|
|
327
336
|
|
|
328
|
-
float gaussianPdf(in float x, in float sigma) {
|
|
329
|
-
return 0.39894 * exp( -0.5 * x * x/( sigma * sigma))/sigma;
|
|
330
|
-
}
|
|
331
337
|
void main() {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
float weightSum = gaussianPdf(0.0, fSigma);
|
|
335
|
-
vec3 diffuseSum = texture2D( colorTexture, vUv).rgb * weightSum;
|
|
338
|
+
float weightSum = gaussianCoefficients[0];
|
|
339
|
+
vec3 diffuseSum = texture2D( colorTexture, vUv ).rgb * weightSum;
|
|
336
340
|
for( int i = 1; i < KERNEL_RADIUS; i ++ ) {
|
|
337
341
|
float x = float(i);
|
|
338
|
-
float w =
|
|
342
|
+
float w = gaussianCoefficients[i];
|
|
339
343
|
vec2 uvOffset = direction * invSize * x;
|
|
340
|
-
vec3 sample1 = texture2D( colorTexture, vUv + uvOffset).rgb;
|
|
341
|
-
vec3 sample2 = texture2D( colorTexture, vUv - uvOffset).rgb;
|
|
344
|
+
vec3 sample1 = texture2D( colorTexture, vUv + uvOffset ).rgb;
|
|
345
|
+
vec3 sample2 = texture2D( colorTexture, vUv - uvOffset ).rgb;
|
|
342
346
|
diffuseSum += (sample1 + sample2) * w;
|
|
343
347
|
weightSum += 2.0 * w;
|
|
344
348
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import DataMap from './DataMap.js';
|
|
2
2
|
import { Color, Mesh, SphereGeometry, BackSide } from 'three';
|
|
3
|
-
import { context,
|
|
3
|
+
import { vec4, context, normalWorld, backgroundBlurriness, backgroundIntensity, NodeMaterial, modelViewProjection } from '../../nodes/Nodes.js';
|
|
4
4
|
|
|
5
5
|
let _clearAlpha;
|
|
6
6
|
const _clearColor = new Color();
|
|
@@ -14,15 +14,15 @@ class Background extends DataMap {
|
|
|
14
14
|
this.renderer = renderer;
|
|
15
15
|
this.nodes = nodes;
|
|
16
16
|
|
|
17
|
-
this.
|
|
18
|
-
this.
|
|
17
|
+
this.backgroundMesh = null;
|
|
18
|
+
this.backgroundMeshNode = null;
|
|
19
19
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
update( scene, renderList, renderContext ) {
|
|
23
23
|
|
|
24
24
|
const renderer = this.renderer;
|
|
25
|
-
const background =
|
|
25
|
+
const background = this.nodes.getBackgroundNode( scene ) || scene.background;
|
|
26
26
|
|
|
27
27
|
let forceClear = false;
|
|
28
28
|
|
|
@@ -49,31 +49,33 @@ class Background extends DataMap {
|
|
|
49
49
|
_clearColor.copy( renderer._clearColor );
|
|
50
50
|
_clearAlpha = renderer._clearAlpha;
|
|
51
51
|
|
|
52
|
-
let
|
|
52
|
+
let backgroundMesh = this.backgroundMesh;
|
|
53
53
|
|
|
54
|
-
if (
|
|
54
|
+
if ( backgroundMesh === null ) {
|
|
55
55
|
|
|
56
|
-
this.
|
|
56
|
+
this.backgroundMeshNode = context( backgroundNode, {
|
|
57
57
|
// @TODO: Add Texture2D support using node context
|
|
58
|
-
getUVNode: () =>
|
|
58
|
+
getUVNode: () => normalWorld,
|
|
59
59
|
getSamplerLevelNode: () => backgroundBlurriness
|
|
60
|
-
} );
|
|
60
|
+
} ).mul( backgroundIntensity );
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
let viewProj = modelViewProjection();
|
|
63
|
+
viewProj = vec4( viewProj.x, viewProj.y, viewProj.w, viewProj.w );
|
|
64
|
+
|
|
65
|
+
const nodeMaterial = new NodeMaterial();
|
|
66
|
+
nodeMaterial.outputNode = this.backgroundMeshNode;
|
|
64
67
|
nodeMaterial.side = BackSide;
|
|
65
68
|
nodeMaterial.depthTest = false;
|
|
66
69
|
nodeMaterial.depthWrite = false;
|
|
67
70
|
nodeMaterial.fog = false;
|
|
71
|
+
nodeMaterial.vertexNode = viewProj;
|
|
68
72
|
|
|
69
|
-
this.
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
boxMesh.onBeforeRender = function ( renderer, scene, camera ) {
|
|
73
|
+
this.backgroundMesh = backgroundMesh = new Mesh( new SphereGeometry( 1, 32, 32 ), nodeMaterial );
|
|
74
|
+
backgroundMesh.frustumCulled = false;
|
|
73
75
|
|
|
74
|
-
|
|
76
|
+
backgroundMesh.onBeforeRender = function ( renderer, scene, camera ) {
|
|
75
77
|
|
|
76
|
-
this.matrixWorld.
|
|
78
|
+
this.matrixWorld.copyPosition( camera.matrixWorld );
|
|
77
79
|
|
|
78
80
|
};
|
|
79
81
|
|
|
@@ -83,15 +85,15 @@ class Background extends DataMap {
|
|
|
83
85
|
|
|
84
86
|
if ( sceneData.backgroundCacheKey !== backgroundCacheKey ) {
|
|
85
87
|
|
|
86
|
-
this.
|
|
88
|
+
this.backgroundMeshNode.node = backgroundNode;
|
|
87
89
|
|
|
88
|
-
|
|
90
|
+
backgroundMesh.material.needsUpdate = true;
|
|
89
91
|
|
|
90
92
|
sceneData.backgroundCacheKey = backgroundCacheKey;
|
|
91
93
|
|
|
92
94
|
}
|
|
93
95
|
|
|
94
|
-
renderList.unshift(
|
|
96
|
+
renderList.unshift( backgroundMesh, backgroundMesh.geometry, backgroundMesh.material, 0, 0, null );
|
|
95
97
|
|
|
96
98
|
} else {
|
|
97
99
|
|
|
@@ -34,9 +34,7 @@ class Bindings extends DataMap {
|
|
|
34
34
|
|
|
35
35
|
this._init( bindings );
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
this.backend.createBindings( bindings, pipeline );
|
|
37
|
+
this.backend.createBindings( bindings );
|
|
40
38
|
|
|
41
39
|
}
|
|
42
40
|
|
|
@@ -58,9 +56,7 @@ class Bindings extends DataMap {
|
|
|
58
56
|
|
|
59
57
|
this._init( bindings );
|
|
60
58
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
this.backend.createBindings( bindings, pipeline );
|
|
59
|
+
this.backend.createBindings( bindings );
|
|
64
60
|
|
|
65
61
|
}
|
|
66
62
|
|
|
@@ -23,17 +23,22 @@ class Pipelines extends DataMap {
|
|
|
23
23
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
getForCompute( computeNode ) {
|
|
26
|
+
getForCompute( computeNode, bindings ) {
|
|
27
27
|
|
|
28
28
|
const { backend } = this;
|
|
29
29
|
|
|
30
30
|
const data = this.get( computeNode );
|
|
31
31
|
|
|
32
|
-
if (
|
|
32
|
+
if ( this._needsComputeUpdate( computeNode ) ) {
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
const previousPipeline = data.pipeline;
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
if ( previousPipeline ) {
|
|
37
|
+
|
|
38
|
+
previousPipeline.usedTimes --;
|
|
39
|
+
previousPipeline.computeProgram.usedTimes --;
|
|
40
|
+
|
|
41
|
+
}
|
|
37
42
|
|
|
38
43
|
// get shader
|
|
39
44
|
|
|
@@ -45,7 +50,7 @@ class Pipelines extends DataMap {
|
|
|
45
50
|
|
|
46
51
|
if ( stageCompute === undefined ) {
|
|
47
52
|
|
|
48
|
-
if ( previousPipeline ) this._releaseProgram( previousPipeline.
|
|
53
|
+
if ( previousPipeline && previousPipeline.computeProgram.usedTimes === 0 ) this._releaseProgram( previousPipeline.computeProgram );
|
|
49
54
|
|
|
50
55
|
stageCompute = new ProgrammableStage( nodeBuilder.computeShader, 'compute' );
|
|
51
56
|
this.programs.compute.set( nodeBuilder.computeShader, stageCompute );
|
|
@@ -56,7 +61,17 @@ class Pipelines extends DataMap {
|
|
|
56
61
|
|
|
57
62
|
// determine compute pipeline
|
|
58
63
|
|
|
59
|
-
const
|
|
64
|
+
const cacheKey = this._getComputeCacheKey( computeNode, stageCompute );
|
|
65
|
+
|
|
66
|
+
let pipeline = this.caches.get( cacheKey );
|
|
67
|
+
|
|
68
|
+
if ( pipeline === undefined ) {
|
|
69
|
+
|
|
70
|
+
if ( previousPipeline && previousPipeline.usedTimes === 0 ) this._releasePipeline( computeNode );
|
|
71
|
+
|
|
72
|
+
pipeline = this._getComputePipeline( computeNode, stageCompute, cacheKey, bindings );
|
|
73
|
+
|
|
74
|
+
}
|
|
60
75
|
|
|
61
76
|
// keep track of all used times
|
|
62
77
|
|
|
@@ -65,6 +80,7 @@ class Pipelines extends DataMap {
|
|
|
65
80
|
|
|
66
81
|
//
|
|
67
82
|
|
|
83
|
+
data.version = computeNode.version;
|
|
68
84
|
data.pipeline = pipeline;
|
|
69
85
|
|
|
70
86
|
}
|
|
@@ -79,11 +95,17 @@ class Pipelines extends DataMap {
|
|
|
79
95
|
|
|
80
96
|
const data = this.get( renderObject );
|
|
81
97
|
|
|
82
|
-
if ( this.
|
|
98
|
+
if ( this._needsRenderUpdate( renderObject ) ) {
|
|
99
|
+
|
|
100
|
+
const previousPipeline = data.pipeline;
|
|
83
101
|
|
|
84
|
-
|
|
102
|
+
if ( previousPipeline ) {
|
|
85
103
|
|
|
86
|
-
|
|
104
|
+
previousPipeline.usedTimes --;
|
|
105
|
+
previousPipeline.vertexProgram.usedTimes --;
|
|
106
|
+
previousPipeline.fragmentProgram.usedTimes --;
|
|
107
|
+
|
|
108
|
+
}
|
|
87
109
|
|
|
88
110
|
// get shader
|
|
89
111
|
|
|
@@ -95,7 +117,7 @@ class Pipelines extends DataMap {
|
|
|
95
117
|
|
|
96
118
|
if ( stageVertex === undefined ) {
|
|
97
119
|
|
|
98
|
-
if ( previousPipeline ) this._releaseProgram( previousPipeline.vertexProgram );
|
|
120
|
+
if ( previousPipeline && previousPipeline.vertexProgram.usedTimes === 0 ) this._releaseProgram( previousPipeline.vertexProgram );
|
|
99
121
|
|
|
100
122
|
stageVertex = new ProgrammableStage( nodeBuilder.vertexShader, 'vertex' );
|
|
101
123
|
this.programs.vertex.set( nodeBuilder.vertexShader, stageVertex );
|
|
@@ -108,7 +130,7 @@ class Pipelines extends DataMap {
|
|
|
108
130
|
|
|
109
131
|
if ( stageFragment === undefined ) {
|
|
110
132
|
|
|
111
|
-
if ( previousPipeline ) this._releaseProgram( previousPipeline.
|
|
133
|
+
if ( previousPipeline && previousPipeline.fragmentProgram.usedTimes === 0 ) this._releaseProgram( previousPipeline.fragmentProgram );
|
|
112
134
|
|
|
113
135
|
stageFragment = new ProgrammableStage( nodeBuilder.fragmentShader, 'fragment' );
|
|
114
136
|
this.programs.fragment.set( nodeBuilder.fragmentShader, stageFragment );
|
|
@@ -119,7 +141,21 @@ class Pipelines extends DataMap {
|
|
|
119
141
|
|
|
120
142
|
// determine render pipeline
|
|
121
143
|
|
|
122
|
-
const
|
|
144
|
+
const cacheKey = this._getRenderCacheKey( renderObject, stageVertex, stageFragment );
|
|
145
|
+
|
|
146
|
+
let pipeline = this.caches.get( cacheKey );
|
|
147
|
+
|
|
148
|
+
if ( pipeline === undefined ) {
|
|
149
|
+
|
|
150
|
+
if ( previousPipeline && previousPipeline.usedTimes === 0 ) this._releasePipeline( previousPipeline );
|
|
151
|
+
|
|
152
|
+
pipeline = this._getRenderPipeline( renderObject, stageVertex, stageFragment, cacheKey );
|
|
153
|
+
|
|
154
|
+
} else {
|
|
155
|
+
|
|
156
|
+
renderObject.pipeline = pipeline;
|
|
157
|
+
|
|
158
|
+
}
|
|
123
159
|
|
|
124
160
|
// keep track of all used times
|
|
125
161
|
|
|
@@ -139,18 +175,31 @@ class Pipelines extends DataMap {
|
|
|
139
175
|
|
|
140
176
|
delete( object ) {
|
|
141
177
|
|
|
142
|
-
const pipeline = this.
|
|
178
|
+
const pipeline = this.get( object ).pipeline;
|
|
179
|
+
|
|
180
|
+
if ( pipeline ) {
|
|
181
|
+
|
|
182
|
+
// pipeline
|
|
183
|
+
|
|
184
|
+
pipeline.usedTimes --;
|
|
143
185
|
|
|
144
|
-
|
|
186
|
+
if ( pipeline.usedTimes === 0 ) this._releasePipeline( pipeline );
|
|
187
|
+
|
|
188
|
+
// programs
|
|
145
189
|
|
|
146
190
|
if ( pipeline.isComputePipeline ) {
|
|
147
191
|
|
|
148
|
-
|
|
192
|
+
pipeline.computeProgram.usedTimes --;
|
|
193
|
+
|
|
194
|
+
if ( pipeline.computeProgram.usedTimes === 0 ) this._releaseProgram( pipeline.computeProgram );
|
|
149
195
|
|
|
150
196
|
} else {
|
|
151
197
|
|
|
152
|
-
|
|
153
|
-
|
|
198
|
+
pipeline.fragmentProgram.usedTimes --;
|
|
199
|
+
pipeline.vertexProgram.usedTimes --;
|
|
200
|
+
|
|
201
|
+
if ( pipeline.vertexProgram.usedTimes === 0 ) this._releaseProgram( pipeline.vertexProgram );
|
|
202
|
+
if ( pipeline.fragmentProgram.usedTimes === 0 ) this._releaseProgram( pipeline.fragmentProgram );
|
|
154
203
|
|
|
155
204
|
}
|
|
156
205
|
|
|
@@ -173,11 +222,17 @@ class Pipelines extends DataMap {
|
|
|
173
222
|
|
|
174
223
|
}
|
|
175
224
|
|
|
176
|
-
|
|
225
|
+
updateForRender( renderObject ) {
|
|
226
|
+
|
|
227
|
+
this.getForRender( renderObject );
|
|
228
|
+
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
_getComputePipeline( computeNode, stageCompute, cacheKey, bindings ) {
|
|
177
232
|
|
|
178
233
|
// check for existing pipeline
|
|
179
234
|
|
|
180
|
-
|
|
235
|
+
cacheKey = cacheKey || this._getComputeCacheKey( computeNode, stageCompute );
|
|
181
236
|
|
|
182
237
|
let pipeline = this.caches.get( cacheKey );
|
|
183
238
|
|
|
@@ -187,7 +242,7 @@ class Pipelines extends DataMap {
|
|
|
187
242
|
|
|
188
243
|
this.caches.set( cacheKey, pipeline );
|
|
189
244
|
|
|
190
|
-
this.backend.createComputePipeline( pipeline );
|
|
245
|
+
this.backend.createComputePipeline( pipeline, bindings );
|
|
191
246
|
|
|
192
247
|
}
|
|
193
248
|
|
|
@@ -195,11 +250,11 @@ class Pipelines extends DataMap {
|
|
|
195
250
|
|
|
196
251
|
}
|
|
197
252
|
|
|
198
|
-
_getRenderPipeline( renderObject, stageVertex, stageFragment ) {
|
|
253
|
+
_getRenderPipeline( renderObject, stageVertex, stageFragment, cacheKey ) {
|
|
199
254
|
|
|
200
255
|
// check for existing pipeline
|
|
201
256
|
|
|
202
|
-
|
|
257
|
+
cacheKey = cacheKey || this._getRenderCacheKey( renderObject, stageVertex, stageFragment );
|
|
203
258
|
|
|
204
259
|
let pipeline = this.caches.get( cacheKey );
|
|
205
260
|
|
|
@@ -213,15 +268,15 @@ class Pipelines extends DataMap {
|
|
|
213
268
|
|
|
214
269
|
this.backend.createRenderPipeline( renderObject );
|
|
215
270
|
|
|
216
|
-
}
|
|
271
|
+
}
|
|
217
272
|
|
|
218
|
-
|
|
273
|
+
return pipeline;
|
|
219
274
|
|
|
220
|
-
|
|
275
|
+
}
|
|
221
276
|
|
|
222
|
-
|
|
277
|
+
_getComputeCacheKey( computeNode, stageCompute ) {
|
|
223
278
|
|
|
224
|
-
return
|
|
279
|
+
return 'compute' + computeNode.id + stageCompute.id;
|
|
225
280
|
|
|
226
281
|
}
|
|
227
282
|
|
|
@@ -247,36 +302,30 @@ class Pipelines extends DataMap {
|
|
|
247
302
|
|
|
248
303
|
}
|
|
249
304
|
|
|
250
|
-
_releasePipeline(
|
|
251
|
-
|
|
252
|
-
const pipeline = this.get( object ).pipeline;
|
|
305
|
+
_releasePipeline( pipeline ) {
|
|
253
306
|
|
|
254
|
-
|
|
307
|
+
this.caches.delete( pipeline.cacheKey );
|
|
255
308
|
|
|
256
|
-
|
|
309
|
+
}
|
|
257
310
|
|
|
258
|
-
|
|
311
|
+
_releaseProgram( program ) {
|
|
259
312
|
|
|
260
|
-
|
|
313
|
+
const code = program.code;
|
|
314
|
+
const stage = program.stage;
|
|
261
315
|
|
|
262
|
-
|
|
316
|
+
this.programs[ stage ].delete( code );
|
|
263
317
|
|
|
264
318
|
}
|
|
265
319
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
if ( -- program.usedTimes === 0 ) {
|
|
320
|
+
_needsComputeUpdate( computeNode ) {
|
|
269
321
|
|
|
270
|
-
|
|
271
|
-
const stage = program.stage;
|
|
272
|
-
|
|
273
|
-
this.programs[ stage ].delete( code );
|
|
322
|
+
const data = this.get( computeNode );
|
|
274
323
|
|
|
275
|
-
|
|
324
|
+
return data.pipeline === undefined || data.version !== computeNode.version;
|
|
276
325
|
|
|
277
326
|
}
|
|
278
327
|
|
|
279
|
-
|
|
328
|
+
_needsRenderUpdate( renderObject ) {
|
|
280
329
|
|
|
281
330
|
const data = this.get( renderObject );
|
|
282
331
|
const material = renderObject.material;
|
|
@@ -312,7 +361,7 @@ class Pipelines extends DataMap {
|
|
|
312
361
|
|
|
313
362
|
}
|
|
314
363
|
|
|
315
|
-
return needsUpdate || data.pipeline
|
|
364
|
+
return needsUpdate || data.pipeline === undefined;
|
|
316
365
|
|
|
317
366
|
}
|
|
318
367
|
|
|
@@ -5,31 +5,42 @@ class RenderContexts {
|
|
|
5
5
|
|
|
6
6
|
constructor() {
|
|
7
7
|
|
|
8
|
-
this.
|
|
8
|
+
this.chainMaps = {};
|
|
9
9
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
get( scene, camera ) {
|
|
12
|
+
get( scene, camera, renderTarget = null ) {
|
|
13
13
|
|
|
14
14
|
const chainKey = [ scene, camera ];
|
|
15
|
+
const attachmentState = renderTarget === null ? 'default' : `${renderTarget.texture.format}:${renderTarget.samples}:${renderTarget.depthBuffer}:${renderTarget.stencilBuffer}`;
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
const chainMap = this.getChainMap( attachmentState );
|
|
18
|
+
|
|
19
|
+
let renderState = chainMap.get( chainKey );
|
|
17
20
|
|
|
18
21
|
if ( renderState === undefined ) {
|
|
19
22
|
|
|
20
23
|
renderState = new RenderContext();
|
|
21
24
|
|
|
22
|
-
|
|
25
|
+
chainMap.set( chainKey, renderState );
|
|
23
26
|
|
|
24
27
|
}
|
|
25
28
|
|
|
29
|
+
if ( renderTarget !== null ) renderState.sampleCount = renderTarget.samples === 0 ? 1 : renderTarget.samples;
|
|
30
|
+
|
|
26
31
|
return renderState;
|
|
27
32
|
|
|
28
33
|
}
|
|
29
34
|
|
|
35
|
+
getChainMap( attachmentState ) {
|
|
36
|
+
|
|
37
|
+
return this.chainMaps[ attachmentState ] || ( this.chainMaps[ attachmentState ] = new ChainMap() );
|
|
38
|
+
|
|
39
|
+
}
|
|
40
|
+
|
|
30
41
|
dispose() {
|
|
31
42
|
|
|
32
|
-
this.
|
|
43
|
+
this.chainMaps = {};
|
|
33
44
|
|
|
34
45
|
}
|
|
35
46
|
|