WebGL中有没有一种方法可以快速反转模具缓冲区?

WebGL中有没有一种方法可以快速反转模具缓冲区?,webgl,stencil-buffer,Webgl,Stencil Buffer,我正在使用WebGL 1.0。我在模具缓冲区画了一个圆圈,现在我想在不清除它的情况下多次使用这个模具缓冲区。第一次使用时,我使用以下工具启用模具测试: gl.enable(GL.STENCIL_TEST); 然后,我对颜色缓冲区执行绘图。在这之后,在以后的某个日期,我想再次绘制,但这次我想剪辑到模具缓冲区中的相反位置。我知道我可以再次绘制模具缓冲区,但由于我没有使用gl.stencilOp(gl.ZERO,gl.ZERO,gl.ZERO),模具缓冲区应该仍然存在,但其中包含原始值 我的问题是-

我正在使用WebGL 1.0。我在模具缓冲区画了一个圆圈,现在我想在不清除它的情况下多次使用这个模具缓冲区。第一次使用时,我使用以下工具启用模具测试:

gl.enable(GL.STENCIL_TEST);
然后,我对颜色缓冲区执行绘图。在这之后,在以后的某个日期,我想再次绘制,但这次我想剪辑到模具缓冲区中的相反位置。我知道我可以再次绘制模具缓冲区,但由于我没有使用
gl.stencilOp(gl.ZERO,gl.ZERO,gl.ZERO)
,模具缓冲区应该仍然存在,但其中包含原始值


我的问题是-是否有一种快速的WebGL方法来反转此模具缓冲区,或者我必须使用
GL.invert
的模具操作再次执行绘图操作?

假设您将模具清除为一个值,并使用不同的值绘制模具,则可以使用
GL.stencilFunc(GL.EQUAL,value,0xFFFF)
到 仅在模具与
值匹配的位置绘制

例如:

模具下方的代码,圆圈为1,正方形为2。然后画3个场景。仅当模具为0时具有立方体的场景,仅当模具为1时具有球体的场景,以及仅当模具为2时具有穿过圆环的场景

const m4=twgl.m4;
常数v3=twgl.v3;
const gl=document.querySelector(“canvas”).getContext(“webgl”{
模具:是的,
});
常量程序信息=生成程序信息(gl);
const renderStencil1=setupSceneStencil1();
const renderStencil2=setupSceneStencil2();
const renderScene1=setupScene1();
const renderScene2=setupScene2();
const renderScene3=setupScene3();
函数渲染(时间){
时间*=0.001;
twgl.resizeCanvasToDisplaySize(总图画布);
总帐禁用(总帐模板测试);
gl.clearStencil(0);
总图视口(0,0,总图画布宽度,总图画布高度);
gl.clearColor(1,1,0,1);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
//在模具中画1
总帐启用(总帐模板测试);
gl.stencilFunc(gl.ALWAYS,1,0xFF);
如果(时间/5%2 | 0){
//这将以2s结束,其中正方形与圆形重叠
总帐模板(总帐增加,总帐增加,总帐增加);
}否则{
//这将在绘制正方形的位置结束2s
总图模板(总图替换,总图替换,总图替换);
}
gl.禁用(gl.深度测试);
renderStencil1(时间);
//将2s拉入模具
gl.stencilFunc(gl.ALWAYS,2,0xFF);
gl.禁用(gl.深度测试);
renderStencil2(时间);
//在有0的地方画
总帐启用(总帐深度测试);
gl.stencilFunc(gl.EQUAL,0,0xFF);
总帐模板(总帐保留,总帐保留,总帐保留);
渲染场景1(时间);
//在有1的地方画
gl.stencilFunc(gl.EQUAL,1,0xFF);
渲染场景2(时间);
//在有2的地方画
gl.stencilFunc(gl.EQUAL,2,0xFF);
渲染场景3(时间);
请求动画帧(渲染);
}
请求动画帧(渲染);
函数setupSceneStencil1(){
const bufferInfo=twgl.primitives.createDiscBufferInfo(gl,1,48);
常量颜色=[1,0,0,1];
常量tex=twgl.createTexture(gl{
src:[255、255、255、255],
});
函数渲染(时间、视图投影){
总账使用程序(programInfo.program);
twgl.setBuffersAndAttributes(总帐、程序信息、缓冲信息);
常数s=1+(数学sin(时间)*.5+.5)*10;
设mat=m4.复制(视图投影);
mat=m4。翻译(mat[
数学单(时间*1.7)*3,
0,
0,
]);
mat=m4.刻度(mat[s,s,s]);
mat=m4.rotateX(Math.PI*.5);
twgl.设置制服(程序信息{
u_扩散:tex,
u_diffuseMult:颜色,
世界观投影:mat,
});
twgl.drawBufferInfo(总账,bufferInfo);
}
返回场景(渲染);
}
函数setupSceneStencil2(){
const bufferInfo=twgl.primitives.createPlaneBufferInfo(gl,2,2);
常量颜色=[0,0,1,1];
常量tex=twgl.createTexture(gl{
src:[255、255、255、255],
});
函数渲染(时间、视图投影){
总账使用程序(programInfo.program);
twgl.setBuffersAndAttributes(总帐、程序信息、缓冲信息);
常数s=1+(数学常数(时间*2.3)*.5+.5)*5;
设mat=m4.复制(视图投影);
mat=m4。翻译(mat[
数学cos(时间*1.3)*3,
0,
0,
]);
mat=m4.刻度(mat[s,s,s]);
mat=m4.rotateZ(mat,-时间);
mat=m4.rotateX(Math.PI*.5);
twgl.设置制服(程序信息{
u_扩散:tex,
u_diffuseMult:颜色,
世界观投影:mat,
});
twgl.drawBufferInfo(总账,bufferInfo);
}
返回场景(渲染);
}
函数setupScene1(){
const bufferInfo=twgl.primitives.createCubeBufferInfo(gl,4);
const color=makeColor();
函数渲染(时间、视图投影、tex){
总账使用程序(programInfo.program);
twgl.setBuffersAndAttributes(总帐、程序信息、缓冲信息);
常数numCubes=20;
for(设i=0;i