Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/materials/nodes/NodeMaterial.js
Original file line number Diff line number Diff line change
Expand Up @@ -797,10 +797,14 @@ class NodeMaterial extends Material {

}

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

instancedMesh( object ).toStack();

} else if ( builder.instances !== null ) {

console.log( '>>', builder.instances );

}

if ( this.positionNode !== null ) {
Expand Down
7 changes: 7 additions & 0 deletions src/nodes/core/NodeBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,13 @@ class NodeBuilder {
*/
this.tab = '\t';

/**
* Reference to the current instance data.
*
* @type {?Array}
*/
this.instances = null;

/**
* Reference to the current function node.
*
Expand Down
5 changes: 4 additions & 1 deletion src/renderers/common/RenderList.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,8 @@ class RenderList {
renderOrder: object.renderOrder,
z: z,
group: group,
clippingContext: clippingContext
clippingContext: clippingContext,
instances: null
};

this.renderItems[ this.renderItemsIndex ] = renderItem;
Expand All @@ -256,6 +257,7 @@ class RenderList {
renderItem.z = z;
renderItem.group = group;
renderItem.clippingContext = clippingContext;
renderItem.instances = null;

}

Expand Down Expand Up @@ -394,6 +396,7 @@ class RenderList {
renderItem.z = null;
renderItem.group = null;
renderItem.clippingContext = null;
renderItem.instances = null;

}

Expand Down
202 changes: 22 additions & 180 deletions src/renderers/common/RenderObject.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,8 @@
import { hash, hashString } from '../../nodes/core/NodeUtils.js';
import { hash } from '../../nodes/core/NodeUtils.js';
import { getGeometryCacheKey, getProgramCacheKey } from './RenderObjectUtils.js';

let _id = 0;

function getKeys( obj ) {

const keys = Object.keys( obj );

let proto = Object.getPrototypeOf( obj );

while ( proto ) {

const descriptors = Object.getOwnPropertyDescriptors( proto );

for ( const key in descriptors ) {

if ( descriptors[ key ] !== undefined ) {

const descriptor = descriptors[ key ];

if ( descriptor && typeof descriptor.get === 'function' ) {

keys.push( key );

}

}

}

proto = Object.getPrototypeOf( proto );

}

return keys;

}

/**
* A render object is the renderer's representation of single entity that gets drawn
* with a draw command. There is no unique mapping of render objects to 3D objects in the
Expand Down Expand Up @@ -69,8 +36,9 @@ class RenderObject {
* @param {LightsNode} lightsNode - The lights node.
* @param {RenderContext} renderContext - The render context.
* @param {ClippingContext} clippingContext - The clipping context.
* @param {Array<Object3D>} [instances=null] - An array of instances for instanced rendering.
*/
constructor( nodes, geometries, renderer, object, material, scene, camera, lightsNode, renderContext, clippingContext ) {
constructor( nodes, geometries, renderer, object, material, scene, camera, lightsNode, renderContext, clippingContext, instances = null ) {

this.id = _id ++;

Expand Down Expand Up @@ -153,6 +121,13 @@ class RenderObject {
*/
this.version = material.version;

/**
* An array of instances for instanced rendering.
*
* @type {?Array<Object3D>}
*/
this.instances = instances;

/**
* The draw range of the geometry.
*
Expand Down Expand Up @@ -451,7 +426,7 @@ class RenderObject {
*/
getChainArray() {

return [ this.object, this.material, this.context, this.lightsNode ];
return [ this.object.geometry, this.material, this.context, this.lightsNode ];

}

Expand Down Expand Up @@ -626,50 +601,7 @@ class RenderObject {
*/
getGeometryCacheKey() {

const { geometry } = this;

let cacheKey = '';

for ( const name of Object.keys( geometry.attributes ).sort() ) {

const attribute = geometry.attributes[ name ];

cacheKey += name + ',';

if ( attribute.data ) cacheKey += attribute.data.stride + ',';
if ( attribute.offset ) cacheKey += attribute.offset + ',';
if ( attribute.itemSize ) cacheKey += attribute.itemSize + ',';
if ( attribute.normalized ) cacheKey += 'n,';

}

// structural equality isn't sufficient for morph targets since the
// data are maintained in textures. only if the targets are all equal
// the texture and thus the instance of `MorphNode` can be shared.

for ( const name of Object.keys( geometry.morphAttributes ).sort() ) {

const targets = geometry.morphAttributes[ name ];

cacheKey += 'morph-' + name + ',';

for ( let i = 0, l = targets.length; i < l; i ++ ) {

const attribute = targets[ i ];

cacheKey += attribute.id + ',';

}

}

if ( geometry.index ) {

cacheKey += 'index,';

}

return cacheKey;
return getGeometryCacheKey( this.geometry );

}

Expand All @@ -682,105 +614,7 @@ class RenderObject {
*/
getMaterialCacheKey() {

const { object, material, renderer } = this;

let cacheKey = material.customProgramCacheKey();

for ( const property of getKeys( material ) ) {

if ( /^(is[A-Z]|_)|^(visible|version|uuid|name|opacity|userData)$/.test( property ) ) continue;

const value = material[ property ];

let valueKey;

if ( value !== null ) {

// some material values require a formatting

const type = typeof value;

if ( type === 'number' ) {

valueKey = value !== 0 ? '1' : '0'; // Convert to on/off, important for clearcoat, transmission, etc

} else if ( type === 'object' ) {

valueKey = '{';

if ( value.isTexture ) {

valueKey += value.mapping;

// WebGPU must honor the sampler data because they are part of the bindings

if ( renderer.backend.isWebGPUBackend === true ) {

valueKey += value.magFilter;
valueKey += value.minFilter;
valueKey += value.wrapS;
valueKey += value.wrapT;
valueKey += value.wrapR;

}

}

valueKey += '}';

} else {

valueKey = String( value );

}

} else {

valueKey = String( value );

}

cacheKey += /*property + ':' +*/ valueKey + ',';

}

cacheKey += this.clippingContextCacheKey + ',';

if ( object.geometry ) {

cacheKey += this.getGeometryCacheKey();

}

if ( object.skeleton ) {

cacheKey += object.skeleton.bones.length + ',';

}

if ( object.isBatchedMesh ) {

cacheKey += object._matricesTexture.uuid + ',';

if ( object._colorsTexture !== null ) {

cacheKey += object._colorsTexture.uuid + ',';

}

}

if ( object.isInstancedMesh || object.count > 1 || Array.isArray( object.morphTargetInfluences ) ) {

// TODO: https://github.com/mrdoob/three.js/pull/29066#issuecomment-2269400850

cacheKey += object.uuid + ',';

}

cacheKey += object.receiveShadow + ',';

return hashString( cacheKey );
return getProgramCacheKey( this.object, this.material, this.renderer, this.clippingContext );

}

Expand Down Expand Up @@ -869,6 +703,14 @@ class RenderObject {

}

if ( this.instances !== null ) {

const base = Math.ceil( this.instances.length / 8 );

cacheKey = hash( cacheKey, base );

}

cacheKey = hash( cacheKey, this.camera.id );

return cacheKey;
Expand Down
Loading
Loading