Skip to content

Commit

Permalink
WebGPURenderer: Depth Pixel & Logarithmic Depth Buffer (mrdoob#27243)
Browse files Browse the repository at this point in the history
* WebGPURenderer: Depth Pixel & Logarithmic Depth Buffer

* Update puppeteer.js
  • Loading branch information
sunag authored and AdaRoseCannon committed Jan 15, 2024
1 parent 00672c7 commit bb54066
Show file tree
Hide file tree
Showing 13 changed files with 532 additions and 46 deletions.
1 change: 1 addition & 0 deletions examples/files.json
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@
"webgpu (wip)": [
"webgpu_backdrop",
"webgpu_backdrop_area",
"webgpu_camera_logarithmicdepthbuffer",
"webgpu_clearcoat",
"webgpu_compute_audio",
"webgpu_compute_particles",
Expand Down
4 changes: 2 additions & 2 deletions examples/jsm/nodes/Nodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export * from './shadernode/ShaderNode.js';
export { default as BitangentNode, bitangentGeometry, bitangentLocal, bitangentView, bitangentWorld, transformedBitangentView, transformedBitangentWorld } from './accessors/BitangentNode.js';
export { default as BufferAttributeNode, bufferAttribute, dynamicBufferAttribute, instancedBufferAttribute, instancedDynamicBufferAttribute } from './accessors/BufferAttributeNode.js';
export { default as BufferNode, buffer } from './accessors/BufferNode.js';
export { default as CameraNode, cameraProjectionMatrix, cameraViewMatrix, cameraNormalMatrix, cameraWorldMatrix, cameraPosition, cameraNear, cameraFar } from './accessors/CameraNode.js';
export { default as CameraNode, cameraProjectionMatrix, cameraViewMatrix, cameraNormalMatrix, cameraWorldMatrix, cameraPosition, cameraNear, cameraFar, cameraLogDepth } from './accessors/CameraNode.js';
export { default as CubeTextureNode, cubeTexture } from './accessors/CubeTextureNode.js';
export { default as InstanceNode, instance } from './accessors/InstanceNode.js';
export { default as MaterialNode, materialAlphaTest, materialColor, materialShininess, materialEmissive, materialOpacity, materialSpecularColor, materialSpecularStrength, materialReflectivity, materialRoughness, materialMetalness, materialNormal, materialClearcoat, materialClearcoatRoughness, materialClearcoatNormal, materialRotation, materialSheen, materialSheenRoughness, materialIridescence, materialIridescenceIOR, materialIridescenceThickness, materialLineScale, materialLineDashSize, materialLineGapSize, materialLineWidth, materialLineDashOffset, materialPointWidth } from './accessors/MaterialNode.js';
Expand Down Expand Up @@ -108,7 +108,7 @@ export { default as ViewportNode, viewport, viewportCoordinate, viewportResoluti
export { default as ViewportTextureNode, viewportTexture, viewportMipTexture } from './display/ViewportTextureNode.js';
export { default as ViewportSharedTextureNode, viewportSharedTexture } from './display/ViewportSharedTextureNode.js';
export { default as ViewportDepthTextureNode, viewportDepthTexture } from './display/ViewportDepthTextureNode.js';
export { default as ViewportDepthNode, viewZToOrthographicDepth, orthographicDepthToViewZ, viewZToPerspectiveDepth, perspectiveDepthToViewZ, depth, depthTexture } from './display/ViewportDepthNode.js';
export { default as ViewportDepthNode, viewZToOrthographicDepth, orthographicDepthToViewZ, viewZToPerspectiveDepth, perspectiveDepthToViewZ, depth, depthTexture, depthPixel } from './display/ViewportDepthNode.js';

// code
export { default as ExpressionNode, expression } from './code/ExpressionNode.js';
Expand Down
10 changes: 8 additions & 2 deletions examples/jsm/nodes/accessors/CameraNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class CameraNode extends Object3DNode {

return 'mat4';

} else if ( scope === CameraNode.NEAR || scope === CameraNode.FAR ) {
} else if ( scope === CameraNode.NEAR || scope === CameraNode.FAR || scope === CameraNode.LOG_DEPTH ) {

return 'float';

Expand Down Expand Up @@ -61,6 +61,10 @@ class CameraNode extends Object3DNode {

uniformNode.value = camera.far;

} else if ( scope === CameraNode.LOG_DEPTH ) {

uniformNode.value = 2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 );

} else {

this.object3d = camera;
Expand All @@ -79,7 +83,7 @@ class CameraNode extends Object3DNode {

this._uniformNode.nodeType = 'mat4';

} else if ( scope === CameraNode.NEAR || scope === CameraNode.FAR ) {
} else if ( scope === CameraNode.NEAR || scope === CameraNode.FAR || scope === CameraNode.LOG_DEPTH ) {

this._uniformNode.nodeType = 'float';

Expand All @@ -94,12 +98,14 @@ class CameraNode extends Object3DNode {
CameraNode.PROJECTION_MATRIX = 'projectionMatrix';
CameraNode.NEAR = 'near';
CameraNode.FAR = 'far';
CameraNode.LOG_DEPTH = 'logDepth';

export default CameraNode;

export const cameraProjectionMatrix = label( nodeImmutable( CameraNode, CameraNode.PROJECTION_MATRIX ), 'projectionMatrix' );
export const cameraNear = nodeImmutable( CameraNode, CameraNode.NEAR );
export const cameraFar = nodeImmutable( CameraNode, CameraNode.FAR );
export const cameraLogDepth = nodeImmutable( CameraNode, CameraNode.LOG_DEPTH );
export const cameraViewMatrix = nodeImmutable( CameraNode, CameraNode.VIEW_MATRIX );
export const cameraNormalMatrix = nodeImmutable( CameraNode, CameraNode.NORMAL_MATRIX );
export const cameraWorldMatrix = nodeImmutable( CameraNode, CameraNode.WORLD_MATRIX );
Expand Down
15 changes: 12 additions & 3 deletions examples/jsm/nodes/accessors/ModelViewProjectionNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,29 @@ import { cameraProjectionMatrix } from './CameraNode.js';
import { modelViewMatrix } from './ModelNode.js';
import { positionLocal } from './PositionNode.js';
import { nodeProxy } from '../shadernode/ShaderNode.js';
import { varying } from '../core/VaryingNode.js';

class ModelViewProjectionNode extends TempNode {

constructor( positionNode = positionLocal ) {
constructor( positionNode = null ) {

super( 'vec4' );

this.positionNode = positionNode;

}

setup() {
setup( builder ) {

return cameraProjectionMatrix.mul( modelViewMatrix ).mul( this.positionNode );
if ( builder.shaderStage === 'fragment' ) {

return varying( builder.context.mvp );

}

const position = this.positionNode || positionLocal;

return cameraProjectionMatrix.mul( modelViewMatrix ).mul( position );

}

Expand Down
34 changes: 31 additions & 3 deletions examples/jsm/nodes/display/ViewportDepthNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,31 @@ import { viewportDepthTexture } from './ViewportDepthTextureNode.js';

class ViewportDepthNode extends Node {

constructor( scope, textureNode = null ) {
constructor( scope, valueNode = null ) {

super( 'float' );

this.scope = scope;
this.textureNode = textureNode;
this.valueNode = valueNode;

this.isViewportDepthNode = true;

}

generate( builder ) {

const { scope } = this;

if ( scope === ViewportDepthNode.DEPTH_PIXEL ) {

return builder.getFragDepth();

}

return super.generate( builder );

}

setup( /*builder*/ ) {

const { scope } = this;
Expand All @@ -29,11 +43,19 @@ class ViewportDepthNode extends Node {

} else if ( scope === ViewportDepthNode.DEPTH_TEXTURE ) {

const texture = this.textureNode || viewportDepthTexture();
const texture = this.valueNode || viewportDepthTexture();

const viewZ = perspectiveDepthToViewZ( texture, cameraNear, cameraFar );
node = viewZToOrthographicDepth( viewZ, cameraNear, cameraFar );

} else if ( scope === ViewportDepthNode.DEPTH_PIXEL ) {

if ( this.valueNode !== null ) {

depthPixelBase().assign( this.valueNode );

}

}

return node;
Expand All @@ -60,10 +82,16 @@ export const perspectiveDepthToViewZ = ( depth, near, far ) => near.mul( far ).d

ViewportDepthNode.DEPTH = 'depth';
ViewportDepthNode.DEPTH_TEXTURE = 'depthTexture';
ViewportDepthNode.DEPTH_PIXEL = 'depthPixel';

export default ViewportDepthNode;

const depthPixelBase = nodeProxy( ViewportDepthNode, ViewportDepthNode.DEPTH_PIXEL );

export const depth = nodeImmutable( ViewportDepthNode, ViewportDepthNode.DEPTH );
export const depthTexture = nodeProxy( ViewportDepthNode, ViewportDepthNode.DEPTH_TEXTURE );
export const depthPixel = nodeImmutable( ViewportDepthNode, ViewportDepthNode.DEPTH_PIXEL );

depthPixel.assign = ( value ) => depthPixelBase( value );

addNodeClass( 'ViewportDepthNode', ViewportDepthNode );
43 changes: 40 additions & 3 deletions examples/jsm/nodes/materials/NodeMaterial.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import { float, vec3, vec4 } from '../shadernode/ShaderNode.js';
import AONode from '../lighting/AONode.js';
import { lightingContext } from '../lighting/LightingContextNode.js';
import EnvironmentNode from '../lighting/EnvironmentNode.js';
import { depthPixel } from '../display/ViewportDepthNode.js';
import { cameraLogDepth } from '../accessors/CameraNode.js';

const NodeMaterials = new Map();

Expand Down Expand Up @@ -50,6 +52,8 @@ class NodeMaterial extends ShaderMaterial {

this.positionNode = null;

this.depthNode = null;

this.outputNode = null;

this.fragmentNode = null;
Expand All @@ -75,7 +79,7 @@ class NodeMaterial extends ShaderMaterial {

builder.addStack();

builder.stack.outputNode = this.setupPosition( builder );
builder.stack.outputNode = this.vertexNode || this.setupPosition( builder );

builder.addFlow( 'vertex', builder.removeStack() );

Expand All @@ -87,6 +91,8 @@ class NodeMaterial extends ShaderMaterial {

if ( this.fragmentNode === null ) {

if ( this.depthWrite === true ) this.setupDepth( builder );

if ( this.normals === true ) this.setupNormal( builder );

this.setupDiffuseColor( builder );
Expand Down Expand Up @@ -116,13 +122,39 @@ class NodeMaterial extends ShaderMaterial {

}

setupDepth( builder ) {

const { renderer } = builder;

// Depth

let depthNode = this.depthNode;

if ( renderer.logarithmicDepthBuffer === true ) {

const fragDepth = modelViewProjection().w.add( 1 );

depthNode = fragDepth.log2().mul( cameraLogDepth ).mul( 0.5 );

}

if ( depthNode !== null ) {

depthPixel.assign( depthNode ).append();

}

}

setupPosition( builder ) {

const object = builder.object;
const { object } = builder;
const geometry = object.geometry;

builder.addStack();

// Vertex

if ( geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color ) {

morph( object ).append();
Expand All @@ -147,9 +179,12 @@ class NodeMaterial extends ShaderMaterial {

}

const mvp = modelViewProjection();

builder.context.vertex = builder.removeStack();
builder.context.mvp = mvp;

return this.vertexNode || modelViewProjection();
return mvp;

}

Expand Down Expand Up @@ -460,6 +495,8 @@ class NodeMaterial extends ShaderMaterial {

this.positionNode = source.positionNode;

this.depthNode = source.depthNode;

this.outputNode = source.outputNode;

this.fragmentNode = source.fragmentNode;
Expand Down
10 changes: 9 additions & 1 deletion examples/jsm/renderers/common/Renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,16 @@ const _vector3 = new Vector3();

class Renderer {

constructor( backend ) {
constructor( backend, parameters = {} ) {

this.isRenderer = true;

//

const {
logarithmicDepthBuffer = false,
} = parameters;

// public

this.domElement = backend.getDomElement();
Expand All @@ -37,6 +43,8 @@ class Renderer {
this.autoClearDepth = true;
this.autoClearStencil = true;

this.logarithmicDepthBuffer = logarithmicDepthBuffer;

this.outputColorSpace = SRGBColorSpace;

this.toneMapping = NoToneMapping;
Expand Down
6 changes: 6 additions & 0 deletions examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,12 @@ ${ flowData.code }

}

getFragDepth() {

return 'gl_FragDepth';

}

isAvailable( name ) {

return supports[ name ] === true;
Expand Down
2 changes: 1 addition & 1 deletion examples/jsm/renderers/webgpu/WebGPURenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class WebGPURenderer extends Renderer {
const backend = new BackendClass( parameters );

//super( new Proxy( backend, debugHandler ) );
super( backend );
super( backend, parameters );

this.isWebGPURenderer = true;

Expand Down
Loading

0 comments on commit bb54066

Please sign in to comment.