webgl中关于模板测试

在WebGL中,模板缓冲区(stencil buffer)是一个二维数组,用于记录像素是否被绘制过。当启用模板测试(stencil test)时,WebGL会比较模板缓冲区中的值和参考值(reference value),根据比较结果决定是否绘制像素。

是否开启默认测试

gl.enable(gl.STENCIL_TEST);
gl.disable(gl.STENCIL_TEST);

gl.stencilMask

gl.stencilMask()是WebGL中的一个方法,用于控制模板缓冲区的写入操作。
gl.stencilMask()方法用于设置可以写入模板缓冲区的位。它接受一个整数参数,该参数的二进制表示形式指定了哪些位可以被写入。例如,如果参数为 0xFF,那么所有位都可以被写入;如果参数为 0x00,那么所有位都不能被写入。

以下是一个示例,演示如何在绘制之前启用模板测试,设置参考值和模板缓冲区的写入掩码:

scss
Copy code
// 启用模板测试
gl.enable(gl.STENCIL_TEST);

// 设置参考值为 1
gl.stencilFunc(gl.EQUAL, 1, 0xFF);

// 设置模板缓冲区的写入掩码为 0xFF
gl.stencilMask(0xFF);

// 绘制三角形
gl.drawArrays(gl.TRIANGLES, 0, 3);
在上面的示例中,我们启用了模板测试,并将参考值设置为 1。我们还将模板缓冲区的写入掩码设置为 0xFF,以允许所有位都被写入。在执行绘制命令时,WebGL会比较模板缓冲区中的值和参考值,并根据比较结果决定是否绘制像素。

gl.stencilOp

gl.stencilOp()是WebGL中的一个方法,用于设置在模板测试期间如何更新模板缓冲区的值。
gl.stencilOp()方法接受三个参数,分别用于指定三种操作:

fail: 模板测试失败时采取的操作。
zfail: 模板测试通过但深度测试失败时采取的操作。
zpass: 模板测试和深度测试都通过时采取的操作。
每个参数都可以设置为以下预定义常量之一:

gl.KEEP: 保持当前模板缓冲区的值不变。
gl.ZERO: 将模板缓冲区的值设为0。
gl.REPLACE: 将模板缓冲区的值替换为参考值。
gl.INCREMENT: 将模板缓冲区的值加1。
gl.INCREMENT_WRAP: 将模板缓冲区的值加1,当溢出时重新从0开始。
gl.DECREMENT: 将模板缓冲区的值减1。
gl.DECREMENT_WRAP: 将模板缓冲区的值减1,当值变为负数时重新从最大值开始。
以下是一个示例,演示如何在模板测试期间设置模板缓冲区的操作:

// 启用模板测试gl.enable(gl.STENCIL_TEST);// 设置模板测试函数gl.stencilFunc(gl.EQUAL, 1, 0xFF);// 设置模板缓冲区的写入掩码为 0xFFgl.stencilMask(0xFF);// 设置模板缓冲区的操作gl.stencilOp(gl.KEEP, gl.KEEP, gl.INCREMENT);// 绘制三角形gl.drawArrays(gl.TRIANGLES, 0, 3);

在上面的示例中,我们启用了模板测试,并将模板测试函数设置为等于参考值为1。我们还将模板缓冲区的写入掩码设置为 0xFF,以允许所有位都被写入。
最后,我们将模板缓冲区的操作设置为保持当前值不变,当模板测试通过并深度测试失败时保持当前值不变,当模板测试通过并深度测试也通过时将当前值加1。
在执行绘制命令时,WebGL会执行上述操作,根据操作更新模板缓冲区的值。

gl.stencilFunc

gl.stencilFunc()是WebGL中的一个方法,用于设置模板测试(stencil test)期间的测试函数。
gl.stencilFunc()方法接受三个参数,分别用于指定测试函数、参考值和比较掩码:
func: 指定测试函数,可以设置为以下预定义常量之一:
gl.NEVER: 永远不通过测试。
gl.LESS: 如果模板值小于参考值,则通过测试。
gl.LEQUAL: 如果模板值小于等于参考值,则通过测试。
gl.EQUAL: 如果模板值等于参考值,则通过测试。
gl.GEQUAL: 如果模板值大于等于参考值,则通过测试。
gl.GREATER: 如果模板值大于参考值,则通过测试。
gl.NOTEQUAL: 如果模板值不等于参考值,则通过测试。
gl.ALWAYS: 总是通过测试。
ref: 指定参考值,范围为0-255。
mask: 指定比较掩码,用于限制参考值和模板值的位数,范围为0-255。
以下是一个示例,演示如何设置模板测试函数:

// 启用模板测试gl.enable(gl.STENCIL_TEST);// 设置模板测试函数gl.stencilFunc(gl.EQUAL, 1, 0xFF);// 绘制三角形gl.drawArrays(gl.TRIANGLES, 0, 3);

在上面的示例中,我们启用了模板测试,并将模板测试函数设置为等于参考值为1。在执行绘制命令时,WebGL会将模板缓冲区中的值与参考值进行比较,如果相等,则通过测试。如果测试通过,WebGL就会绘制三角形,否则就不会绘制。

unity中使用模板测试

在Unity的ShaderLab中,Stencil命令可以用于在渲染过程中设置模板缓冲区的值。这可以用于许多目的,例如创建遮罩效果或在渲染对象时只绘制模板缓冲区中特定位置的像素。以下是Stencil命令的基本语法:

Stencil {    Ref [referenceValue]    Comp [comparisonFunction]    Pass [passOperation]    Fail [failOperation]    ZFail [zFailOperation]}

其中,Ref指定模板缓冲区应该被设置为的值,Comp指定比较函数,用于确定当前像素的值是否应该写入模板缓冲区。如果比较函数返回true,Pass操作将被执行,否则将执行Fail操作。ZFail操作指定在通过测试但深度测试失败时执行的操作。

unity模板测试案例

这里是clipping mask,用于裁剪的模板

    Properties    {         [IntRange] _Ref("Ref", Range(0, 255)) = 0    }     SubShader    {            Stencil {            Ref [_Ref]            Comp Always            Pass Replace         }    }

下面是等待被裁剪的对象

    Properties    {        [IntRange] _Ref("Ref", Range(0, 255)) = 0    }    SubShader    {         Stencil {            Ref [_Ref]            Comp Equal        }    }      

这个案例中先设置clippmask Ref值=x,再设置Comp Always代表该像素模板值总是写入,Pass Replace 表示将参考值写入缓冲区
再设置待裁剪对象,Ref值=x,再设置Comp Equal,表示等于Ref值则通过模板测试