Skip to content
Open
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
6b4d65d
Add node material rebuild debug reporting
RenaudRohlinger Apr 2, 2026
14f2a38
Fix image buffer normalization branch
RenaudRohlinger Apr 2, 2026
44296dc
Tests: ignore webgpu materials debug rebuild screenshot
RenaudRohlinger Apr 2, 2026
254e6e6
save node comp
RenaudRohlinger Apr 4, 2026
e5da40b
Move material rebuild debug to inspector
RenaudRohlinger Apr 10, 2026
dbf880c
Remove RenderObjects debug tests
RenaudRohlinger Apr 10, 2026
7259596
Fix analyzer CodeQL warnings
RenaudRohlinger Apr 10, 2026
1fce173
Report updateBefore material rebuilds
RenaudRohlinger Apr 10, 2026
3358050
Add node rebuild trigger example
RenaudRohlinger Apr 10, 2026
8df6ee9
Report undiffed node cache rebuilds
RenaudRohlinger Apr 10, 2026
3166024
Make node rebuild trigger per object
RenaudRohlinger Apr 10, 2026
fb1656c
Fix node toggle state in debug example
RenaudRohlinger Apr 10, 2026
af002f2
Use updateBefore event for node rebuild example
RenaudRohlinger Apr 10, 2026
3e08277
Improve node rebuild debug logging
RenaudRohlinger Apr 10, 2026
fd6b404
Update materials debug rebuild screenshot
RenaudRohlinger Apr 10, 2026
3683a60
Improve node material rebuild diagnostics
RenaudRohlinger Apr 10, 2026
98deff6
Fix node material debug analyzer lint
RenaudRohlinger Apr 10, 2026
f040b43
Improve node material refresh diagnostics
RenaudRohlinger Apr 10, 2026
0eeef3e
Add compute rebuild debug logging
RenaudRohlinger Apr 11, 2026
49bfc7e
Move material debug setting to console storage
RenaudRohlinger Apr 14, 2026
24ad366
fix wrong param
RenaudRohlinger Apr 14, 2026
fbda71e
add default info too
RenaudRohlinger Apr 14, 2026
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
1 change: 1 addition & 0 deletions examples/files.json
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@
"webgpu_materials_displacementmap",
"webgpu_materials_envmaps_bpcem",
"webgpu_materials_envmaps",
"webgpu_materials_debug_rebuild",
"webgpu_materials_lightmap",
"webgpu_materials_matcap",
"webgpu_materials_sss",
Expand Down
88 changes: 86 additions & 2 deletions examples/jsm/inspector/Inspector.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ import { Settings } from './tabs/Settings.js';
import { Viewer } from './tabs/Viewer.js';
import { Timeline } from './tabs/Timeline.js';
import { setText } from './ui/utils.js';
import NodeMaterialDebug from './NodeMaterialDebug.js';

import { setConsoleFunction, REVISION } from 'three/webgpu';

class Inspector extends RendererInspector {

constructor() {
constructor( options = {} ) {

super();

Expand Down Expand Up @@ -43,7 +44,12 @@ class Inspector extends RendererInspector {
const timeline = new Timeline();
profiler.addTab( timeline );

const consoleTab = new Console();
const consoleTab = new Console( { nodeMaterialDebugEnabled: options.nodeMaterialDebugEnabled } );
consoleTab.addEventListener( 'node-material-debug', ( event ) => {

this.setNodeMaterialDebug( event.enabled );

} );
profiler.addTab( consoleTab );

const settings = new Settings();
Expand All @@ -68,6 +74,9 @@ class Inspector extends RendererInspector {
this.settings = settings;
this.once = {};
this.extensionsData = new WeakMap();
this.nodeMaterialDebug = null;
this.onNodeMaterialInvalidation = null;
this.nodeMaterialDebugEnabled = consoleTab.nodeMaterialDebugEnabled === true;

this.displayCycle = {
text: {
Expand Down Expand Up @@ -257,21 +266,32 @@ class Inspector extends RendererInspector {

}

this.updateNodeMaterialDebug();

}

setRenderer( renderer ) {

if ( this.nodeMaterialDebug !== null ) {

this.nodeMaterialDebug.dispose();
this.nodeMaterialDebug = null;

}

super.setRenderer( renderer );

if ( renderer !== null ) {

setConsoleFunction( this.resolveConsole.bind( this ) );
this.setNodeMaterialDebug( this.nodeMaterialDebugEnabled );

if ( this.isAvailable ) {

renderer.init().then( () => {

renderer.backend.trackTimestamp = true;
this.updateNodeMaterialDebug();

if ( renderer.hasFeature( 'timestamp-query' ) !== true ) {

Expand All @@ -291,6 +311,70 @@ class Inspector extends RendererInspector {

}

beginNodeBuild( info ) {

super.beginNodeBuild( info );

if ( this.nodeMaterialDebug !== null ) this.nodeMaterialDebug.updatePendingBuildInfo( info );

}

finishNodeBuild( info ) {

super.finishNodeBuild( info );

if ( this.nodeMaterialDebug !== null ) this.nodeMaterialDebug.flushPendingInvalidations( info );

}

updateNodeMaterialDebug() {

if ( this.nodeMaterialDebug !== null ) this.nodeMaterialDebug.updateRenderer();

return this;

}

setNodeMaterialDebug( enabled ) {

this.nodeMaterialDebugEnabled = enabled === true;

const renderer = this.getRenderer();

if ( this.nodeMaterialDebugEnabled === true && renderer !== null ) {

if ( this.nodeMaterialDebug === null ) this.nodeMaterialDebug = new NodeMaterialDebug( renderer );
this.nodeMaterialDebug.onNodeMaterialInvalidation = ( event ) => {

const label = event.compute === true ? ( event.computeLabel || 'unknown compute node' ) : ( event.materialLabel || ( event.material ? event.material.name || event.material.type : 'unknown material' ) );
const type = event.compute === true ? 'Compute node' : 'NodeMaterial';

const property = event.property !== undefined ? ` via ${ event.property }` : '';
const values = event.previousValue !== undefined && event.value !== undefined ? ` (${ event.previousValue } -> ${ event.value })` : '';
const source = event.sourceProperty !== undefined && event.sourceProperty !== event.property ? ` [${ event.sourceProperty }]` : '';
const reason = event.reason !== undefined ? ` because ${ event.reason }` : '';
const buildInfo = event.buildInfo;
const timing = buildInfo && buildInfo.durationMs !== undefined ? ` in <strong>${ buildInfo.durationMs.toFixed( 3 ) } ms</strong>` : '';

this.console.addMessage( 'warn', `Renderer: ${ type } needs rebuild for "${ label }"${ property }${ values }${ source }${ reason }${ timing }.` );

if ( typeof this.onNodeMaterialInvalidation === 'function' ) this.onNodeMaterialInvalidation( event );

};

this.nodeMaterialDebug.updateRenderer();

} else if ( this.nodeMaterialDebug !== null ) {

this.nodeMaterialDebug.dispose();
this.nodeMaterialDebug = null;

}

return this;

}

createParameters( name ) {

if ( this.parameters.isVisible === false ) {
Expand Down
Loading
Loading