Single Depth peeling 顺序无关渲染(OIT)
什么是顺序无关渲染
在3D渲染中,物体的渲染是按一定的顺序渲染的,这也就可能导致半透明的物体先于不透明的物体渲染,结果就是可能出现半透明物体后的物体由于深度遮挡而没有渲染出来。对于这种情况通常会先渲染所有的不透明物体再渲染半透明物体或者按深度进行排序来解决。但这样仍然无法解决半透明物体之间的透明效果渲染错误问题,特别是物体之间存在交叉无法通过简单的排序来解决。于是就有一些用专门来解决半透明物体渲染算法,OIT算法即Order Independent Transparency(顺序无关的半透明渲染)。Depth Peeling是众多OIT算法里可以得到精确blending结果的一个,在非游戏的3d应用场景中应该还是很有价值的。

两个交叉半透明四边形(未使用OIT渲染)

两个交叉半透明四边形(使用OIT渲染)
Single Depth Peeling原理
Single Depth Peeling 顾名思义,就是通过多次绘制,每次绘制剥离离相机最靠近的一层,像剥洋葱一样层层剥开,按顺序混合就得到了精确的混合结果。既然有Single Depth Peeling,还有一种优化版本就是Dual Depth Peeling,从前后两个方向剥离,不在本次讨论的范围,有兴趣可以参考链接论文。
深度剥离是一种对深度值进行排序的技术。它的原理比较直观,通常的深度检测是将场景中Z值最小的像素输出到屏幕上,就是里相机最近的像素。如此一来就一定有离相机第二近的点,第三近的点·····。通过多次渲染的方法,第一次正常渲染,将深度值存入纹理就得到来离相机最近像素的深度和颜色。第二遍渲染时,把每个像素的深度与上次的深度值做比较,凡是小于上次深度值的都通过测试,在加上FBO深度测试的最小值功能就能得到下一个最小的深度值与颜色值,以此类推即可。
缺点
需要剥离N次才能完成,就需要N个Pass,N是深度复杂度。因此性能是严重的瓶颈,另外如何确定N也是个问题。
具体流程
1、创建两对颜色纹理和两对GL_FLOAT类型的深度纹理用来pingpong。
2、clear深度纹理为0,关闭OpenGL混合
2、正常渲染,大于深度纹理上的值都可以通过测试,加上深度缓冲测试的最小深度值就可以得到离相机最近的深度与颜色值。将颜色结果与颜色纹理中的颜色做混合,深度写入深度纹理。
3、使用上次得到的颜色与深度作为输入纹理重复2的操作,直到剥离完成。
如何从前向后混合颜色
从前向后直接混合明显是错误的,但是我们可以根据混合算法推导出反向混合的算法,具体推导可以参考Dual Peth Peeling的paper。具体混合算法为:
glBlendEquation(GL_FUNC_ADD);
glBlendFuncSeparate(GL_DST_ALPHA, GL_ONE, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
如何确定N
我们无法确定需要剥离多少次,因为不同的渲染目标的深度复杂度是不同的。目前来说最好的方法是采用遮挡查询的方式来检测是否剥离完成。但这种方式需要GPU同步,也会带来严重的性能问题。方式如下
GLuint queryId;
glBeginQuery(GL_SAMPLES_PASSED, queryId);
//depth peeling
glEndQuery(GL_SAMPLES_PASSED);
GLuint queryReady = GL_FALSE;
glGetQueryObjectuiv(queryId, GL_QUERY_RESULT_AVAILABLE, &queryReady);
GLuint samples = 0;
glGetQueryObjectuiv(mOITQueryId, GL_QUERY_RESULT, &samples);
samples为0时就剥离完成了,不能0则继续剥离。
实际应用中值得注意的地方
由于深度精度问题可能会造成交叉的地方有接缝,具体做法如下:
1、深度缓冲及纹理使用GL_FLOAT类型增加精度。
2、纹理需要使用高精度的纹理 precision highp sampler2D;
3、离摄像机过于仍然会由于精度不足而出现接缝,这时就需要动态调整摄像机远近平面来提升精度
4、优化遮挡查询中的同步操作
5、避免遮挡查询出现死循环
优化方向
1、本文采用从前向后剥离,在细节要求不高的情况下可以固定N,忽略后续的剥离影响不大。
2、使用Dpeth Peeling的优化版本Dual Dpeth Peeling
3、使用高版本才能支持的per pixel linked list方法
Single Depth peeling 顺序无关渲染(OIT)的更多相关文章
- DirectX11 With Windows SDK--29 计算着色器:内存模型、线程同步;实现顺序无关透明度(OIT)
前言 由于透明混合在不同的绘制顺序下结果会不同,这就要求绘制前要对物体进行排序,然后再从后往前渲染.但即便是仅渲染一个物体(如上一章的水波),也会出现透明绘制顺序不对的情况,普通的绘制是无法避免的.如 ...
- CSharpGL(22)实现顺序无关的半透明渲染(Order-Independent-Transparency)
+BIT祝威+悄悄在此留下版了个权的信息说: CSharpGL(22)实现顺序无关的半透明渲染(Order-Independent-Transparency) 在 GL.Enable(GL_BLEND ...
- NV OIT algorithm : Depth peeling is a fragment-level depth sorting technique
https://developer.nvidia.com/content/interactive-order-independent-transparency Correctly rendering ...
- depth peeling实现半透明
aaarticlea/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aH
- sqlmap映射继承机制及映射字段顺序与SQL查询字段顺序无关
<typeAlias alias="TblSpPartsinfo" type="com.bn.car.biz.supply.dao.po.PartsInfoPO&q ...
- thead、tbody、tfoot与顺序无关
今天发现一个问题,thead.tbody.tfoot等标签的内容排版与顺序无关,做了一个小的实验:
- Unity3D事件函数的执行顺序 - 包含渲染等模块的完整版,中英文对照
原文地址: http://www.cnblogs.com/ysdyaoguai/p/3746828.html In Unity scripting, there are a number of eve ...
- 浏览器加载和渲染html的顺序-css渲染效率的探究
1.浏览器加载和渲染html的顺序1.IE下载的顺序是从上到下,渲染的顺序也是从上到下,下载和渲染是同时进行的.2.在渲染到页面的某一部分时,其上面的所有部分都已经下载完成(并不是说所有相关联的元素都 ...
- 浏览器加载和渲染html的顺序-css渲染效率的探究(转载)
1.浏览器加载和渲染html的顺序1.IE下载的顺序是从上到下,渲染的顺序也是从上到下,下载和渲染是同时进行的.2.在渲染到页面的某一部分时,其上面的所有部分都已经下载完成(并不是说所有相关联的元素都 ...
随机推荐
- ServletContext使用介绍
ServletContext是一个容器(域对象)可以存储键值对数据(String key,Object value),保存在ServletContext中的数据不仅可以提供给所有的servlet使用, ...
- centos7下PHP安装gd扩展
第一步: 安装需要用到的库 yum -y install libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel 第二步: ...
- net core 微服务框架 Viper 调用链路追踪
1.Viper是什么? Viper 是.NET平台下的Anno微服务框架的一个示例项目.入门简单.安全.稳定.高可用.全平台可监控.底层通讯可以随意切换thrift grpc. 自带服务发现.调用链追 ...
- oneshot_tjctf_2016
简单题,容易想到先泄漏libc基址,然后jump to onegadget 从而getshell from pwn import * ''' author: lemon time: 2020-10-2 ...
- http与https随笔
http: 超文本传输协议.使用TCP/IP协议 https: 安全超文本传输协议.使用TLS/SSL协议 不同: 1.安全 http是明文传输.http是具有安全性的SSL加密传输协议. https ...
- Pytorch中cudnn版本查询
问题: Disable or able cudnn,查询版本. Disable cudnn for batch_norm: (See: @Microsoft / human-pose-estimati ...
- Hadoop框架:HDFS高可用环境配置
本文源码:GitHub·点这里 || GitEE·点这里 一.HDFS高可用 1.基础描述 在单点或者少数节点故障的情况下,集群还可以正常的提供服务,HDFS高可用机制可以通过配置Active/Sta ...
- 解放双手,不写SQL!一个开源mybatis神器
什么是通用 Mapper? 它是一个可以方便的使用 Mybatis 进行单表的增删改查优秀开源产品.它使用拦截器来实现具体的执行 Sql,完全使用原生的 Mybatis 进行操作.在 Github 上 ...
- Python使用协程进行爬虫
详情点我跳转 关注公众号"轻松学编程"了解更多. 1.协程 协程,又称微线程,纤程.英文名Coroutine. 协程是啥 ?? 首先我们得知道协程是啥?协程其实可以认为是比线程更小 ...
- P5530 [BOI 2002]双调路径
题意描述 [BOI 2002]双调路径 题意描述的确实不是很清楚(出题人惜字如金). 给定一张有 \(n\) 个点,\(m\) 条边的无向图,每条边有两个权值,分别表示经过这个点的代价和时间. 同时给 ...