Javascript WebGL中的模具缓冲区

Javascript WebGL中的模具缓冲区,javascript,canvas,webgl,stencil-buffer,Javascript,Canvas,Webgl,Stencil Buffer,我如何使用模具缓冲区为我最简单的程序? 我读过很多不同的主题,但我没有找到详细的指南。 我想在一个四面体的每一面都开一个洞 请一步一步向我解释使用模具缓冲区 要使用模具缓冲区,您必须在创建webgl上下文时首先请求它 const gl = someCanvasElement.getContext('webgl', {stencil: true}); 然后打开模具测试 gl.enable(gl.STENCIL_TEST); 设置测试,使其始终通过,并将参考值设置为1 gl.stenc

我如何使用模具缓冲区为我最简单的程序? 我读过很多不同的主题,但我没有找到详细的指南。 我想在一个四面体的每一面都开一个洞

请一步一步向我解释使用模具缓冲区


要使用模具缓冲区,您必须在创建webgl上下文时首先请求它

const gl = someCanvasElement.getContext('webgl', {stencil: true});
然后打开模具测试

  gl.enable(gl.STENCIL_TEST);
设置测试,使其始终通过,并将参考值设置为1

  gl.stencilFunc(
     gl.ALWAYS,    // the test
     1,            // reference value
     0xFF,         // mask
  );
并设置操作,以便在模板和深度测试都通过时将模板设置为参考值

  gl.stencilOp(
     gl.KEEP,     // what to do if the stencil test fails
     gl.KEEP,     // what to do if the depth test fails
     gl.REPLACE,  // what to do if both tests pass
  );
然后我们画第一个内三角形

... lots of setup for a single triangle ...

gl.drawArrays(...) or gl.drawElements(...)
然后我们更改测试,使其仅在模具为零时通过

  gl.stencilFunc(
     gl.EQUAL,     // the test
     0,            // reference value
     0xFF,         // mask
  );
  gl.stencilOp(
     gl.KEEP,     // what to do if the stencil test fails
     gl.KEEP,     // what to do if the depth test fails
     gl.KEEP,     // what to do if both tests pass
  );

现在我们可以画其他的东西(较大的三角形),它只会在模具缓冲区中有0的地方画,除了第一个三角形被画的地方

例如:

const m4=twgl.m4;
const gl=document.querySelector('canvas').getContext('webgl',{stencil:true});
常数vs=`
属性向量4位置;
一致mat4矩阵;
void main(){
gl_位置=矩阵*位置;
}
`;
常数fs=`
精密中泵浮子;
vec4颜色均匀;
void main(){
gl_FragColor=颜色;
}
`;
const program=twgl.createProgram(gl[vs,fs]);
const posLoc=gl.getAttriblLocation(程序“位置”);
常量matLoc=gl.getUniformLocation(程序“矩阵”);
const colorLoc=gl.getUniformLocation(程序“颜色”);
const buf=gl.createBuffer();
gl.bindBuffer(gl.ARRAY\u BUFFER,buf);
gl.bufferData(gl.ARRAY\u BUFFER,新Float32Array([
0, -1,
1,  1,
-1,  1,
])、总图、静态图);
gl.EnableVertexAttributeArray(posLoc);
gl.VertexAttribute指针(
posLoc,//属性位置
2,//2每个顶点的值
gl.FLOAT,//32位浮点值
false,//不规范化
0,//步长(0=基于类型和大小)
0,//偏移到缓冲区中
);
//将模具清除为0(默认值)
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
gl.useProgram(程序);
//打开模具
总帐启用(总帐模板测试);
//设置模具测试,使其始终通过
//以及对1的引用
gl.stencilFunc(
gl.ALWAYS,//测试
1,//参考值
0xFF,//掩码
);
//将其设置为替换为参考值(1)
gl.stencilOp(
gl.KEEP,//如果模具测试失败怎么办
gl.KEEP,//如果深度测试失败怎么办
gl.REPLACE,//如果两个测试都通过了怎么办
);
//画一个白色的小三角形
gl.uniform4fv(colorLoc[1,1,1,1]);//白色
gl.uniformMatrix4fv(matLoc,false,m4.缩放([0.2,0.2,1]);
总图数组(总图三角形,0,3);
//设置模具必须=0的测试
gl.stencilFunc(
gl.EQUAL,//测试
0,//参考值
0xFF,//掩码
);
//绘制时不要更改模具缓冲区
gl.stencilOp(
gl.KEEP,//如果模具测试失败怎么办
gl.KEEP,//如果深度测试失败怎么办
gl.KEEP,//如果两个测试都通过了怎么办
);
//画一个大的绿色三角形
gl.uniform4fv(colorLoc[0,1,0,1]);//绿色
gl.uniformMatrix4fv(matLoc,false,m4.缩放([0.9,-0.9,1]);
总图数组(总图三角形,0,3)
canvas{边框:1px纯黑;}

非常感谢!这是非常有价值的信息。感谢您的评论,我已经了解了如何使用模具缓冲区。