Skip to content
Merged
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
113 changes: 106 additions & 7 deletions src/materials/nodes/manager/NodeMaterialObserver.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,14 @@ const _materialCache = new WeakMap();
*/
const _geometryCache = new WeakMap();

/**
* Holds the texture data for comparison.
*
* @private
* @type {WeakMap<Texture,Object>}
*/
const _textureCache = new WeakMap();

/**
* This class is used by {@link WebGPURenderer} as management component.
* It's primary purpose is to determine whether render objects require a
Expand Down Expand Up @@ -355,6 +363,14 @@ class NodeMaterialObserver {
drawRange: { start: geometry.drawRange.start, count: geometry.drawRange.count }
};

// force refresh on dispose

geometry.addEventListener( 'dispose', () => {

data._version ++;

} );

_geometryCache.set( geometry, data );

}
Expand All @@ -363,6 +379,47 @@ class NodeMaterialObserver {

}

/**
* Returns a texture data structure holding the texture state for
* monitoring.
*
* @param {Texture} texture - The texture.
* @return {Object} An object for monitoring the texture.
*/
getTextureData( texture ) {

let data = _textureCache.get( texture );

if ( data === undefined ) {

data = { _version: 0 };

// force refresh on dispose

const onDispose = () => {

data._version ++;

};

if ( texture.renderTarget !== null ) {

texture.renderTarget.addEventListener( 'dispose', onDispose );

} else {

texture.addEventListener( 'dispose', onDispose );

}

_textureCache.set( texture, data );

}

return data;

}

/**
* Returns a material data structure holding the material property values for
* monitoring.
Expand All @@ -382,13 +439,17 @@ class NodeMaterialObserver {

const value = material[ property ];

if ( value === null || value === undefined ) continue;
if ( value === undefined ) continue;

if ( value === null ) {

if ( typeof value === 'object' && value.clone !== undefined ) {
data[ property ] = null; // track unset properties

} else if ( typeof value === 'object' && value.clone !== undefined ) {

if ( value.isTexture === true ) {

data[ property ] = { id: value.id, version: 0 };
data[ property ] = { id: value.id, version: 0, cacheVersion: this.getTextureData( value )._version };

} else {

Expand Down Expand Up @@ -456,7 +517,35 @@ class NodeMaterialObserver {
if ( property === '_renderId' ) continue;
if ( property === '_version' ) continue;

if ( value.equals !== undefined ) {
if ( value === null || mtlValue === null || mtlValue === undefined ) {

// a property was assigned or removed since the last observation so a new snapshot is required

if ( value !== ( mtlValue === undefined ? null : mtlValue ) ) {

if ( mtlValue === null || mtlValue === undefined ) {

materialData[ property ] = null;

} else if ( mtlValue.isTexture === true ) {

materialData[ property ] = { id: mtlValue.id, version: mtlValue.version, cacheVersion: this.getTextureData( mtlValue )._version };

} else if ( typeof mtlValue === 'object' && mtlValue.clone !== undefined ) {

materialData[ property ] = mtlValue.clone();

} else {

materialData[ property ] = mtlValue;

}

changed = true;

}

} else if ( value.equals !== undefined ) {

if ( value.equals( mtlValue ) === false ) {

Expand All @@ -468,10 +557,13 @@ class NodeMaterialObserver {

} else if ( mtlValue.isTexture === true ) {

if ( value.id !== mtlValue.id || value.version !== mtlValue.version ) {
const textureData = this.getTextureData( mtlValue );

if ( value.id !== mtlValue.id || value.version !== mtlValue.version || value.cacheVersion !== textureData._version ) {

value.id = mtlValue.id;
value.version = mtlValue.version;
value.cacheVersion = textureData._version;

changed = true;

Expand Down Expand Up @@ -521,6 +613,8 @@ class NodeMaterialObserver {
if ( renderObjectData.geometryId !== geometry.id ) {

renderObjectData.geometryId = geometry.id;
renderObjectData.geometryVersion = this.getGeometryData( geometry )._version;

return false;

}
Expand Down Expand Up @@ -692,7 +786,12 @@ class NodeMaterialObserver {

for ( let i = 0; i < lightsData.length; i ++ ) {

if ( renderObjectData.lights[ i ].map !== lightsData[ i ].map ) {
const lightData = renderObjectData.lights[ i ];

if ( lightData.map !== lightsData[ i ].map || lightData.cacheVersion !== lightsData[ i ].cacheVersion ) {

lightData.map = lightsData[ i ].map;
lightData.cacheVersion = lightsData[ i ].cacheVersion;

return false;

Expand Down Expand Up @@ -762,7 +861,7 @@ class NodeMaterialObserver {

// only add lights that have a map

lights.push( { map: light.map.version } );
lights.push( { map: light.map.version, cacheVersion: this.getTextureData( light.map )._version } );

}

Expand Down
2 changes: 1 addition & 1 deletion src/renderers/common/Bindings.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ class Bindings extends DataMap {

for ( const binding of bindGroup.bindings ) {

if ( binding.isNodeUniformsGroup === true && binding.groupNode.shared === true ) {
if ( ( binding.isNodeUniformsGroup === true || binding.isNodeUniformBuffer === true ) && binding.groupNode.shared === true ) {

const updatedGroup = this.nodes.updateGroup( binding );

Expand Down
13 changes: 11 additions & 2 deletions src/renderers/webgpu/WebGPUBackend.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import WebGPUTextureUtils from './utils/WebGPUTextureUtils.js';
import { WebGPUCoordinateSystem, TimestampQuery, REVISION, HalfFloatType, Compatibility, CustomBlending } from '../../constants.js';
import { Color } from '../../math/Color.js';
import WebGPUTimestampQueryPool from './utils/WebGPUTimestampQueryPool.js';
import { error } from '../../utils.js';
import { error, warnOnce } from '../../utils.js';

import GPUBufferDescriptor from './descriptors/GPUBufferDescriptor.js';
import GPUCommandEncoderDescriptor from './descriptors/GPUCommandEncoderDescriptor.js';
Expand Down Expand Up @@ -2309,7 +2309,16 @@ class WebGPUBackend extends Backend {
if ( renderContextData.currentPass ) {

// Handle occlusion queries
if ( renderContextData.occlusionQuerySet !== undefined ) {

if ( renderContextData.currentPass instanceof GPURenderBundleEncoder ) {

if ( object.occlusionTest === true ) {

warnOnce( 'WebGPUBackend: Occlusion queries can not be recorded into render bundles.' );

}

} else if ( renderContextData.occlusionQuerySet !== undefined ) {

const lastObject = renderContextData.lastOcclusionObject;
if ( lastObject !== object ) {
Expand Down