Skip to content

Commit

Permalink
hardware clippoing
Browse files Browse the repository at this point in the history
  • Loading branch information
aardgoose committed Jun 5, 2024
1 parent c870fa1 commit 7d01e14
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 5 deletions.
28 changes: 28 additions & 0 deletions examples/jsm/nodes/accessors/BuiltinNode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import Node, { addNodeClass } from '../core/Node.js';
import { nodeProxy } from '../shadernode/ShaderNode.js';

class BuiltinNode extends Node {

constructor( name ) {

super( 'float' );

this.name = name;

this.isBuiltNode = true;

}

generate( /* builder */ ) {

return this.name;

}

}

export default BuiltinNode;

export const builtin = nodeProxy( BuiltinNode );

addNodeClass( 'BuiltinhNode', BuiltinNode );
37 changes: 36 additions & 1 deletion examples/jsm/nodes/accessors/ClippingNode.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@

import Node from '../core/Node.js';
import { nodeObject } from '../shadernode/ShaderNode.js';
import { positionView } from './PositionNode.js';
import { positionLocal, positionView } from './PositionNode.js';
import { diffuseColor, property } from '../core/PropertyNode.js';
import { tslFn } from '../shadernode/ShaderNode.js';
import { loop } from '../utils/LoopNode.js';
import { smoothstep } from '../math/MathNode.js';
import { uniforms } from './UniformsNode.js';
import { modelWorldMatrix } from '../accessors/ModelNode.js';
import { builtin } from './BuiltinNode.js';

class ClippingNode extends Node {

Expand All @@ -32,6 +34,10 @@ class ClippingNode extends Node {

return this.setupAlphaToCoverage( clippingContext.planes, numClippingPlanes, numUnionClippingPlanes );

} else if ( this.scope === ClippingNode.HARDWARE ) {

return this.setupHardwareClipping( clippingContext.planes, numUnionClippingPlanes, builder );

} else {

return this.setupDefault( clippingContext.planes, numClippingPlanes, numUnionClippingPlanes );
Expand Down Expand Up @@ -133,13 +139,42 @@ class ClippingNode extends Node {

}

setupHardwareClipping( planes, numUnionClippingPlanes, builder ) {

return tslFn( () => {

const clippingPlanes = uniforms( planes );
let plane;

console.log( 'hwclipping');

const hw_clip_distances = builtin( builder.getClipDistance() );

const worldPosition = modelWorldMatrix.mul( positionLocal ).xyz.toVar();

for ( let i = 0; i < numUnionClippingPlanes; i ++ ) {

plane = clippingPlanes.element( i );

const distance = worldPosition.dot( plane.xyz ).add( plane.w );
hw_clip_distances.element( i ).assign( distance );

}

} )();

}

}

ClippingNode.ALPHA_TO_COVERAGE = 'alphaToCoverage';
ClippingNode.DEFAULT = 'default';
ClippingNode.HARDWARE = 'hardware';

export default ClippingNode;

export const clipping = () => nodeObject( new ClippingNode() );

export const clippingAlpha = () => nodeObject( new ClippingNode( ClippingNode.ALPHA_TO_COVERAGE ) );

export const hardwareClipping = () => nodeObject( new ClippingNode( ClippingNode.HARDWARE ) );
25 changes: 23 additions & 2 deletions examples/jsm/nodes/materials/NodeMaterial.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import EnvironmentNode from '../lighting/EnvironmentNode.js';
import IrradianceNode from '../lighting/IrradianceNode.js';
import { depthPixel } from '../display/ViewportDepthNode.js';
import { cameraLogDepth } from '../accessors/CameraNode.js';
import { clipping, clippingAlpha } from '../accessors/ClippingNode.js';
import { clipping, clippingAlpha, hardwareClipping } from '../accessors/ClippingNode.js';
import { faceDirection } from '../display/FrontFacingNode.js';

const NodeMaterials = new Map();
Expand All @@ -42,6 +42,7 @@ class NodeMaterial extends Material {
this.fog = true;
this.lights = true;
this.normals = true;
this.hardwareClipping = true;

this.lightsNode = null;
this.envNode = null;
Expand Down Expand Up @@ -146,7 +147,7 @@ class NodeMaterial extends Material {

setupClipping( builder ) {

if ( builder.clippingContext === null ) return null;
if ( builder.clippingContext === null || this.hardwareClipping === true ) return null;

const { globalClippingCount, localClippingCount } = builder.clippingContext;

Expand All @@ -171,6 +172,24 @@ class NodeMaterial extends Material {

}

setupHardwareClipping( builder ) {

if ( builder.clippingContext === null ) return null;

const { localClipIntersection, globalClippingCount } = builder.clippingContext;

if ( globalClippingCount && localClipIntersection && ! this.alphaToCoverage ) {

builder.enableHardwareClipping( globalClippingCount );
builder.stack.add( hardwareClipping() );

this.hardwareClipping = true;
}

return;

}

setupDepth( builder ) {

const { renderer } = builder;
Expand Down Expand Up @@ -244,6 +263,8 @@ class NodeMaterial extends Material {

}

this.setupHardwareClipping( builder );

const mvp = modelViewProjection();

builder.context.vertex = builder.removeStack();
Expand Down
30 changes: 29 additions & 1 deletion examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,12 @@ ${ flowData.code }

}

getClipDistance() {

return 'gl_ClipDistance';

}

isAvailable( name ) {

return supports[ name ] === true;
Expand All @@ -561,6 +567,26 @@ ${ flowData.code }

}

enableHardwareClipping( planeCount ) {

const renderer = this.renderer;

const gl = renderer.getContext();
const ext = gl.getExtension( 'WEBGL_clip_cull_distance' );

if ( ext && planeCount <= gl.getParameter( ext.MAX_CLIP_DISTANCES_WEBGL ) ) {

gl.enable( ext.CLIP_DISTANCE0_WEBGL + planeCount - 1 );
console.log( 'requested hardware clipping', planeCount, gl.getParameter( ext.MAX_CLIP_DISTANCES_WEBGL ) );

return true;

}

return false;

}

registerTransform( varyingName, attributeNode ) {

this.transforms.push( { varyingName, attributeNode } );
Expand Down Expand Up @@ -602,6 +628,8 @@ ${vars}
${ this.getSignature() }
${ true ? '#extension GL_ANGLE_clip_cull_distance : enable' : '' }
// precision
${ defaultPrecisions }
Expand Down Expand Up @@ -736,7 +764,7 @@ void main() {

this.vertexShader = this._getGLSLVertexCode( shadersData.vertex );
this.fragmentShader = this._getGLSLFragmentCode( shadersData.fragment );

//console.log( this.vertexShader );
} else {

this.computeShader = this._getGLSLVertexCode( shadersData.compute );
Expand Down
20 changes: 20 additions & 0 deletions examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -594,12 +594,31 @@ ${ flowData.code }

}

getClipDistance() {

return 'hw_clip_distances';

}

isFlipY() {

return false;

}

enableHardwareClipping( planeCount ) {

if ( planeCount <= 8 && this.renderer.backend.hasFeature( 'clip-distances' ) ) {

this.getBuiltin( 'clip_distances', 'hw_clip_distances', `array<f32, ${ planeCount } >`, 'vertex' );
return true;

}

return false;

}

getBuiltins( shaderStage ) {

const snippets = [];
Expand Down Expand Up @@ -975,6 +994,7 @@ ${ flowData.code }
this.vertexShader = this._getWGSLVertexCode( shadersData.vertex );
this.fragmentShader = this._getWGSLFragmentCode( shadersData.fragment );

console.log( this.vertexShader );
} else {

this.computeShader = this._getWGSLComputeCode( shadersData.compute, ( this.object.workgroupSize || [ 64 ] ).join( ', ' ) );
Expand Down
2 changes: 1 addition & 1 deletion examples/webgpu_clipping.html
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@

// Renderer

renderer = new WebGPURenderer( { antialias: true } );
renderer = new WebGPURenderer( { antialias: true, forceWebGL: true } );
renderer.shadowMap.enabled = true;
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
Expand Down

0 comments on commit 7d01e14

Please sign in to comment.