最近做课题的时候需要计算一个 view(就是一次渲染得到的帧) 下的重叠像素个数(两个物体或更多的物体重叠)。

  • 最开始我的想法是渲染一个物体输出一张纹理,这样对比物体之间的纹理就知道重叠了。但是这样当物体很多的时候需要输出太多的纹理到CPU,太慢了,也很麻烦。
  • 后来和同学讨论了一下,觉得是不是可以使用一张纹理作为帧缓冲的输出,同时作为片段着色器的输入,这样可以每渲染一个像素点加1,最终大于1的位置表示重叠。但是后来这样试了,在片段着色器中采样这张纹理的时候,采样出来的值明显不对,没有随着渲染一个物体后再次采样会逐步积累增加。(感觉因为是同一张纹理,但是是输入和输出,在GPU中分配了两个存储位置,各自使用自己的,所以没有叠加,我瞎猜的……)
  • 后来查到仿佛可以使用累积缓冲,每次渲染的结果叠加在一起,但是需要加权,value = α*value + (1-α)*newvalue ,感觉不太好操作,放弃了。
  • 最后看了一下stencil,发现可以实现我需要的功能。虽然几个月前看过一次,但是当时没有太懂,这次算是理解了。

  

  现在再来回顾一下 Stencil 的用法:

  • glStencilMask(value) 位遮罩, value=0x00表示模板缓冲不可写入;value=0xFF表示可以写入。
  • void glStencilFunc(GLenum func, GLint ref, GLuint mask)  指定ref值与存储的模板值对比
  • void glStencilOp(GLenum sfail, GLenum dpfail, GLenum dppass) 指定模板值的写入策略

  

  流程代码

        glEnable(GL_DEPTH_TEST);
glEnable(GL_STENCIL_TEST);
glStencilMask(0xFF); //开启模板写入 (清空模板缓冲需要开启模板写入!!!)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // 我们现在使用模板缓冲
glStencilOp(GL_INCR, GL_INCR, GL_INCR);
glStencilMask(0x00); //关闭模板写入
this->DrawSkyBox(false);
this->DrawFloor(false);
glStencilFunc(GL_ALWAYS, , 0xFF);
glStencilMask(0xFF); //开启模板写入
this->DrawBuildings(false); // 先渲染building,shader中的编号保持一致,但是sky一定在前
glStencilMask(0x00); //关闭模板写入

  遇到的坑是清空模板缓冲前一定要开启模板写入!!!

  模板值读取:

    这个耽搁了很久,开始是附加模板纹理到帧缓冲中,然后从纹理中读取值,但是怎么都读出来不对……

    后来发现可以直接使用其API读取   glReadPixels 。

    使用此API读取时,其是直接面向当前帧缓冲获取模板值数据,故与模板生成方式无关,可以是默认屏幕的帧缓冲,也可以使自己生成的帧缓冲(可以是RBO模板缓冲、模板缓冲纹理、深度-模板缓冲纹理)。

float* WKS::Texture::GetStencilData(GLuint width, GLuint height) {
float* pixels = new float[width * height];
glReadPixels(, , width, height, GL_STENCIL_INDEX, GL_FLOAT, pixels);
return pixels;
}

  一定要记得在对应的帧缓冲中使用。

  

  

进一步使用 模板缓冲(stencil)的更多相关文章

  1. windows API下的模板缓冲(stencil buffer)

    在windows API搭建的OpenGL窗口中使用模板缓冲,需要在像素格式描述表中设置stencil buffer位宽为8,这样窗口会自动生成stencil buffer,然后可以在opengl环境 ...

  2. Shader 模板缓冲和模板测试

    http://blog.sina.com.cn/s/blog_6e159df70102xa67.html 模板缓冲的概念 Unity官方的Shader文档根本没有提到这个玩意,这个概念也是看到了UGU ...

  3. WebGL学习笔记(十五):模板缓冲

    可以用来干啥? 模板缓冲一般用来实现一些地面反射投影和类似镜子的特殊效果,如下: 开启模板缓冲 默认情况下,模板缓冲是关闭的,模板缓冲如果处于关闭状态,运行模板相关的代码不会报错,但是不会出现预期的效 ...

  4. webgl 模板缓冲

    先思考个问题, 想实现遮罩怎么办? <!doctype html> <html> <head> <meta charset="utf-8" ...

  5. Unity Shader之模板测试

    Unity Shader之模板测试 一沙一世界,一花一天堂 一.Stencil testing 渲染管线     当片段着色器处理完一个片段之后,模板测试(Stencil Test)会开始执行,和深度 ...

  6. DirectX11笔记(二)--Direct3D初始化1之基本概念

    原文:DirectX11笔记(二)--Direct3D初始化1之基本概念 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u010333737/art ...

  7. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十一章:模板测试

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十一章:模板测试 代码工程地址: https://github.co ...

  8. OpenGL ES 中的模板测试

    模板测试的主要功能是丢弃一部分片元,相对于深度检测来说,模板测试提出的片元数量相对较少.模板测试发生在剪裁测试之后,深度测试之前. 使用模板测试时很重要的代码提示: 1.glClear( GL_STE ...

  9. [UnityShader基础]05.模板测试

    参考链接: https://blog.csdn.net/u011047171/article/details/46928463 https://blog.csdn.net/JohnBlu/articl ...

随机推荐

  1. 防止sql注入的最好方式

    避免 SQL injection 攻击的传统方法之一是,把它作为一个输入合法性检查的问题来处理,只接受列在白名单中的字符,或者识别并避免那些列在黑名单中的恶意数据.白名单方法是一种非常有效方法,它可以 ...

  2. 一目了然卷积神经网络 - An Intuitive Explanation of Convolutional Neural Networks

    An Intuitive Explanation of Convolutional Neural Networks 原文地址:https://ujjwalkarn.me/2016/08/11/intu ...

  3. `MediaDevices.getUserMedia` `undefined` 的问题

    通过 MediaDevices.getUserMedia() 获取用户多媒体权限时,需要注意其只工作于以下三种环境: localhost 域 开启了 HTTPS 的域 使用 file:/// 协议打开 ...

  4. netcore 2.2 使用 AutoMapper 实现实体之间映射

    一.什么是AutoMapper? AutoMapper是一个简单的对象映射框架(OOM),将一个对象映射到另一个对象. 二.AutoMapper的好处 以前的时候我们将DTO对象转换为Model对象时 ...

  5. 关于python中的增量赋值的理解

    增量赋值运算符 += 和 *= 的表现取决于它们的第一个操作对象 += 操作首先会尝试调用对象的 __ iadd__方法,如果没有该方法,那么尝试调用__add__方法,所以+= 与 + 的区别实质是 ...

  6. 获取主线程Thread.currentThread()

    package seday08.thread; /** * @author xingsir * 主线程 * 线程提供了一个静态方法这个方法会将运行这个方法的线程返回:static Thread cur ...

  7. 简约清新立体商务年终工作总结汇报动态PPT模板

    模版来源:http://ppt.dede58.com/gongzuohuibao/26682.html

  8. Geoserver发布服务

    Geoserver发布服务的数据源很多样化 在数据存储中选择要发布的数据来源,这里以POSTGIS为例 1. 2.如果成功,就会读取出库里面的表,你可以在这里添加图层,发布服务 3.点击发布,进行服务 ...

  9. mongo [initandlisten] exception in initAndListen: 98 Unable to create/open lock file: /data/db/mongod.lock errno:13 Permission denied Is a mongod instance already running?, terminating 2019-09-23T16:

    解决方法: 加权 sudo chmod -Rf 777 /data/db

  10. django 做 migrate 时 表已存在的处理

    在开发web的时候,如果是以前已存在的项目,项目下载下来后,为了使用测试库的数据,会直接将整个测试库(如sqlite3)拿到本机来.这种情况下,如果执行的顺序不对,很容易在执行migrate的时候出现 ...