Skip to content

Commit

Permalink
TSL: Introduce instance() for custom use (#29911)
Browse files Browse the repository at this point in the history
* Introduce `instance()` for custom use

* cleanup

* update names
  • Loading branch information
sunag authored Nov 16, 2024
1 parent 5b51d6f commit d792454
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 23 deletions.
6 changes: 3 additions & 3 deletions src/materials/nodes/NodeMaterial.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { output, diffuseColor, emissive, varyingProperty } from '../../nodes/cor
import { materialAlphaTest, materialColor, materialOpacity, materialEmissive, materialNormal, materialLightMap, materialAOMap } from '../../nodes/accessors/MaterialNode.js';
import { modelViewProjection } from '../../nodes/accessors/ModelViewProjectionNode.js';
import { normalLocal } from '../../nodes/accessors/Normal.js';
import { instance } from '../../nodes/accessors/InstanceNode.js';
import { instancedMesh } from '../../nodes/accessors/InstancedMeshNode.js';
import { batch } from '../../nodes/accessors/BatchNode.js';
import { materialReference } from '../../nodes/accessors/MaterialReferenceNode.js';
import { positionLocal, positionView } from '../../nodes/accessors/Position.js';
Expand Down Expand Up @@ -342,9 +342,9 @@ class NodeMaterial extends Material {

}

if ( ( object.instanceMatrix && object.instanceMatrix.isInstancedBufferAttribute === true ) ) {
if ( ( object.isInstancedMesh && object.instanceMatrix && object.instanceMatrix.isInstancedBufferAttribute === true ) ) {

instance( object ).append();
instancedMesh( object ).append();

}

Expand Down
1 change: 1 addition & 0 deletions src/nodes/Nodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export { default as BufferNode } from './accessors/BufferNode.js';
export { default as VertexColorNode } from './accessors/VertexColorNode.js';
export { default as CubeTextureNode } from './accessors/CubeTextureNode.js';
export { default as InstanceNode } from './accessors/InstanceNode.js';
export { default as InstancedMeshNode } from './accessors/InstancedMeshNode.js';
export { default as BatchNode } from './accessors/BatchNode.js';
export { default as MaterialNode } from './accessors/MaterialNode.js';
export { default as MaterialReferenceNode } from './accessors/MaterialReferenceNode.js';
Expand Down
1 change: 1 addition & 0 deletions src/nodes/TSL.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export * from './accessors/Camera.js';
export * from './accessors/VertexColorNode.js';
export * from './accessors/CubeTextureNode.js';
export * from './accessors/InstanceNode.js';
export * from './accessors/InstancedMeshNode.js';
export * from './accessors/BatchNode.js';
export * from './accessors/MaterialNode.js';
export * from './accessors/MaterialProperties.js';
Expand Down
37 changes: 17 additions & 20 deletions src/nodes/accessors/InstanceNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@ class InstanceNode extends Node {

}

constructor( instanceMesh ) {
constructor( count, instanceMatrix, instanceColor ) {

super( 'void' );

this.instanceMesh = instanceMesh;
this.count = count;
this.instanceMatrix = instanceMatrix;
this.instanceColor = instanceColor;

this.instanceMatrixNode = null;

Expand All @@ -39,28 +41,25 @@ class InstanceNode extends Node {

setup( builder ) {

let instanceMatrixNode = this.instanceMatrixNode;
let instanceColorNode = this.instanceColorNode;
const { count, instanceMatrix, instanceColor } = this;

const instanceMesh = this.instanceMesh;
let { instanceMatrixNode, instanceColorNode } = this;

if ( instanceMatrixNode === null ) {

const instanceAttribute = instanceMesh.instanceMatrix;

// 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.

if ( instanceMesh.count <= 1000 ) {
if ( count <= 1000 ) {

instanceMatrixNode = buffer( instanceAttribute.array, 'mat4', Math.max( instanceMesh.count, 1 ) ).element( instanceIndex );
instanceMatrixNode = buffer( instanceMatrix.array, 'mat4', Math.max( count, 1 ) ).element( instanceIndex );

} else {

const buffer = new InstancedInterleavedBuffer( instanceAttribute.array, 16, 1 );
const buffer = new InstancedInterleavedBuffer( instanceMatrix.array, 16, 1 );

this.buffer = buffer;

const bufferFn = instanceAttribute.usage === DynamicDrawUsage ? instancedDynamicBufferAttribute : instancedBufferAttribute;
const bufferFn = instanceMatrix.usage === DynamicDrawUsage ? instancedDynamicBufferAttribute : instancedBufferAttribute;

const instanceBuffers = [
// F.Signature -> bufferAttribute( array, type, stride, offset )
Expand All @@ -78,13 +77,11 @@ class InstanceNode extends Node {

}

const instanceColorAttribute = instanceMesh.instanceColor;

if ( instanceColorAttribute && instanceColorNode === null ) {
if ( instanceColor && instanceColorNode === null ) {

const buffer = new InstancedBufferAttribute( instanceColorAttribute.array, 3 );
const buffer = new InstancedBufferAttribute( instanceColor.array, 3 );

const bufferFn = instanceColorAttribute.usage === DynamicDrawUsage ? instancedDynamicBufferAttribute : instancedBufferAttribute;
const bufferFn = instanceColor.usage === DynamicDrawUsage ? instancedDynamicBufferAttribute : instancedBufferAttribute;

this.bufferColor = buffer;

Expand Down Expand Up @@ -123,15 +120,15 @@ class InstanceNode extends Node {

update( /*frame*/ ) {

if ( this.instanceMesh.instanceMatrix.usage !== DynamicDrawUsage && this.buffer != null && this.instanceMesh.instanceMatrix.version !== this.buffer.version ) {
if ( this.instanceMatrix.usage !== DynamicDrawUsage && this.buffer != null && this.instanceMatrix.version !== this.buffer.version ) {

this.buffer.version = this.instanceMesh.instanceMatrix.version;
this.buffer.version = this.instanceMatrix.version;

}

if ( this.instanceMesh.instanceColor && this.instanceMesh.instanceColor.usage !== DynamicDrawUsage && this.bufferColor != null && this.instanceMesh.instanceColor.version !== this.bufferColor.version ) {
if ( this.instanceColor && this.instanceColor.usage !== DynamicDrawUsage && this.bufferColor != null && this.instanceColor.version !== this.bufferColor.version ) {

this.bufferColor.version = this.instanceMesh.instanceColor.version;
this.bufferColor.version = this.instanceColor.version;

}

Expand Down
26 changes: 26 additions & 0 deletions src/nodes/accessors/InstancedMeshNode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import InstanceNode from './InstanceNode.js';
import { nodeProxy } from '../tsl/TSLBase.js';

class InstancedMeshNode extends InstanceNode {

static get type() {

return 'InstancedMeshNode';

}

constructor( instanceMesh ) {

const { count, instanceMatrix, instanceColor } = instanceMesh;

super( count, instanceMatrix, instanceColor );

this.instanceMesh = instanceMesh;

}

}

export default InstancedMeshNode;

export const instancedMesh = /*@__PURE__*/ nodeProxy( InstancedMeshNode );

0 comments on commit d792454

Please sign in to comment.