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
72 changes: 68 additions & 4 deletions examples/jsm/inspector/Inspector.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import { Profiler } from './ui/Profiler.js';
import { Performance } from './tabs/Performance.js';
import { Console } from './tabs/Console.js';
import { Parameters } from './tabs/Parameters.js';
import { setText, ease } from './ui/utils.js';
import { Viewer } from './tabs/Viewer.js';
import { setText, ease, splitPath, splitCamelCase } from './ui/utils.js';

import { setConsoleFunction, REVISION } from 'three/webgpu';
import { QuadMesh, NodeMaterial, CanvasTarget, setConsoleFunction, REVISION, NoToneMapping } from 'three/webgpu';
import { renderOutput, vec3, vec4 } from 'three/tsl';

const EASE_FACTOR = 0.1;

Expand All @@ -24,6 +26,9 @@ class Inspector extends RendererInspector {
parameters.hide();
profiler.addTab( parameters );

const viewer = new Viewer();
profiler.addTab( viewer );

const performance = new Performance();
profiler.addTab( performance );

Expand All @@ -38,10 +43,12 @@ class Inspector extends RendererInspector {
this.softDeltaTime = 0;

this.statsData = new Map();
this.canvasNodes = new Map();
this.profiler = profiler;
this.performance = performance;
this.console = console;
this.parameters = parameters;
this.viewer = viewer;
this.once = {};

this.displayCycle = {
Expand Down Expand Up @@ -247,6 +254,63 @@ class Inspector extends RendererInspector {

}

getCanvasDataByNode( node ) {

let canvasData = this.canvasNodes.get( node );

if ( canvasData === undefined ) {

const renderer = this.getRenderer();

const canvas = document.createElement( 'canvas' );

const canvasTarget = new CanvasTarget( canvas );
canvasTarget.setPixelRatio( window.devicePixelRatio );
canvasTarget.setSize( 140, 140 );

const id = node.id;

const { path, name } = splitPath( splitCamelCase( node.getName() || '(unnamed)' ) );

let output = vec4( vec3( node ), 1 );
output = renderOutput( output, NoToneMapping, renderer.outputColorSpace );
output = output.context( { inspector: true } );

const material = new NodeMaterial();
material.outputNode = output;

const quad = new QuadMesh( material );
quad.name = 'Inspector - ' + name;

canvasData = {
id,
name,
path,
node,
quad,
canvasTarget,
material
};

this.canvasNodes.set( node, canvasData );

}

return canvasData;

}

resolveViewer() {

const nodes = this.currentNodes;

const renderer = this.getRenderer();
const canvasDataList = nodes.map( node => this.getCanvasDataByNode( node ) );

this.viewer.update( renderer, canvasDataList );

}

resolveFrame( frame ) {

const nextFrame = this.getFrameById( frame.frameId + 1 );
Expand Down Expand Up @@ -278,7 +342,7 @@ class Inspector extends RendererInspector {

// Frame desync, probably due to async GPU timing.

return;
frame.miscellaneous = 0;

}

Expand All @@ -298,7 +362,7 @@ class Inspector extends RendererInspector {

if ( this.displayCycle.text.needsUpdate ) {

setText( 'fps-counter', this.fps.toFixed() );
setText( 'fps-counter', this.softFPS.toFixed() );

this.performance.updateText( this, frame );

Expand Down
12 changes: 12 additions & 0 deletions examples/jsm/inspector/RendererInspector.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export class RendererInspector extends InspectorBase {

this.currentFrame = null;
this.currentRender = null;
this.currentNodes = null;

this.frames = [];
this.framesLib = {};
Expand All @@ -89,6 +90,7 @@ export class RendererInspector extends InspectorBase {

this.currentFrame = this._createFrame();
this.currentRender = this.currentFrame;
this.currentNodes = [];

}

Expand All @@ -104,6 +106,7 @@ export class RendererInspector extends InspectorBase {

this.currentFrame = null;
this.currentRender = null;
this.currentNodes = null;

this._lastFinishTime = now;

Expand Down Expand Up @@ -138,6 +141,8 @@ export class RendererInspector extends InspectorBase {

}

resolveViewer() { }

resolveFrame( /*frame*/ ) { }

async resolveTimestamp() {
Expand Down Expand Up @@ -266,12 +271,19 @@ export class RendererInspector extends InspectorBase {

if ( this.isAvailable ) {

this.resolveViewer();
this.resolveTimestamp();

}

}

inspect( node ) {

this.currentNodes.push( node );

}

beginCompute( uid, computeNode ) {

const frame = this.getFrame();
Expand Down
5 changes: 3 additions & 2 deletions examples/jsm/inspector/tabs/Performance.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class Performance extends Tab {
const frameStats = new Item( 'Frame Stats', createValueSpan(), createValueSpan(), createValueSpan() );
perfList.add( frameStats );

const miscellaneous = new Item( 'Miscellaneous / Idle', createValueSpan(), createValueSpan(), createValueSpan() );
const miscellaneous = new Item( 'Miscellaneous & Idle', createValueSpan(), createValueSpan(), createValueSpan() );
miscellaneous.domElement.firstChild.style.backgroundColor = '#00ff0b1a';
miscellaneous.domElement.firstChild.classList.add( 'no-hover' );
frameStats.add( miscellaneous );
Expand Down Expand Up @@ -235,7 +235,7 @@ class Performance extends Tab {

//

setText( 'graph-fps-counter', inspector.fps.toFixed() + ' FPS' );
setText( 'graph-fps-counter', inspector.softFPS.toFixed() + ' FPS' );

//

Expand All @@ -248,6 +248,7 @@ class Performance extends Tab {
setText( this.miscellaneous.data[ 1 ], frame.miscellaneous.toFixed( 2 ) );
setText( this.miscellaneous.data[ 2 ], '-' );
setText( this.miscellaneous.data[ 3 ], frame.miscellaneous.toFixed( 2 ) );

//

this.currentItem = null;
Expand Down
166 changes: 166 additions & 0 deletions examples/jsm/inspector/tabs/Viewer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import { Tab } from '../ui/Tab.js';
import { List } from '../ui/List.js';
import { Item } from '../ui/Item.js';

import { RendererUtils, NoToneMapping, LinearSRGBColorSpace } from 'three/webgpu';

class Viewer extends Tab {

constructor() {

super( 'Viewer' );

const nodeList = new List( 'Viewer', 'Name' );
nodeList.setGridStyle( '150px minmax(200px, 2fr)' );
nodeList.domElement.style.minWidth = '600px';

const scrollWrapper = document.createElement( 'div' );
scrollWrapper.className = 'list-scroll-wrapper';
scrollWrapper.appendChild( nodeList.domElement );
this.content.appendChild( scrollWrapper );

const nodes = new Item( 'Nodes' );
nodeList.add( nodes );

//

this.itemLibrary = new Map();
this.folderLibrary = new Map();
this.currentDataList = [];
this.nodeList = nodeList;
this.nodes = nodes;

}

getFolder( name ) {

let folder = this.folderLibrary.get( name );

if ( folder === undefined ) {

folder = new Item( name );

this.folderLibrary.set( name, folder );
this.nodeList.add( folder );

}

return folder;

}

addNodeItem( canvasData ) {

let item = this.itemLibrary.get( canvasData.id );

if ( item === undefined ) {

const name = canvasData.name;
const domElement = canvasData.canvasTarget.domElement;

item = new Item( domElement, name );
item.itemRow.children[ 1 ].style[ 'justify-content' ] = 'flex-start';
this.itemLibrary.set( canvasData.id, item );

}

return item;

}

update( renderer, canvasDataList ) {

if ( ! this.isActive ) return;

//

const previousDataList = [ ...this.currentDataList ];

// remove old

for ( const canvasData of previousDataList ) {

if ( this.itemLibrary.has( canvasData.id ) && canvasDataList.indexOf( canvasData ) === - 1 ) {

const item = this.itemLibrary.get( canvasData.id );
const parent = item.parent;

parent.remove( item );

if ( this.folderLibrary.has( parent.data[ 0 ] ) && parent.children.length === 0 ) {

parent.parent.remove( parent );

this.folderLibrary.delete( parent.data[ 0 ] );

}

this.itemLibrary.delete( canvasData.id );

}

}

//

const indexes = {};

for ( const canvasData of canvasDataList ) {

const item = this.addNodeItem( canvasData );
const previousCanvasTarget = renderer.getCanvasTarget();

const path = canvasData.path;

if ( path ) {

const folder = this.getFolder( path );

if ( indexes[ path ] === undefined ) {

indexes[ path ] = 0;

}

if ( folder.parent === null || item.parent !== folder || folder.children.indexOf( item ) !== indexes[ path ] ) {

folder.add( item );

}

indexes[ path ] ++;

} else {

if ( ! item.parent ) {

this.nodes.add( item );

}

}

this.currentDataList = canvasDataList;

//

const state = RendererUtils.resetRendererState( renderer );

renderer.toneMapping = NoToneMapping;
renderer.outputColorSpace = LinearSRGBColorSpace;

renderer.setCanvasTarget( canvasData.canvasTarget );

canvasData.quad.render( renderer );

renderer.setCanvasTarget( previousCanvasTarget );

RendererUtils.restoreRendererState( renderer, state );

}

}

}

export { Viewer };
2 changes: 1 addition & 1 deletion examples/jsm/inspector/ui/Style.js
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ export class Style {

.item-toggler {
display: inline-block;
width: 1.5em;
margin-right: 0.8em;
text-align: left;
}

Expand Down
3 changes: 3 additions & 0 deletions examples/jsm/inspector/ui/Tab.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export class Tab {
this.content.id = `${this.id}-content`;
this.content.className = 'profiler-content';

this.isActive = false;
this.isVisible = true;

}
Expand All @@ -20,6 +21,8 @@ export class Tab {
this.button.classList.toggle( 'active', isActive );
this.content.classList.toggle( 'active', isActive );

this.isActive = isActive;

}

show() {
Expand Down
Loading
Loading