Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebGPURenderer: hardware clipping support. #1391

Merged
merged 10 commits into from
Dec 8, 2024
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: 36 additions & 36 deletions src-testing/changes.patch
Original file line number Diff line number Diff line change
Expand Up @@ -3675,7 +3675,7 @@ index b17e7080..e2b545b7 100644
if (map === undefined) return false;
}
diff --git a/src-testing/src/renderers/common/ClippingContext.ts b/src-testing/src/renderers/common/ClippingContext.ts
index 1488999a..2de7e35d 100644
index f7ac6960..5b8b4893 100644
--- a/src-testing/src/renderers/common/ClippingContext.ts
+++ b/src-testing/src/renderers/common/ClippingContext.ts
@@ -1,11 +1,33 @@
Expand Down Expand Up @@ -4880,7 +4880,7 @@ index 0486f793..5c8d620c 100644
}

diff --git a/src-testing/src/renderers/common/RenderObject.ts b/src-testing/src/renderers/common/RenderObject.ts
index bceef2c6..2acb1ac3 100644
index 4d179411..4e41a679 100644
--- a/src-testing/src/renderers/common/RenderObject.ts
+++ b/src-testing/src/renderers/common/RenderObject.ts
@@ -1,8 +1,27 @@
Expand Down Expand Up @@ -5000,7 +5000,7 @@ index bceef2c6..2acb1ac3 100644

return true;
}
@@ -119,7 +180,7 @@ export default class RenderObject {
@@ -123,7 +184,7 @@ export default class RenderObject {
}

getChainArray() {
Expand All @@ -5009,7 +5009,7 @@ index bceef2c6..2acb1ac3 100644
}

getAttributes() {
@@ -128,8 +189,8 @@ export default class RenderObject {
@@ -132,8 +193,8 @@ export default class RenderObject {
const nodeAttributes = this.getNodeBuilderState().nodeAttributes;
const geometry = this.geometry;

Expand All @@ -5020,7 +5020,7 @@ index bceef2c6..2acb1ac3 100644

for (const nodeAttribute of nodeAttributes) {
const attribute =
@@ -342,6 +403,6 @@ export default class RenderObject {
@@ -346,6 +407,6 @@ export default class RenderObject {
dispose() {
this.material.removeEventListener('dispose', this.onMaterialDispose);

Expand Down Expand Up @@ -7503,7 +7503,7 @@ index 3b16e861..99874f36 100644
const monitor = renderObject.getMonitor();

diff --git a/src-testing/src/renderers/webgl-fallback/WebGLBackend.ts b/src-testing/src/renderers/webgl-fallback/WebGLBackend.ts
index b9713fd2..e52f74d8 100644
index 7db9864a..bb852529 100644
--- a/src-testing/src/renderers/webgl-fallback/WebGLBackend.ts
+++ b/src-testing/src/renderers/webgl-fallback/WebGLBackend.ts
@@ -13,6 +13,7 @@ import { WebGLBufferRenderer } from './WebGLBufferRenderer.js';
Expand All @@ -7524,7 +7524,7 @@ index b9713fd2..e52f74d8 100644
}

diff --git a/src-testing/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.ts b/src-testing/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.ts
index b1e72064..40f26bf1 100644
index 2ac9e7c4..beef6e0e 100644
--- a/src-testing/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.ts
+++ b/src-testing/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.ts
@@ -1,4 +1,4 @@
Expand Down Expand Up @@ -7594,7 +7594,7 @@ index b1e72064..40f26bf1 100644
super(object, renderer, new GLSLNodeParser());

this.uniformGroups = {};
@@ -82,7 +122,7 @@ class GLSLNodeBuilder extends NodeBuilder {
@@ -83,7 +123,7 @@ class GLSLNodeBuilder extends NodeBuilder {
return texture.isVideoTexture === true && texture.colorSpace !== NoColorSpace;
}

Expand All @@ -7603,7 +7603,7 @@ index b1e72064..40f26bf1 100644
return glslMethods[method] || method;
}

@@ -90,7 +130,7 @@ class GLSLNodeBuilder extends NodeBuilder {
@@ -91,7 +131,7 @@ class GLSLNodeBuilder extends NodeBuilder {
return '';
}

Expand All @@ -7612,7 +7612,7 @@ index b1e72064..40f26bf1 100644
const layout = shaderNode.layout;
const flowData = this.flowShaderNode(shaderNode);

@@ -116,7 +156,7 @@ ${flowData.code}
@@ -117,7 +157,7 @@ ${flowData.code}
return code;
}

Expand All @@ -7621,7 +7621,7 @@ index b1e72064..40f26bf1 100644
const attribute = storageBufferNode.value;

if (attribute.pbo === undefined) {
@@ -180,7 +220,7 @@ ${flowData.code}
@@ -181,7 +221,7 @@ ${flowData.code}
}
}

Expand All @@ -7630,7 +7630,7 @@ index b1e72064..40f26bf1 100644
if (node.isNodeUniform && node.node.isTextureNode !== true && node.node.isBufferNode !== true) {
return shaderStage.charAt(0) + '_' + node.name;
}
@@ -188,7 +228,7 @@ ${flowData.code}
@@ -189,7 +229,7 @@ ${flowData.code}
return super.getPropertyName(node, shaderStage);
}

Expand All @@ -7639,7 +7639,7 @@ index b1e72064..40f26bf1 100644
const { node, indexNode } = storageArrayElementNode;
const attribute = node.value;

@@ -260,7 +300,13 @@ ${flowData.code}
@@ -261,7 +301,13 @@ ${flowData.code}
return propertyName;
}

Expand All @@ -7654,7 +7654,7 @@ index b1e72064..40f26bf1 100644
if (depthSnippet) {
return `texelFetch( ${textureProperty}, ivec3( ${uvIndexSnippet}, ${depthSnippet} ), ${levelSnippet} )`;
} else {
@@ -268,7 +314,7 @@ ${flowData.code}
@@ -269,7 +315,7 @@ ${flowData.code}
}
}

Expand All @@ -7663,7 +7663,7 @@ index b1e72064..40f26bf1 100644
if (texture.isDepthTexture) {
return `texture( ${textureProperty}, ${uvSnippet} ).x`;
} else {
@@ -278,24 +324,39 @@ ${flowData.code}
@@ -279,24 +325,39 @@ ${flowData.code}
}
}

Expand Down Expand Up @@ -7711,7 +7711,7 @@ index b1e72064..40f26bf1 100644
shaderStage = this.shaderStage,
) {
if (shaderStage === 'fragment') {
@@ -304,11 +365,12 @@ ${flowData.code}
@@ -305,11 +366,12 @@ ${flowData.code}
console.error(
`WebGPURenderer: THREE.DepthTexture.compareFunction() does not support ${shaderStage} shader.`,
);
Expand All @@ -7726,7 +7726,7 @@ index b1e72064..40f26bf1 100644

const vars = this.vars[shaderStage];

@@ -321,7 +383,7 @@ ${flowData.code}
@@ -322,7 +384,7 @@ ${flowData.code}
return snippets.join('\n\t');
}

Expand All @@ -7735,7 +7735,7 @@ index b1e72064..40f26bf1 100644
const uniforms = this.uniforms[shaderStage];

const bindingSnippets = [];
@@ -403,7 +465,7 @@ ${flowData.code}
@@ -404,7 +466,7 @@ ${flowData.code}
return output;
}

Expand All @@ -7744,7 +7744,7 @@ index b1e72064..40f26bf1 100644
let nodeType = super.getTypeFromAttribute(attribute);

if (/^[iu]/.test(nodeType) && attribute.gpuType !== IntType) {
@@ -421,7 +483,7 @@ ${flowData.code}
@@ -422,7 +484,7 @@ ${flowData.code}
return nodeType;
}

Expand All @@ -7753,7 +7753,7 @@ index b1e72064..40f26bf1 100644
let snippet = '';

if (shaderStage === 'vertex' || shaderStage === 'compute') {
@@ -437,8 +499,8 @@ ${flowData.code}
@@ -438,8 +500,8 @@ ${flowData.code}
return snippet;
}

Expand All @@ -7764,7 +7764,7 @@ index b1e72064..40f26bf1 100644
const members = struct.getMemberTypes();

for (let i = 0; i < members.length; i++) {
@@ -449,7 +511,7 @@ ${flowData.code}
@@ -450,7 +512,7 @@ ${flowData.code}
return snippets.join('\n');
}

Expand All @@ -7773,7 +7773,7 @@ index b1e72064..40f26bf1 100644
const snippets = [];
const structs = this.structs[shaderStage];

@@ -470,7 +532,7 @@ ${flowData.code}
@@ -471,7 +533,7 @@ ${flowData.code}
return snippets.join('\n\n');
}

Expand All @@ -7782,7 +7782,7 @@ index b1e72064..40f26bf1 100644
let snippet = '';

const varyings = this.varyings;
@@ -535,7 +597,7 @@ ${flowData.code}
@@ -540,7 +602,7 @@ ${flowData.code}
return 'gl_FragDepth';
}

Expand All @@ -7791,7 +7791,7 @@ index b1e72064..40f26bf1 100644
const map = this.extensions[shaderStage] || (this.extensions[shaderStage] = new Map());

if (map.has(name) === false) {
@@ -546,7 +608,7 @@ ${flowData.code}
@@ -551,7 +613,7 @@ ${flowData.code}
}
}

Expand All @@ -7800,17 +7800,17 @@ index b1e72064..40f26bf1 100644
const snippets = [];

if (shaderStage === 'vertex') {
@@ -569,7 +631,7 @@ ${flowData.code}
return snippets.join('\n');
@@ -578,7 +640,7 @@ ${flowData.code}
return 'gl_ClipDistance';
}

- isAvailable(name) {
+ isAvailable(name: string) {
let result = supports[name];

if (result === undefined) {
@@ -594,11 +656,11 @@ ${flowData.code}
return true;
@@ -621,11 +683,11 @@ ${flowData.code}
this.builtins['vertex'].push(`out float gl_ClipDistance[ ${planeCount} ]`);
}

- registerTransform(varyingName, attributeNode) {
Expand All @@ -7823,7 +7823,7 @@ index b1e72064..40f26bf1 100644
const transforms = this.transforms;

let snippet = '';
@@ -614,14 +676,14 @@ ${flowData.code}
@@ -641,14 +703,14 @@ ${flowData.code}
return snippet;
}

Expand All @@ -7840,7 +7840,7 @@ index b1e72064..40f26bf1 100644
return `#version 300 es

${this.getSignature()}
@@ -661,7 +723,7 @@ void main() {
@@ -688,7 +750,7 @@ void main() {
`;
}

Expand All @@ -7849,7 +7849,7 @@ index b1e72064..40f26bf1 100644
return `#version 300 es

${this.getSignature()}
@@ -693,19 +755,20 @@ void main() {
@@ -720,19 +782,20 @@ void main() {
}

buildCode() {
Expand All @@ -7874,7 +7874,7 @@ index b1e72064..40f26bf1 100644
const slotName = node.name;

if (slotName) {
@@ -731,28 +794,33 @@ void main() {
@@ -758,28 +821,33 @@ void main() {
}
}

Expand Down Expand Up @@ -7935,7 +7935,7 @@ index 36f987a9..8c774ec4 100644
}

diff --git a/src-testing/src/renderers/webgpu/nodes/WGSLNodeBuilder.ts b/src-testing/src/renderers/webgpu/nodes/WGSLNodeBuilder.ts
index 2b4d0266..f967399c 100644
index 615f446e..fa8d418a 100644
--- a/src-testing/src/renderers/webgpu/nodes/WGSLNodeBuilder.ts
+++ b/src-testing/src/renderers/webgpu/nodes/WGSLNodeBuilder.ts
@@ -10,7 +10,7 @@ import {
Expand Down Expand Up @@ -8100,7 +8100,7 @@ index 2b4d0266..f967399c 100644
const layout = shaderNode.layout;
const flowData = this.flowShaderNode(shaderNode);

@@ -689,8 +713,8 @@ ${flowData.code}
@@ -698,8 +722,8 @@ ${flowData.code}
return snippets.join('\n');
}

Expand All @@ -8111,7 +8111,7 @@ index 2b4d0266..f967399c 100644

if (shaderStage === 'compute') {
this.getBuiltin('global_invocation_id', 'id', 'vec3<u32>', 'attribute');
@@ -776,8 +800,8 @@ ${flowData.code}
@@ -785,8 +809,8 @@ ${flowData.code}
return `\n${snippets.join('\n')}\n`;
}

Expand All @@ -8122,7 +8122,7 @@ index 2b4d0266..f967399c 100644

if (shaderStage === 'vertex') {
this.getBuiltin('position', 'Vertex', 'vec4<f32>', 'vertex');
@@ -813,7 +837,7 @@ ${flowData.code}
@@ -822,7 +846,7 @@ ${flowData.code}
return shaderStage === 'vertex' ? this._getWGSLStruct('VaryingsStruct', '\t' + code) : code;
}

Expand Down
2 changes: 1 addition & 1 deletion three.js
Submodule three.js updated 38 files
+54 −95 build/three.cjs
+54 −95 build/three.module.js
+1 −1 build/three.module.min.js
+83 −108 build/three.webgpu.js
+1 −1 build/three.webgpu.min.js
+83 −108 build/three.webgpu.nodes.js
+1 −1 build/three.webgpu.nodes.min.js
+2 −0 docs/examples/en/exporters/GLTFExporter.html
+2 −0 docs/examples/zh/exporters/GLTFExporter.html
+2 −2 examples/jsm/csm/CSMShadowNode.js
+1 −1 examples/jsm/tsl/display/AfterImageNode.js
+1 −1 examples/jsm/tsl/display/BloomNode.js
+1 −1 examples/jsm/tsl/display/DenoiseNode.js
+1 −1 examples/jsm/tsl/display/DepthOfFieldNode.js
+1 −1 examples/jsm/tsl/display/FXAANode.js
+1 −1 examples/jsm/tsl/display/FilmNode.js
+5 −1 examples/jsm/tsl/display/GTAONode.js
+1 −1 examples/jsm/tsl/display/LensflareNode.js
+1 −1 examples/jsm/tsl/display/Lut3DNode.js
+2 −2 examples/jsm/tsl/display/PixelationPassNode.js
+1 −1 examples/jsm/tsl/display/SMAANode.js
+1 −1 examples/jsm/tsl/display/SSRNode.js
+1 −1 examples/jsm/tsl/display/SobelOperatorNode.js
+1 −1 examples/jsm/tsl/display/TransitionNode.js
+1 −1 manual/examples/resources/editor-settings.js
+26 −1 src/materials/nodes/NodeMaterial.js
+130 −122 src/math/ColorManagement.js
+5 −5 src/math/Vector2.js
+7 −7 src/math/Vector3.js
+11 −9 src/math/Vector4.js
+26 −0 src/nodes/accessors/BuiltinNode.js
+38 −15 src/nodes/accessors/ClippingNode.js
+6 −0 src/renderers/common/ClippingContext.js
+6 −0 src/renderers/common/RenderObject.js
+2 −2 src/renderers/webgl-fallback/WebGLBackend.js
+40 −7 src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js
+26 −1 src/renderers/webgl-fallback/utils/WebGLState.js
+17 −0 src/renderers/webgpu/nodes/WGSLNodeBuilder.js
2 changes: 2 additions & 0 deletions types/three/src/materials/nodes/NodeMaterial.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ declare class NodeMaterial extends Material {

fog: boolean;
lights: boolean;
hardwareClipping: boolean;

lightsNode: LightsNode | null;
envNode: Node | null;
Expand Down Expand Up @@ -72,6 +73,7 @@ declare class NodeMaterial extends Material {
build(builder: NodeBuilder): void;
setup(builder: NodeBuilder): void;
setupClipping(builder: NodeBuilder): ClippingNode | null;
setupHardwareClipping(builder: NodeBuilder): void;
setupDepth(builder: NodeBuilder): void;
setupPosition(builder: NodeBuilder): Node;
setupDiffuseColor(builder: NodeBuilder): void;
Expand Down
14 changes: 14 additions & 0 deletions types/three/src/nodes/accessors/BuiltinNode.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Node from "../core/Node.js";
import { ShaderNodeObject } from "../tsl/TSLCore.js";

declare class BuiltinNode extends Node {
name: string;

readonly isBuiltinNode: true;

constructor(name: string);
}

export default BuiltinNode;

export const builtin: (name: string) => ShaderNodeObject<BuiltinNode>;
6 changes: 6 additions & 0 deletions types/three/src/nodes/accessors/ClippingNode.d.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
import { Plane } from "../../math/Plane.js";
import Node from "../core/Node.js";
import NodeBuilder from "../core/NodeBuilder.js";
import { ShaderNodeObject } from "../tsl/TSLCore.js";

export type ClippingNodeScope = typeof ClippingNode.ALPHA_TO_COVERAGE | typeof ClippingNode.DEFAULT;

export default class ClippingNode extends Node {
scope: ClippingNodeScope;

hardwareClipping?: boolean;

constructor(scope?: ClippingNodeScope);

static ALPHA_TO_COVERAGE: "alphaToCoverage";
static DEFAULT: "default";
static HARDWARE: "hardware";
}

export const clipping: () => ShaderNodeObject<ClippingNode>;
export const clippingAlpha: () => ShaderNodeObject<ClippingNode>;
export const hardwareClipping: () => ShaderNodeObject<ClippingNode>;
1 change: 1 addition & 0 deletions types/three/src/renderers/common/ClippingContext.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@ declare class ClippingContext {
updateGlobal(scene: Scene, camera: Camera): void;
update(parentContext: ClippingContext, clippingGroup: ClippingGroup): void;
getGroupContext(clippingGroup: ClippingGroup): ClippingContext;
get unionClippingCount(): number;
}
export default ClippingContext;
1 change: 1 addition & 0 deletions types/three/src/renderers/common/RenderObject.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export default class RenderObject {
);
updateClipping(parent: ClippingContext): void;
get clippingNeedsUpdate(): boolean;
get hardwareClippingPlanes(): number;
getNodeBuilderState(): NodeBuilderState;
getMonitor(): NodeMaterialObserver;
getBindings(): BindGroup[];
Expand Down
2 changes: 1 addition & 1 deletion types/three/src/renderers/webgl/WebGLState.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ declare class WebGLState {
blendDstAlpha?: BlendingDstFactor,
premultiplyAlpha?: boolean,
): void;
setMaterial(material: Material, frontFaceCW: boolean): void;
setMaterial(material: Material, frontFaceCW: boolean, hardwareClippingPlanes: number): void;
setFlipSided(flipSided: boolean): void;
setCullFace(cullFace: CullFace): void;
setLineWidth(width: number): void;
Expand Down
Loading