在OpenGL和D3D11的管线中,像素shader之后的操作就是深度模版测试,深度模版测试是以sample为单位进行的,就是一个像素上可以有多个采样点,每个采样点都有深度信息。深度模版测试对每个采样点都要进行一次,如果是msaa,最后要对每次采样的像素结果进行resolve,得到最终的结果。在下面的链接中有msaa的介绍。

http://www.cnblogs.com/mikewolf2002/archive/2012/11/22/2783235.html

    深度模版测试的流程如下图:

在OpenGL中使用深度模版测试,首先要enable深度测试和模版测试,可以通过下面两个函数实现:

glEnable(GL_DEPTH_TEST);

glEnable(GL_STENCIL_TEST);

下面的函数初始化深度缓冲和模版缓冲值。

glClearStencil(0); // 初始为0

glClearDepth(1.0f); //初始为1.0

glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); //该函数会复位深度和模版值,分别为1.0和0,就是每个像素对应的深度值初始为1.0,对应的模版值为0。

      在模板测试的过程中,可以先使用一个比较用掩码(comparison mask)与模板缓冲区中的值进行位与运算,再与参考值进行比较,从而实现对模板缓冲区中的值的某一位上的置位状态的判断。这样,模板缓冲区中的值不仅可以作为一个独立的整体使用,还可以作为一个比特集合使用。

     在OpenGL中,可以通过调用glStencilFunc()函数来设定比较条件(comparison function)、参考值(reference value)以及比较用掩码(comparison mask)。

glStencilFunc(GL_EQUAL, // 比较条件

                   0x1, // 参考值

                   0xff); // 比较用掩码

比较条件可以设置为以下的值

     GL_NEVER 从来不能通过

GL_ALWAYS 永远可以通过(默认值)

GL_LESS 小于参考值可以通过

GL_LEQUAL 小于或者等于可以通过

GL_EQUAL 等于通过

GL_GEQUAL 大于等于通过

GL_GREATER 大于通过

GL_NOTEQUAL 不等于通过

      除了比较参考值与模板值之外,我们还需要使用一些操作来更新模板缓冲区中的值,这些操作被称为模板操作(stencil operation)。模板缓冲区的更新与模板测试的结果以及深度测试的结果有着密切的联系。如上面的流程图所示:模板操作可以为下述三种情况,分别指定相应的更新方法。

1. 模板测试失败。

2. 模板测试通过,但深度测试失败。

3. 模板测试通过,且深度测试通过。

    当上述情况中的一个发生时,就会执行预先设定的更新操作。在OpenGL中,可以使用glStencilOp()函数来为上述三种情况分别设置更新方法。例如,

glStencilOp(GL_KEEP, // 第一种情况更新方法

GL_DECR, // 第二种情况的更新方法

GL_INCR); // 第三种情况的更新方法

可是设置的更新方法如下:

GL_KEEP    保持当前的模板值不变

GL_ZERO   将当前的模板值设为0

GL_REPLAC   将当前的模板值设置为参考值

GL_INCR    在当前的模板值上加1

GL_DECR    在当前的模板值上减1

GL_INVERT   对当前的模板值进行按位取反操作

     我们可以通过写入掩码(write mask)来更新模板值指定比特位上的置位状态。OpenGL中,提供了glStencilMask()函数来设置写入掩码。例如,glStencilMask(0xff);还可以通过函数glDepthMask(GL_FALSE)来打开或关闭深度写功能,GL_TRUE为打开,GL_FALSE为禁止写。在新版本的OpenGL中,允许为多边形的正面和背面使用不同的模板测试条件和模板值改变方式,于是就有了glStencilFuncSeparate函数和glStencilOpSeparate函数。这两个函数分别与glStencilFunc和glStencilOp类似,只在最前面多了一个参数face,用于指定当前设置的是哪个面。可以选择GL_FRONT, GL_BACK, GL_FRONT_AND_BACK。

在D3D11中,通过深度模版状态来设置深度模版测试各种条件。

// 设置深度模版状态描述.
depthStencilDesc.DepthEnable = true;
depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;//D3D11_DEPTH_WRITE_MASK_ZERO禁止写深度缓冲
depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;

depthStencilDesc.StencilEnable = true;
depthStencilDesc.StencilReadMask = 0xFF; //和OpenGL中函数glStencilFunc的第三个参数意思一样
depthStencilDesc.StencilWriteMask = 0xFF; //和glStencilMask意思一样

// 对于front face 像素使用的模版操作操作,三种状况下的stencil操作
depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

// 对于back face像素使用的模版操作模式.
depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

// 创建深度模版状态,使其生效
result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState);
if(FAILED(result))
    {
    return false;

    }

// 设置深度模版状态.
m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1);

OpenGL和D3D11中的深度模版测试的更多相关文章

  1. OpenGL中的深度、深度缓存、深度测试及保存成图片

    1.深度 所谓深度,就是在openGL坐标系中,像素点Z坐标距离摄像机的距离.摄像机可能放在坐标系的任何位置,那么,就不能简单的说Z数值越大或越小,就是越靠近摄像机. 2.深度缓冲区 深度缓冲区原理就 ...

  2. Unity3D Shader Stencil模版测试学习

    官方文档地址: https://docs.unity3d.com/Manual/SL-Stencil.html 参考博客: http://blog.csdn.net/onafioo/article/d ...

  3. ipa包兼容性大作战!WeTest iOS深度兼容测试全新升级

    2018年,移动端适配话题热闹无比,有iOS新版本新机型发布,全面屏.异形屏.曲面屏争相斗艳,从而产生了各类特殊的屏幕分辨率设备. 正是因为这些特殊分辨率,导致2018年手机设备频繁出现适配问题,如屏 ...

  4. <style scoped >中使用深度选择器影响子组件

    摘自:https://blog.csdn.net/zhouzuoluo/article/details/95593143 <style scoped >中使用深度选择器影响子组件 在< ...

  5. D3D11中的MSAA

    这两年我的工作都转到了D3D11,目前新出硬件几乎全部支持此标准,加上D3D11接口清晰,概念直观,等到windows7普及,想必未来都是D3D11的天下.最近时间较空,我陆续开始写些基础文章,希望对 ...

  6. 在mysql数据库中制作千万级测试表

    在mysql数据库中制作千万级测试表 前言: 最近准备深入的学一下mysql,包括各种引擎的特性.性能优化.分表分库等.为了方便测试性能.分表等工作,就需要先建立一张比较大的数据表.我这里准备先建一张 ...

  7. tornado中使用Mako模版

    tornado是一个优秀的python的开源web 框架,框架本身的性能确实很好,但是他自带的模版只能说是一般般.关于tornado的详细信息可以直接到管网参考. http://www.tornado ...

  8. Unity脚本在层级面板中的执行顺序测试3

    断断续续的写了3篇,以后有时间可以做成一个系列了 前面2篇测试了GameObject的顺序,以及Awake和OnEnable的时机: Unity脚本在层级面板中的执行顺序测试1 http://www. ...

  9. Unity脚本在层级面板中的执行顺序测试4-附加整理

    测试4为一些附加内容,后续的各种tips都加在此. 前几篇测试的链接: Unity脚本在层级面板中的执行顺序测试1 http://www.cnblogs.com/hont/p/4298110.html ...

随机推荐

  1. vue-awesome-swiper使用纪实

    最近做一个项目,需要用到轮播和全屏滑动功能,所以用到了vue-awesome-swiper插件,以下为个人记录下此插件的用法. 效果说明: 上面部分是个轮播图,自动开始轮播,轮播间隔为3000ms 推 ...

  2. 《编写可维护的javascript》读书笔记(中)——编程实践

    上篇读书笔记系列之:<编写可维护的javascript>读书笔记(上) 上篇说的是编程风格,记录的都是最重要的点,不讲废话,写的比较简洁,而本篇将加入一些实例,因为那样比较容易说明问题. ...

  3. SCTF2018-Event easiest web - phpmyadmin

    6月19日的SCTF的web送分题. 打开链接是一个phpmyadmin的登陆界面,尝试用默认账号:root  密码:root登陆 于是直接进去了,首先看下数据库,除了些初始化的库以外,abc这个库比 ...

  4. 1,EasyNetQ-链接到RabbitMQ

    一.链接到RabbitMQ 1,创建连接 注意不能有空格 var bus = RabbitHutch.CreateBus(“host=myServer;virtualHost=myVirtualHos ...

  5. 洛谷 P1135 奇怪的电梯

    题目描述 呵呵,有一天我做了一个梦,梦见了一种很奇怪的电梯.大楼的每一层楼都可以停电梯,而且第i层楼(1<=i<=N)上有一个数字Ki(0<=Ki<=N).电梯只有四个按钮:开 ...

  6. 快速沃尔什变换与k进制FWT

    这是一篇用来卖萌的文章QAQ 考虑以下三类卷积 \(C_k = \sum \limits_{i \;or\;j = k} A_i * B_j\) \(C_k = \sum \limits_{i\;an ...

  7. AIM Tech Round 3 (Div. 1) B. Recover the String 构造

    B. Recover the String 题目连接: http://www.codeforces.com/contest/708/problem/B Description For each str ...

  8. 【Hadoop】HDFS - 创建文件流程详解

    1.本文目的 通过解析客户端创建文件流程,认知hadoop的HDFS系统的一些功能和概念. 2.主要概念 2.1 NameNode(NN): HDFS系统核心组件,负责分布式文件系统的名字空间管理.I ...

  9. Delphi 的链式代码

    有了一系列的 Helper, Delphi 也可以使用链式代码了. //譬如要把 3.1415926 中的 141 提取为一个整数: var num: Integer; begin num := Pi ...

  10. Go内置库模块 flag

    import "flag" flag包实现了命令行参数的解析.每个参数认为一条记录,根据实际进行定义,到一个set集合.每条都有各自的状态参数. 在使用flag时正常流程: 1.  ...