Skip to content

Commit 0229ebd

Browse files
committed
WebGPURenderer: Support stencil options.
1 parent 29ec65b commit 0229ebd

File tree

2 files changed

+137
-5
lines changed

2 files changed

+137
-5
lines changed

examples/jsm/renderers/webgpu/WebGPURenderPipelines.js

Lines changed: 126 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
import { GPUPrimitiveTopology, GPUIndexFormat, GPUTextureFormat, GPUCompareFunction, GPUFrontFace, GPUCullMode, GPUVertexFormat, GPUBlendFactor, GPUBlendOperation, BlendColorFactor, OneMinusBlendColorFactor, GPUColorWriteFlags } from './constants.js';
1+
import { GPUPrimitiveTopology, GPUIndexFormat, GPUTextureFormat, GPUCompareFunction, GPUFrontFace, GPUCullMode, GPUVertexFormat, GPUBlendFactor, GPUBlendOperation, BlendColorFactor, OneMinusBlendColorFactor, GPUColorWriteFlags, GPUStencilOperation } from './constants.js';
22
import {
33
FrontSide, BackSide, DoubleSide,
44
NeverDepth, AlwaysDepth, LessDepth, LessEqualDepth, EqualDepth, GreaterEqualDepth, GreaterDepth, NotEqualDepth,
5+
NeverStencilFunc, AlwaysStencilFunc, LessStencilFunc, LessEqualStencilFunc, EqualStencilFunc, GreaterEqualStencilFunc, GreaterStencilFunc, NotEqualStencilFunc,
6+
KeepStencilOp, ZeroStencilOp, ReplaceStencilOp, InvertStencilOp, IncrementStencilOp, DecrementStencilOp, IncrementWrapStencilOp, DecrementWrapStencilOp,
57
NoBlending, NormalBlending, AdditiveBlending, SubtractiveBlending, MultiplyBlending, CustomBlending,
68
AddEquation, SubtractEquation, ReverseSubtractEquation, MinEquation, MaxEquation,
79
ZeroFactor, OneFactor, SrcColorFactor, OneMinusSrcColorFactor, SrcAlphaFactor, OneMinusSrcAlphaFactor, DstAlphaFactor, OneMinusDstAlphaFactor, DstColorFactor, OneMinusDstColorFactor, SrcAlphaSaturateFactor
@@ -122,6 +124,8 @@ class WebGPURenderPipelines {
122124

123125
}
124126

127+
//
128+
125129
const geometry = object.geometry;
126130
let indexFormat;
127131

@@ -133,8 +137,10 @@ class WebGPURenderPipelines {
133137

134138
}
135139

136-
let alphaBlend;
137-
let colorBlend;
140+
//
141+
142+
let alphaBlend = {};
143+
let colorBlend = {};
138144

139145
if ( material.transparent === true && material.blending !== NoBlending ) {
140146

@@ -143,12 +149,27 @@ class WebGPURenderPipelines {
143149

144150
}
145151

152+
//
153+
154+
let stencilFront = {};
155+
156+
if ( material.stencilWrite === true ) {
157+
158+
stencilFront = {
159+
compare: this._getStencilCompare( material ),
160+
failOp: this._getStencilOperation( material.stencilFail ),
161+
depthFailOp: this._getStencilOperation( material.stencilZFail ),
162+
passOp: this._getStencilOperation( material.stencilZPass )
163+
};
164+
165+
}
166+
146167
// pipeline
147168

148169
const primitiveTopology = this._getPrimitiveTopology( object );
149170
const rasterizationState = this._getRasterizationStateDescriptor( material );
150-
const depthCompare = this._getDepthCompare( material );
151171
const colorWriteMask = this._getColorWriteMask( material );
172+
const depthCompare = this._getDepthCompare( material );
152173

153174
pipeline = device.createRenderPipeline( {
154175
layout: layout,
@@ -163,9 +184,13 @@ class WebGPURenderPipelines {
163184
writeMask: colorWriteMask
164185
} ],
165186
depthStencilState: {
187+
format: GPUTextureFormat.Depth24PlusStencil8,
166188
depthWriteEnabled: material.depthWrite,
167189
depthCompare: depthCompare,
168-
format: GPUTextureFormat.Depth24PlusStencil8,
190+
stencilFront: stencilFront,
191+
stencilBack: {}, // three.js does not provide an API to configure the back function (gl.stencilFuncSeparate() was never used)
192+
stencilReadMask: material.stencilFuncMask,
193+
stencilWriteMask: material.stencilWriteMask
169194
},
170195
vertexState: {
171196
indexFormat: indexFormat,
@@ -563,6 +588,102 @@ class WebGPURenderPipelines {
563588

564589
}
565590

591+
_getStencilCompare( material ) {
592+
593+
let stencilCompare;
594+
595+
const stencilFunc = material.stencilFunc;
596+
597+
switch ( stencilFunc ) {
598+
599+
case NeverStencilFunc:
600+
stencilCompare = GPUCompareFunction.Never;
601+
break;
602+
603+
case AlwaysStencilFunc:
604+
stencilCompare = GPUCompareFunction.Always;
605+
break;
606+
607+
case LessStencilFunc:
608+
stencilCompare = GPUCompareFunction.Less;
609+
break;
610+
611+
case LessEqualStencilFunc:
612+
stencilCompare = GPUCompareFunction.LessEqual;
613+
break;
614+
615+
case EqualStencilFunc:
616+
stencilCompare = GPUCompareFunction.Equal;
617+
break;
618+
619+
case GreaterEqualStencilFunc:
620+
stencilCompare = GPUCompareFunction.GreaterEqual;
621+
break;
622+
623+
case GreaterStencilFunc:
624+
stencilCompare = GPUCompareFunction.Greater;
625+
break;
626+
627+
case NotEqualStencilFunc:
628+
stencilCompare = GPUCompareFunction.NotEqual;
629+
break;
630+
631+
default:
632+
console.error( 'THREE.WebGPURenderer: Invalid stencil function.', stencilFunc );
633+
634+
}
635+
636+
return stencilCompare;
637+
638+
}
639+
640+
_getStencilOperation( op ) {
641+
642+
let stencilOperation;
643+
644+
switch ( op ) {
645+
646+
case KeepStencilOp:
647+
stencilOperation = GPUStencilOperation.Keep;
648+
break;
649+
650+
case ZeroStencilOp:
651+
stencilOperation = GPUStencilOperation.Zero;
652+
break;
653+
654+
case ReplaceStencilOp:
655+
stencilOperation = GPUStencilOperation.Replace;
656+
break;
657+
658+
case InvertStencilOp:
659+
stencilOperation = GPUStencilOperation.Invert;
660+
break;
661+
662+
case IncrementStencilOp:
663+
stencilOperation = GPUStencilOperation.IncrementClamp;
664+
break;
665+
666+
case DecrementStencilOp:
667+
stencilOperation = GPUStencilOperation.DecrementClamp;
668+
break;
669+
670+
case IncrementWrapStencilOp:
671+
stencilOperation = GPUStencilOperation.IncrementWrap;
672+
break;
673+
674+
case DecrementWrapStencilOp:
675+
stencilOperation = GPUStencilOperation.DecrementWrap;
676+
break;
677+
678+
default:
679+
console.error( 'THREE.WebGPURenderer: Invalid stencil operation.', stencilOperation );
680+
681+
}
682+
683+
return stencilOperation;
684+
685+
}
686+
566687
_getVertexFormat( type ) {
567688

568689
// @TODO: This code is GLSL specific. We need to update when we switch to WGSL.

examples/jsm/renderers/webgpu/constants.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,17 @@ export const GPUColorWriteFlags = {
209209
All: 0xF
210210
};
211211

212+
export const GPUStencilOperation = {
213+
Keep: 'keep',
214+
Zero: 'zero',
215+
Replace: 'replace',
216+
Invert: 'invert',
217+
IncrementClamp: 'increment-clamp',
218+
DecrementClamp: 'decrement-clamp',
219+
IncrementWrap: 'increment-wrap',
220+
DecrementWrap: 'decrement-wrap'
221+
};
222+
212223
// @TODO Move to src/constants.js
213224

214225
export const BlendColorFactor = 211;

0 commit comments

Comments
 (0)