【六十五,高级OpenGL-02模板测试】

2020-05-25  本文已影响0人  Woodlouse

模板测试

片段着色器处理完之后,模板测试就开始执行了,它能丢弃一些片段,被保留下来的片段会进入到深度测试,深度测试会丢弃更多的片段。

模板测试中的模板值通常是八位的,因此每个片段/像素共有256种不同的模板值,这样我们能将这些模板值设置为我们链接的,然后在模板测试时根据这个模板值,我们就可以决定丢弃或保留它了。

使用模板缓冲,要遵守的原则:

开启模板缓冲写入
glEnable(GL_STENCIL_TEST);

清空模板缓冲
glClear(GL_COLOR_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

设置位遮罩(Bitmask)

glStencilMask(0xFF);
glStencilMask(0x00);

模板函数

模板函数有两个作用:
1,何时模板测试通过或者测试失败;
2,在测试通过/失败时如何操作模板值;

分别对应两个函数:
1,glStencilFunc(GLenum func, GLint ref, GLuint Mask);
func: : 模板测试函数
ref: : 指定模板测试的引用值,模板缓冲的内容和这个值比较;
Mask:* : 指定一个遮罩,在模板测试对比引用值和储存的模板值前,对它们进行按位与(and)操作,初始设置为1。

2,glStencilOp(GLenum sfail, GLenum dpfail, GLenum dppass);
sfail:模板测试失败将采取的动作;
dpfail:模板测试通过,深度测试失败将采取的动作;
*dppass:模板测试,深度测试都通过将采取的动作;
可以采取的动作:

操作 描述
GL_KEEP 保持现在的模板值
GL_ZERO 将模板值设置为0
GL_REPLACE 将模板值设置为glStencilFunc中设置的ref值
GL_INCR 如果模板值不是最大值则+1
GL_INCR_WRAP 与GL_INCR一样将模板值+1,如已是最大则设置为0
GL_DECR 将模板值减1
GL_DRCR_WRAP 与GL_DECR一样将模板值减1,如已是最小,则设置为0
GL_INVERT Bitwise inverts the current stencil buffer value.

应用

模板测试特别有用的一个功能是:物体轮廓(Object Outlining)
物体轮廓就像它的名字所描述的那样,它能够给每个(或一个)物体创建一个有颜色的边。在策略游戏中当你打算选择一个单位的时候它特别有用。给物体加上轮廓的步骤如下:

1,在绘制物体前,把模板方程设置为GL_ALWAYS,用1更新物体将被渲染的片段。
2,渲染物体,写入模板缓冲。
3,关闭模板写入和深度测试。
4,每个物体放大一点点。
5,使用一个不同的片段着色器用来输出一个纯颜色。
6,再次绘制物体,但只是当它们的片段的模板值不为1时才进行。
7,开启模板写入和深度测试。

最终实现效果图如下:


物体轮廓

模板测试-物体轮廓代码

上一篇 下一篇

猜你喜欢

热点阅读