在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. 006.LVM快照

    一 快照介绍 快照就是将当时的系统信息记录下来,就好像照相一样,未来若有任何资料变动了,则原始资料会被移动到快照区,没有被改动的区域则由快照区与档案系统共享. 二 快照原理 当建立快照区时,LVM会预 ...

  2. 无线网络实体图生成工具airgraph-ng

    无线网络实体图生成工具airgraph-ng   airgraph-ng是aircrack-ng套件提供的一个图表生成工具.该工具可以根据airodump工具生成的CSV文件绘制PNG格式的图.绘制的 ...

  3. luogu P4779 【模板】单源最短路径(标准版)

    线段树优化dij 哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈 我可能是个智障 // luogu-judger-enable-o2 #pragma GCC diagnostic error "-std= ...

  4. zoj 3460 二分+二分图匹配

    不错的思想 /* 大致题意: 用n个导弹发射塔攻击m个目标.每个发射架在某个时刻只能为 一颗导弹服务,发射一颗导弹需要准备t1的时间,一颗导弹从发 射到击中目标的时间与目标到发射架的距离有关.每颗导弹 ...

  5. 一个页面从输入 URL 到页面加载显示完成,这个过程中都发生了什么?

    分为4个步骤: 1)  当发送一个 URL 请求时,不管这个 URL 是 Web 页面的 URL 还是 Web 页面上每个资源的 URL,浏览器都会开启一个线程来处理这个请求,同时在远程 DNS 服务 ...

  6. 2010-2011 ACM-ICPC, NEERC, Moscow Subregional Contest Problem A. Alien Visit 计算几何

    Problem A. Alien Visit 题目连接: http://codeforces.com/gym/100714 Description Witness: "First, I sa ...

  7. MikroTik RouterOS安装到SATA硬盘

    其实这个问题再5.x以上的版本就已经不存在这个问题,基本现在的版本都支持SATA,如果不支持,估计用的是2.x版本的,那么只需要设置成混合模式(百度)即可.

  8. ARM DEBUGGER FOR NEARLY ONE DOLLAR

    http://hackaday.com/2014/01/23/arm-debugger-for-nearly-one-dollar/ Oh that title is so misleading. B ...

  9. Programming 2D Games 读书笔记(第五章)

      http://www.programming2dgames.com/chapter5.htm 示例一:Planet 真正示例的开始,首先是载入2张图片 1.Graphics添加了2个方法 load ...

  10. Matlab 7.1安装及打不开问题解决

    一.安装方法   1.解压[MATLAB.V7.1.Windows版本号].MATLAB.V7.1.R14.SP3.CD1.iso,双击setup进行安装,输入username,单位,找到crac ...