|
@@ -5,6 +5,8 @@ import { normalLocal } from './NormalNode.js';
|
|
import { positionLocal } from './PositionNode.js';
|
|
import { positionLocal } from './PositionNode.js';
|
|
import { nodeProxy, vec3, mat3, mat4 } from '../shadernode/ShaderNode.js';
|
|
import { nodeProxy, vec3, mat3, mat4 } from '../shadernode/ShaderNode.js';
|
|
import { NodeUpdateType } from '../core/constants.js';
|
|
import { NodeUpdateType } from '../core/constants.js';
|
|
|
|
+import { buffer } from '../accessors/BufferNode.js';
|
|
|
|
+import { instanceIndex } from '../core/IndexNode.js';
|
|
|
|
|
|
import { InstancedInterleavedBuffer } from '../../core/InstancedInterleavedBuffer.js';
|
|
import { InstancedInterleavedBuffer } from '../../core/InstancedInterleavedBuffer.js';
|
|
import { InstancedBufferAttribute } from '../../core/InstancedBufferAttribute.js';
|
|
import { InstancedBufferAttribute } from '../../core/InstancedBufferAttribute.js';
|
|
@@ -32,26 +34,39 @@ class InstanceNode extends Node {
|
|
setup( /*builder*/ ) {
|
|
setup( /*builder*/ ) {
|
|
|
|
|
|
let instanceMatrixNode = this.instanceMatrixNode;
|
|
let instanceMatrixNode = this.instanceMatrixNode;
|
|
|
|
+ let instanceColorNode = this.instanceColorNode;
|
|
|
|
|
|
const instanceMesh = this.instanceMesh;
|
|
const instanceMesh = this.instanceMesh;
|
|
|
|
|
|
if ( instanceMatrixNode === null ) {
|
|
if ( instanceMatrixNode === null ) {
|
|
|
|
|
|
const instanceAttribute = instanceMesh.instanceMatrix;
|
|
const instanceAttribute = instanceMesh.instanceMatrix;
|
|
- const buffer = new InstancedInterleavedBuffer( instanceAttribute.array, 16, 1 );
|
|
|
|
|
|
|
|
- this.buffer = buffer;
|
|
|
|
- const bufferFn = instanceAttribute.usage === DynamicDrawUsage ? instancedDynamicBufferAttribute : instancedBufferAttribute;
|
|
|
|
|
|
+ // Both WebGPU and WebGL backends have UBO max limited to 64kb. Matrix count number bigger than 1000 ( 16 * 4 * 1000 = 64kb ) will fallback to attribute.
|
|
|
|
|
|
- const instanceBuffers = [
|
|
|
|
- // F.Signature -> bufferAttribute( array, type, stride, offset )
|
|
|
|
- bufferFn( buffer, 'vec4', 16, 0 ),
|
|
|
|
- bufferFn( buffer, 'vec4', 16, 4 ),
|
|
|
|
- bufferFn( buffer, 'vec4', 16, 8 ),
|
|
|
|
- bufferFn( buffer, 'vec4', 16, 12 )
|
|
|
|
- ];
|
|
|
|
|
|
+ if ( instanceMesh.count <= 1000 ) {
|
|
|
|
|
|
- instanceMatrixNode = mat4( ...instanceBuffers );
|
|
|
|
|
|
+ instanceMatrixNode = buffer( instanceAttribute.array, 'mat4', instanceMesh.count ).element( instanceIndex );
|
|
|
|
+
|
|
|
|
+ } else {
|
|
|
|
+
|
|
|
|
+ const buffer = new InstancedInterleavedBuffer( instanceAttribute.array, 16, 1 );
|
|
|
|
+
|
|
|
|
+ this.buffer = buffer;
|
|
|
|
+
|
|
|
|
+ const bufferFn = instanceAttribute.usage === DynamicDrawUsage ? instancedDynamicBufferAttribute : instancedBufferAttribute;
|
|
|
|
+
|
|
|
|
+ const instanceBuffers = [
|
|
|
|
+ // F.Signature -> bufferAttribute( array, type, stride, offset )
|
|
|
|
+ bufferFn( buffer, 'vec4', 16, 0 ),
|
|
|
|
+ bufferFn( buffer, 'vec4', 16, 4 ),
|
|
|
|
+ bufferFn( buffer, 'vec4', 16, 8 ),
|
|
|
|
+ bufferFn( buffer, 'vec4', 16, 12 )
|
|
|
|
+ ];
|
|
|
|
+
|
|
|
|
+ instanceMatrixNode = mat4( ...instanceBuffers );
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
|
|
this.instanceMatrixNode = instanceMatrixNode;
|
|
this.instanceMatrixNode = instanceMatrixNode;
|
|
|
|
|
|
@@ -59,13 +74,17 @@ class InstanceNode extends Node {
|
|
|
|
|
|
const instanceColorAttribute = instanceMesh.instanceColor;
|
|
const instanceColorAttribute = instanceMesh.instanceColor;
|
|
|
|
|
|
- if ( instanceColorAttribute && this.instanceColorNode === null ) {
|
|
|
|
|
|
+ if ( instanceColorAttribute && instanceColorNode === null ) {
|
|
|
|
|
|
const buffer = new InstancedBufferAttribute( instanceColorAttribute.array, 3 );
|
|
const buffer = new InstancedBufferAttribute( instanceColorAttribute.array, 3 );
|
|
|
|
+
|
|
const bufferFn = instanceColorAttribute.usage === DynamicDrawUsage ? instancedDynamicBufferAttribute : instancedBufferAttribute;
|
|
const bufferFn = instanceColorAttribute.usage === DynamicDrawUsage ? instancedDynamicBufferAttribute : instancedBufferAttribute;
|
|
|
|
|
|
this.bufferColor = buffer;
|
|
this.bufferColor = buffer;
|
|
- this.instanceColorNode = vec3( bufferFn( buffer, 'vec3', 3, 0 ) );
|
|
|
|
|
|
+
|
|
|
|
+ instanceColorNode = vec3( bufferFn( buffer, 'vec3', 3, 0 ) );
|
|
|
|
+
|
|
|
|
+ this.instanceColorNode = instanceColorNode;
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@@ -98,13 +117,13 @@ class InstanceNode extends Node {
|
|
|
|
|
|
update( /*frame*/ ) {
|
|
update( /*frame*/ ) {
|
|
|
|
|
|
- if ( this.instanceMesh.instanceMatrix.usage !== DynamicDrawUsage && this.instanceMesh.instanceMatrix.version !== this.buffer.version ) {
|
|
|
|
|
|
+ if ( this.instanceMesh.instanceMatrix.usage !== DynamicDrawUsage && this.buffer != null && this.instanceMesh.instanceMatrix.version !== this.buffer.version ) {
|
|
|
|
|
|
this.buffer.version = this.instanceMesh.instanceMatrix.version;
|
|
this.buffer.version = this.instanceMesh.instanceMatrix.version;
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- if ( this.instanceMesh.instanceColor && this.instanceMesh.instanceColor.usage !== DynamicDrawUsage && this.instanceMesh.instanceColor.version !== this.bufferColor.version ) {
|
|
|
|
|
|
+ if ( this.instanceMesh.instanceColor && this.instanceMesh.instanceColor.usage !== DynamicDrawUsage && this.bufferColor != null && this.instanceMesh.instanceColor.version !== this.bufferColor.version ) {
|
|
|
|
|
|
this.bufferColor.version = this.instanceMesh.instanceColor.version;
|
|
this.bufferColor.version = this.instanceMesh.instanceColor.version;
|
|
|
|
|