super-three 0.155.0 → 0.156.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 +107 -125
- package/build/three.js +107 -125
- package/build/three.min.js +1 -1
- package/build/three.module.js +104 -126
- package/build/three.module.min.js +1 -1
- package/examples/jsm/controls/OrbitControls.js +13 -5
- package/examples/jsm/csm/CSMShader.js +35 -1
- package/examples/jsm/libs/tween.module.js +790 -735
- package/examples/jsm/libs/utif.module.js +1644 -1558
- package/examples/jsm/loaders/DDSLoader.js +46 -3
- package/examples/jsm/loaders/EXRLoader.js +4 -4
- package/examples/jsm/loaders/FBXLoader.js +2 -0
- package/examples/jsm/loaders/GLTFLoader.js +17 -7
- package/examples/jsm/loaders/KTX2Loader.js +126 -77
- package/examples/jsm/loaders/LogLuvLoader.js +2 -2
- package/examples/jsm/loaders/MMDLoader.js +10 -7
- package/examples/jsm/loaders/RGBELoader.js +48 -66
- package/examples/jsm/loaders/STLLoader.js +7 -0
- package/examples/jsm/nodes/Nodes.js +3 -0
- package/examples/jsm/nodes/accessors/BufferAttributeNode.js +28 -2
- package/examples/jsm/nodes/accessors/CubeTextureNode.js +18 -3
- package/examples/jsm/nodes/accessors/ExtendedMaterialNode.js +2 -4
- package/examples/jsm/nodes/accessors/LineMaterialNode.js +31 -0
- package/examples/jsm/nodes/accessors/MaterialNode.js +55 -33
- package/examples/jsm/nodes/accessors/MaterialReferenceNode.js +3 -0
- package/examples/jsm/nodes/accessors/Object3DNode.js +2 -2
- package/examples/jsm/nodes/accessors/TextureNode.js +6 -2
- package/examples/jsm/nodes/accessors/TextureStoreNode.js +29 -0
- package/examples/jsm/nodes/core/AttributeNode.js +2 -2
- package/examples/jsm/nodes/core/Node.js +17 -1
- package/examples/jsm/nodes/core/NodeBuilder.js +94 -12
- package/examples/jsm/nodes/core/NodeUniform.js +1 -1
- package/examples/jsm/nodes/core/OutputStructNode.js +58 -0
- package/examples/jsm/nodes/core/PropertyNode.js +2 -0
- package/examples/jsm/nodes/core/StackNode.js +4 -4
- package/examples/jsm/nodes/core/StructTypeNode.js +24 -0
- package/examples/jsm/nodes/display/ViewportNode.js +19 -5
- package/examples/jsm/nodes/materials/LineDashedNodeMaterial.js +54 -0
- package/examples/jsm/nodes/materials/Materials.js +1 -0
- package/examples/jsm/nodes/materials/NodeMaterial.js +12 -3
- package/examples/jsm/nodes/math/HashNode.js +35 -0
- package/examples/jsm/nodes/shadernode/ShaderNode.js +4 -0
- package/examples/jsm/nodes/utils/SplitNode.js +1 -1
- package/examples/jsm/postprocessing/FilmPass.js +3 -5
- package/examples/jsm/postprocessing/RenderPass.js +30 -12
- package/examples/jsm/postprocessing/SAOPass.js +23 -98
- package/examples/jsm/postprocessing/SSAOPass.js +10 -30
- package/examples/jsm/renderers/common/Backend.js +11 -8
- package/examples/jsm/renderers/common/Binding.js +6 -0
- package/examples/jsm/renderers/common/Bindings.js +5 -4
- package/examples/jsm/renderers/common/Pipelines.js +2 -2
- package/examples/jsm/renderers/common/RenderContexts.js +26 -1
- package/examples/jsm/renderers/common/RenderList.js +12 -4
- package/examples/jsm/renderers/common/RenderObject.js +6 -2
- package/examples/jsm/renderers/common/Renderer.js +12 -3
- package/examples/jsm/renderers/common/SampledTexture.js +2 -1
- package/examples/jsm/renderers/common/Sampler.js +1 -1
- package/examples/jsm/renderers/common/StorageBuffer.js +1 -1
- package/examples/jsm/renderers/common/Textures.js +155 -15
- package/examples/jsm/renderers/common/nodes/NodeSampledTexture.js +2 -2
- package/examples/jsm/renderers/common/nodes/NodeSampler.js +1 -1
- package/examples/jsm/renderers/common/nodes/Nodes.js +43 -9
- package/examples/jsm/renderers/webgl/WebGLBackend.js +607 -0
- package/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js +118 -17
- package/examples/jsm/renderers/webgl/utils/WebGLAttributeUtils.js +84 -0
- package/examples/jsm/renderers/webgl/utils/WebGLExtensions.js +26 -0
- package/examples/jsm/renderers/webgl/utils/WebGLState.js +529 -0
- package/examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js +199 -0
- package/examples/jsm/renderers/webgl/utils/WebGLUtils.js +242 -0
- package/examples/jsm/renderers/webgl-legacy/nodes/GLSL1NodeBuilder.js +340 -0
- package/examples/jsm/renderers/{webgl → webgl-legacy}/nodes/WebGLNodeBuilder.js +1 -1
- package/examples/jsm/renderers/webgpu/WebGPUBackend.js +279 -40
- package/examples/jsm/renderers/webgpu/WebGPURenderer.js +18 -2
- package/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js +89 -59
- package/examples/jsm/renderers/webgpu/nodes/WGSLNodeFunction.js +2 -2
- package/examples/jsm/renderers/webgpu/utils/WebGPUBindingUtils.js +15 -2
- package/examples/jsm/renderers/webgpu/utils/WebGPUPipelineUtils.js +34 -9
- package/examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js +26 -135
- package/examples/jsm/renderers/webgpu/utils/WebGPUUtils.js +6 -5
- package/examples/jsm/shaders/FilmShader.js +11 -54
- package/examples/jsm/shaders/SAOShader.js +0 -13
- package/examples/jsm/shaders/SSAOShader.js +33 -26
- package/package.json +1 -1
- package/src/Three.js +1 -0
- package/src/audio/Audio.js +6 -0
- package/src/constants.js +4 -1
- package/src/core/Object3D.js +1 -14
- package/src/core/UniformsGroup.js +2 -2
- package/src/loaders/DataTextureLoader.js +0 -2
- package/src/materials/Material.js +2 -2
- package/src/math/Vector2.js +2 -2
- package/src/math/Vector3.js +3 -3
- package/src/math/Vector4.js +4 -4
- package/src/objects/Line.js +1 -1
- package/src/objects/Mesh.js +1 -1
- package/src/objects/Points.js +1 -1
- package/src/renderers/WebGLRenderer.js +21 -49
- package/src/renderers/shaders/ShaderChunk/map_fragment.glsl.js +11 -1
- package/src/renderers/shaders/ShaderLib/background.glsl.js +8 -0
- package/src/renderers/webgl/WebGLBackground.js +5 -14
- package/src/renderers/webgl/WebGLProgram.js +2 -0
- package/src/renderers/webgl/WebGLPrograms.js +5 -1
- package/src/renderers/webgl/WebGLTextures.js +4 -4
- package/src/renderers/webgl/WebGLUtils.js +27 -20
- package/src/textures/Texture.js +2 -2
- package/src/utils.js +9 -1
- /package/examples/jsm/renderers/{webgl → webgl-legacy}/nodes/SlotNode.js +0 -0
- /package/examples/jsm/renderers/{webgl → webgl-legacy}/nodes/WebGLNodes.js +0 -0
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import { MathNode, GLSLNodeParser, NodeBuilder, NodeMaterial } from '
|
|
1
|
+
import { MathNode, GLSLNodeParser, NodeBuilder, NodeMaterial } from '../../../nodes/Nodes.js';
|
|
2
|
+
|
|
3
|
+
import UniformsGroup from '../../common/UniformsGroup.js';
|
|
4
|
+
import { NodeSampledTexture, NodeSampledCubeTexture } from '../../common/nodes/NodeSampledTexture.js';
|
|
2
5
|
|
|
3
6
|
const glslMethods = {
|
|
4
7
|
[ MathNode.ATAN2 ]: 'atan'
|
|
@@ -16,6 +19,8 @@ class GLSLNodeBuilder extends NodeBuilder {
|
|
|
16
19
|
|
|
17
20
|
super( object, renderer, new GLSLNodeParser(), scene );
|
|
18
21
|
|
|
22
|
+
this.uniformsGroup = {};
|
|
23
|
+
|
|
19
24
|
}
|
|
20
25
|
|
|
21
26
|
getMethod( method ) {
|
|
@@ -32,15 +37,13 @@ class GLSLNodeBuilder extends NodeBuilder {
|
|
|
32
37
|
|
|
33
38
|
} else {
|
|
34
39
|
|
|
35
|
-
return `
|
|
40
|
+
return `texture( ${textureProperty}, ${uvSnippet} )`;
|
|
36
41
|
|
|
37
42
|
}
|
|
38
43
|
|
|
39
44
|
}
|
|
40
45
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if ( this.material.extensions !== undefined ) this.material.extensions.shaderTextureLOD = true;
|
|
46
|
+
getTextureLevel( texture, textureProperty, uvSnippet, biasSnippet ) {
|
|
44
47
|
|
|
45
48
|
return `textureLod( ${textureProperty}, ${uvSnippet}, ${biasSnippet} )`;
|
|
46
49
|
|
|
@@ -66,25 +69,29 @@ class GLSLNodeBuilder extends NodeBuilder {
|
|
|
66
69
|
|
|
67
70
|
const uniforms = this.uniforms[ shaderStage ];
|
|
68
71
|
|
|
69
|
-
|
|
72
|
+
const bindingSnippets = [];
|
|
73
|
+
const groupSnippets = [];
|
|
70
74
|
|
|
71
75
|
for ( const uniform of uniforms ) {
|
|
72
76
|
|
|
73
77
|
let snippet = null;
|
|
78
|
+
let group = false;
|
|
74
79
|
|
|
75
80
|
if ( uniform.type === 'texture' ) {
|
|
76
81
|
|
|
77
|
-
snippet = `sampler2D ${uniform.name}
|
|
82
|
+
snippet = `sampler2D ${uniform.name};`;
|
|
78
83
|
|
|
79
84
|
} else if ( uniform.type === 'cubeTexture' ) {
|
|
80
85
|
|
|
81
|
-
snippet = `samplerCube ${uniform.name}
|
|
86
|
+
snippet = `samplerCube ${uniform.name};`;
|
|
82
87
|
|
|
83
88
|
} else {
|
|
84
89
|
|
|
85
90
|
const vectorType = this.getVectorType( uniform.type );
|
|
86
91
|
|
|
87
|
-
snippet = `${vectorType} ${uniform.name}
|
|
92
|
+
snippet = `${vectorType} ${uniform.name};`;
|
|
93
|
+
|
|
94
|
+
group = true;
|
|
88
95
|
|
|
89
96
|
}
|
|
90
97
|
|
|
@@ -92,18 +99,36 @@ class GLSLNodeBuilder extends NodeBuilder {
|
|
|
92
99
|
|
|
93
100
|
if ( precision !== null ) {
|
|
94
101
|
|
|
95
|
-
snippet =
|
|
102
|
+
snippet = precisionLib[ precision ] + ' ' + snippet;
|
|
103
|
+
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if ( group ) {
|
|
107
|
+
|
|
108
|
+
snippet = '\t' + snippet;
|
|
109
|
+
|
|
110
|
+
groupSnippets.push( snippet );
|
|
96
111
|
|
|
97
112
|
} else {
|
|
98
113
|
|
|
99
114
|
snippet = 'uniform ' + snippet;
|
|
100
115
|
|
|
116
|
+
bindingSnippets.push( snippet );
|
|
117
|
+
|
|
101
118
|
}
|
|
102
119
|
|
|
103
|
-
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
let output = '';
|
|
123
|
+
|
|
124
|
+
if ( groupSnippets.length > 0 ) {
|
|
125
|
+
|
|
126
|
+
output += this._getGLSLUniformStruct( shaderStage + 'NodeUniforms', groupSnippets.join( '\n' ) ) + '\n';
|
|
104
127
|
|
|
105
128
|
}
|
|
106
129
|
|
|
130
|
+
output += bindingSnippets.join( '\n' );
|
|
131
|
+
|
|
107
132
|
return output;
|
|
108
133
|
|
|
109
134
|
}
|
|
@@ -116,9 +141,11 @@ class GLSLNodeBuilder extends NodeBuilder {
|
|
|
116
141
|
|
|
117
142
|
const attributes = this.attributes;
|
|
118
143
|
|
|
144
|
+
let location = 0;
|
|
145
|
+
|
|
119
146
|
for ( const attribute of attributes ) {
|
|
120
147
|
|
|
121
|
-
snippet += `
|
|
148
|
+
snippet += `layout( location = ${ location ++ } ) in ${ attribute.type } ${ attribute.name };\n`;
|
|
122
149
|
|
|
123
150
|
}
|
|
124
151
|
|
|
@@ -138,7 +165,7 @@ class GLSLNodeBuilder extends NodeBuilder {
|
|
|
138
165
|
|
|
139
166
|
for ( const varying of varyings ) {
|
|
140
167
|
|
|
141
|
-
snippet += `${varying.needsInterpolation ? '
|
|
168
|
+
snippet += `${varying.needsInterpolation ? 'out' : '/*out*/'} ${varying.type} ${varying.name};\n`;
|
|
142
169
|
|
|
143
170
|
}
|
|
144
171
|
|
|
@@ -148,7 +175,7 @@ class GLSLNodeBuilder extends NodeBuilder {
|
|
|
148
175
|
|
|
149
176
|
if ( varying.needsInterpolation ) {
|
|
150
177
|
|
|
151
|
-
snippet += `
|
|
178
|
+
snippet += `in ${varying.type} ${varying.name};\n`;
|
|
152
179
|
|
|
153
180
|
}
|
|
154
181
|
|
|
@@ -184,9 +211,24 @@ class GLSLNodeBuilder extends NodeBuilder {
|
|
|
184
211
|
|
|
185
212
|
}
|
|
186
213
|
|
|
214
|
+
_getGLSLUniformStruct( name, vars ) {
|
|
215
|
+
|
|
216
|
+
return `
|
|
217
|
+
layout( std140 ) uniform ${name} {
|
|
218
|
+
${vars}
|
|
219
|
+
};`;
|
|
220
|
+
|
|
221
|
+
}
|
|
222
|
+
|
|
187
223
|
_getGLSLVertexCode( shaderData ) {
|
|
188
224
|
|
|
189
|
-
return
|
|
225
|
+
return `#version 300 es
|
|
226
|
+
|
|
227
|
+
${ this.getSignature() }
|
|
228
|
+
|
|
229
|
+
// precision
|
|
230
|
+
precision highp float;
|
|
231
|
+
precision highp int;
|
|
190
232
|
|
|
191
233
|
// uniforms
|
|
192
234
|
${shaderData.uniforms}
|
|
@@ -208,6 +250,8 @@ void main() {
|
|
|
208
250
|
// flow
|
|
209
251
|
${shaderData.flow}
|
|
210
252
|
|
|
253
|
+
gl_PointSize = 1.0;
|
|
254
|
+
|
|
211
255
|
}
|
|
212
256
|
`;
|
|
213
257
|
|
|
@@ -215,7 +259,9 @@ void main() {
|
|
|
215
259
|
|
|
216
260
|
_getGLSLFragmentCode( shaderData ) {
|
|
217
261
|
|
|
218
|
-
return
|
|
262
|
+
return `#version 300 es
|
|
263
|
+
|
|
264
|
+
${ this.getSignature() }
|
|
219
265
|
|
|
220
266
|
// precision
|
|
221
267
|
precision highp float;
|
|
@@ -230,6 +276,8 @@ ${shaderData.varyings}
|
|
|
230
276
|
// codes
|
|
231
277
|
${shaderData.codes}
|
|
232
278
|
|
|
279
|
+
layout( location = 0 ) out vec4 fragColor;
|
|
280
|
+
|
|
233
281
|
void main() {
|
|
234
282
|
|
|
235
283
|
// vars
|
|
@@ -280,7 +328,7 @@ void main() {
|
|
|
280
328
|
|
|
281
329
|
} else if ( shaderStage === 'fragment' ) {
|
|
282
330
|
|
|
283
|
-
flow += '
|
|
331
|
+
flow += 'fragColor = ';
|
|
284
332
|
|
|
285
333
|
}
|
|
286
334
|
|
|
@@ -306,6 +354,9 @@ void main() {
|
|
|
306
354
|
this.vertexShader = this._getGLSLVertexCode( shadersData.vertex );
|
|
307
355
|
this.fragmentShader = this._getGLSLFragmentCode( shadersData.fragment );
|
|
308
356
|
|
|
357
|
+
//console.log( this.vertexShader );
|
|
358
|
+
//console.log( this.fragmentShader );
|
|
359
|
+
|
|
309
360
|
} else {
|
|
310
361
|
|
|
311
362
|
console.warn( 'GLSLNodeBuilder: compute shaders are not supported.' );
|
|
@@ -315,6 +366,56 @@ void main() {
|
|
|
315
366
|
|
|
316
367
|
}
|
|
317
368
|
|
|
369
|
+
getUniformFromNode( node, type, shaderStage, name = null ) {
|
|
370
|
+
|
|
371
|
+
const uniformNode = super.getUniformFromNode( node, type, shaderStage, name );
|
|
372
|
+
const nodeData = this.getDataFromNode( node, shaderStage );
|
|
373
|
+
|
|
374
|
+
let uniformGPU = nodeData.uniformGPU;
|
|
375
|
+
|
|
376
|
+
if ( uniformGPU === undefined ) {
|
|
377
|
+
|
|
378
|
+
if ( type === 'texture' ) {
|
|
379
|
+
|
|
380
|
+
uniformGPU = new NodeSampledTexture( uniformNode.name, uniformNode.node );
|
|
381
|
+
|
|
382
|
+
this.bindings[ shaderStage ].push( uniformGPU );
|
|
383
|
+
|
|
384
|
+
} else if ( type === 'cubeTexture' ) {
|
|
385
|
+
|
|
386
|
+
uniformGPU = new NodeSampledCubeTexture( uniformNode.name, uniformNode.node );
|
|
387
|
+
|
|
388
|
+
this.bindings[ shaderStage ].push( uniformGPU );
|
|
389
|
+
|
|
390
|
+
} else {
|
|
391
|
+
|
|
392
|
+
let uniformsGroup = this.uniformsGroup[ shaderStage ];
|
|
393
|
+
|
|
394
|
+
if ( uniformsGroup === undefined ) {
|
|
395
|
+
|
|
396
|
+
uniformsGroup = new UniformsGroup( shaderStage + 'NodeUniforms' );
|
|
397
|
+
//uniformsGroup.setVisibility( gpuShaderStageLib[ shaderStage ] );
|
|
398
|
+
|
|
399
|
+
this.uniformsGroup[ shaderStage ] = uniformsGroup;
|
|
400
|
+
|
|
401
|
+
this.bindings[ shaderStage ].push( uniformsGroup );
|
|
402
|
+
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
uniformGPU = this.getNodeUniform( uniformNode, type );
|
|
406
|
+
|
|
407
|
+
uniformsGroup.addUniform( uniformGPU );
|
|
408
|
+
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
nodeData.uniformGPU = uniformGPU;
|
|
412
|
+
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
return uniformNode;
|
|
416
|
+
|
|
417
|
+
}
|
|
418
|
+
|
|
318
419
|
build() {
|
|
319
420
|
|
|
320
421
|
// @TODO: Move this code to super.build()
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
class WebGLAttributeUtils {
|
|
2
|
+
|
|
3
|
+
constructor( backend ) {
|
|
4
|
+
|
|
5
|
+
this.backend = backend;
|
|
6
|
+
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
createAttribute( attribute, bufferType ) {
|
|
10
|
+
|
|
11
|
+
const backend = this.backend;
|
|
12
|
+
const { gl } = backend;
|
|
13
|
+
|
|
14
|
+
const array = attribute.array;
|
|
15
|
+
const usage = attribute.usage || gl.STATIC_DRAW;
|
|
16
|
+
|
|
17
|
+
const bufferGPU = gl.createBuffer();
|
|
18
|
+
|
|
19
|
+
gl.bindBuffer( bufferType, bufferGPU );
|
|
20
|
+
gl.bufferData( bufferType, array, usage );
|
|
21
|
+
gl.bindBuffer( bufferType, null );
|
|
22
|
+
|
|
23
|
+
//attribute.onUploadCallback();
|
|
24
|
+
|
|
25
|
+
let type;
|
|
26
|
+
|
|
27
|
+
if ( array instanceof Float32Array ) {
|
|
28
|
+
|
|
29
|
+
type = gl.FLOAT;
|
|
30
|
+
|
|
31
|
+
} else if ( array instanceof Uint16Array ) {
|
|
32
|
+
|
|
33
|
+
if ( attribute.isFloat16BufferAttribute ) {
|
|
34
|
+
|
|
35
|
+
type = gl.HALF_FLOAT;
|
|
36
|
+
|
|
37
|
+
} else {
|
|
38
|
+
|
|
39
|
+
type = gl.UNSIGNED_SHORT;
|
|
40
|
+
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
} else if ( array instanceof Int16Array ) {
|
|
44
|
+
|
|
45
|
+
type = gl.SHORT;
|
|
46
|
+
|
|
47
|
+
} else if ( array instanceof Uint32Array ) {
|
|
48
|
+
|
|
49
|
+
type = gl.UNSIGNED_INT;
|
|
50
|
+
|
|
51
|
+
} else if ( array instanceof Int32Array ) {
|
|
52
|
+
|
|
53
|
+
type = gl.INT;
|
|
54
|
+
|
|
55
|
+
} else if ( array instanceof Int8Array ) {
|
|
56
|
+
|
|
57
|
+
type = gl.BYTE;
|
|
58
|
+
|
|
59
|
+
} else if ( array instanceof Uint8Array ) {
|
|
60
|
+
|
|
61
|
+
type = gl.UNSIGNED_BYTE;
|
|
62
|
+
|
|
63
|
+
} else if ( array instanceof Uint8ClampedArray ) {
|
|
64
|
+
|
|
65
|
+
type = gl.UNSIGNED_BYTE;
|
|
66
|
+
|
|
67
|
+
} else {
|
|
68
|
+
|
|
69
|
+
throw new Error( 'THREE.WebGLBackend: Unsupported buffer data format: ' + array );
|
|
70
|
+
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
backend.set( attribute, {
|
|
74
|
+
bufferGPU,
|
|
75
|
+
type,
|
|
76
|
+
bytesPerElement: array.BYTES_PER_ELEMENT,
|
|
77
|
+
version: attribute.version
|
|
78
|
+
} );
|
|
79
|
+
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export default WebGLAttributeUtils;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
class WebGLExtensions {
|
|
2
|
+
|
|
3
|
+
constructor( backend ) {
|
|
4
|
+
|
|
5
|
+
this.backend = backend;
|
|
6
|
+
|
|
7
|
+
this.gl = this.backend.gl;
|
|
8
|
+
this.availableExtensions = this.gl.getSupportedExtensions();
|
|
9
|
+
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
get( name ) {
|
|
13
|
+
|
|
14
|
+
return this.gl.getExtension( name );
|
|
15
|
+
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
has( name ) {
|
|
19
|
+
|
|
20
|
+
return this.availableExtensions.includes( name );
|
|
21
|
+
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export default WebGLExtensions;
|