每天一篇GDC: Optimized Stenciled Shadow Volumes_kevin_dust的博客-程序员资料

技术标签: paper翻译  

图片稍后补上。。
Optimized Stenciled Shadow Volumes
首先当然先说说这事神马:
Shadow Volume其实是区别ShadowMapping的一种阴影生成方法
首先分两个步骤:
1、生成阴影体
2、对阴影进行渲染

为了简要说明shadow Volume的原理,接下来先介绍该方法是如何对阴影进行渲染

一、阴影渲染(ZPass && ZFail)
1、ZPass:
其实这个方法很简单,也很迅速:

算法:
(1)、先取得整个场景的深度值(此时没必要进行光照)
(2)、接下来,我们根据深度值,来做一些列判断,so关闭深度写
(3)、好了,开始渲染了,不过我们不是直接渲染阴影,而是先渲染阴影体..
(4)我们以视点到观察地方的顺序渲染阴影体
(5)、对于某个像素来说,如果阴影体正面的深度测试通过,则该像素的模版值+1,如果阴影体背面的深度测试通过,则-1
(6)、最后,模板值不为0的就在阴影体中..
(7)、此时重新开启深度写,用模板的方法对整个场景重新渲染(加上光照)
(8)、不渲染模板值不为0的阴影部分即可(用alpha blend)
缺陷:

(1)、整个算法建立在视点不在阴影体中,若视点在阴影体中,该算法失效

(2)、当Z-near clip plane过近,由于视锥剔除,阴影体的一部分可能被剔除,就会导致模板计数错误
2、ZPass:
算法:
(1)、先取得整个场景的深度值(此时没必要进行光照)
(2)、接下来,我们根据深度值,来做一些列判断,so关闭深度写
(3)、好了,开始渲染了,不过我们不是直接渲染阴影,而是先渲染阴影体..
(4)、我们以观察地方到视点的顺序渲染阴影体(与ZPass相反)
(5)、对于某个像素来说,如果阴影体背面的深度测试通过,则该像素的模版值+1,如果阴影体正面的深度测试通过,则-1
(6)、最后,模板值不为0的就在阴影体中..
(7)、此时重新开启深度写,用模板的方法对整个场景重新渲染(加上光照)
(8)、不渲染模板值不为0的阴影部分即可(用alpha blend)
缺陷:
(1)、要求阴影体积必须封口

    (2)、当Z-far clip plane过近,由于视锥剔除,阴影体的一部分可能被剔除,就会导致模板计数错误

二、阴影体生成–见shadowVolume优化的第五点
三、Shadow Volume的优化
1、Fill Rate Optimizations
(1)Zpass VS ZFail:(可以根据不同情况选择来用)
a、Zpass不需要封口,而且加上遮挡剔除,他的速度很快。但是当阴影体与nearPlane相交,更有甚者,视点在阴影体里面(这时候更加相交),就跪了
b、ZFail就慢一点咯..而且要封口..
对于每个occluder(遮掩物),我们都可以分别选择ZPass,还是ZFail。
如何选择:

以光源,nearPlane做一个三角面,如果不在里面,则Zpass,否则ZFail
(2)Exploit Bounds:(就是弄个判断,没必要的就别弄了)
··(光照裁剪算法。。。)

解决方案:Depth Bounds Test :根据ZMax和ZMin判断

2、Culling Optimizations
(1)、Shadow volume culling
传统的culling做法:
Use conservative bounding geometry(保守边界:封口) to efficiently determine when object is outside the view frustum
Shadow volume culling(看不见不代表不投射阴影):
新的剔除标准:

(2)、Portal-based culling
For bounded lights, we can treat the light bounds as the “visible object” we’re testing for
If the light bounds are visible, we need to process the light
If the light bounds are invisible, we can safely skip the light
3、Silhouette Determination Optimizations\
(1)、对于静态的遮掩物和光源:可以提前算好阴影体
Precomputation of shadow volumes can include bounding shadow volumes to the light bounds
(2)、对于静态的遮掩物和光源:采用有效的数据结构
But static occluders could exploit precomputation
See SIGGRAPH 2000 paper “Silhouette Clipping” by Sander, Gui, Gortler, Hoppe, and Snyder
Check out the “Fast Silhouette Extraction” section
Data structure is useful for fast shadow volume possible silhouette edge determination
(3)、简化遮掩物模型
A、越复杂的模型就会出现更多的silhouette edges
B、三角面越多,就要花更多时间搜索silhouette edges
C、越多silhouette edges ,shadow volume就要消耗更多填充率(绘制更多的点)

4、Shadow Volume Rendering Optimizations
(1)、Compute Silhouette Loops on CPU
Only render silhouette for zpass
Vertex transform sharing
(2)、Extrude Triangles instead of quads
避免Shadow Volume冗余的变化
GL_QUAD_STRIP rather than GL_QUADS
需要一个确定的由所有silhouette组成的循环
一旦找到一个就可以直接遍历一次循环
Shadow Volume Extrusion using Triangle Fans\
(3)、Wrapping stencil to avoid overflows
(4)、Two-sided stencil testing
First, rasterizing front-facing geometry
Second, rasterizing back-facing geometry

wo sets of stencil state: front- and back-facing
Rasterizes just as many fragments,but more efficient for CPU & GPU
(5)、Vertex programs for shadow volume rendering
(1)、Fully automatic shadow volume extrusion
Everything off-loaded to GPU,This needs a LOT of extra vertices
Quite inefficient, not recommended
No way to do zpass cap optimizations
No way to do triangle extrusion optimizations

(2)、Vertex normal-based extrusion
If NL is greater or equal to zero, leave vertex alone
If NL is less than zero, project vertex away from light
Worst on faceted, jaggy, or low-polygon count geometry
No way to do zpass cap optimizations
No way to do triangle extrusion optimizations

顶点的法线是典型的为了光照计算,而不是阴影:
顶点的法线可以很好地表达弯曲程度,但不是方向
阴影应该取决于细小平面的方向
这里的法线应该是为了一个三角形(平面的法线),而不是一个顶点的法线
一种乱来方法
在同一位置放入多个法线不同的顶点
(3)、Semi-automatic shadow volume extrusion(通过CPU计算)
a unique set of possible silhouette edge of vertices per light per model

A、遍历模型的所有三角形
B、计算dot3( light_direction , triangle_normal ) 。用这个结果判断三角形是面向光源(dot3>0) 还是背向光源(dot<0) 。
C、对于面向光源的三角形,将所有的三条边压入一个栈,和里面的边进行比较,如果发现重复的(edge1和edge2) ,将这些边删除
D、检测过所有三角形的所有边以后,栈里面剩下的边就是当前光源/
E、物体位置下面的silhouette edge.
F、根据光源方向, 利用CPU 或者vertex shader 将这些silhouette edge 投射出去形成shadow volume.
特点:
Make two copies of every vertex,each with 4 components (x,y,z,w)
Straightforward to handle caps too
Vertex array memory required = 8 floats / vertex
Independent of number of lights
Vertex program required is very short
Much less vertex array memory than fully automatic approach
5、Shadow Volume Polygon Rendering Order
Naïve approach
Simply render cap & projection shadow volume polygons in “memory order” of the edges and polygons in CPU memory(以内存存放顺序渲染)
Disadvantages
Potentially poor rasterization locality for stencil buffer updates
Typically sub-par vertex re-use
Advantages
Friendly to memory pre-fetching Obvious, easy to implement approach
GPU Optimized Approach
Possible silhouette edges form loops
Render the projected edge shadow volume quads in “loop order”
(刚刚说到的,弄一个循环,以此为顺序)
When you must render finite and infinite caps
Greedily search for adjacent cap polygons
Continue until the cap polygons bump into possible silhouette edge loops – then look for more un-rendered capping polygons
Advantages:
Tends to maximize vertex re-use
Avoids retransforming vertices multiple times due to poor locality of reference
Maximizes stencil update efficiency
Adjacent polygons make better use of memory b/w
Convenient for optimizations
zpass cap elimination
triangle instead of quad extrusion
Easy to implement
Once you locate a possible silhouette edge, it’s easy to follow the loop
Easy to greedily search for adjacent finite & infinite cap polygons

四、Shadow Volume的噩梦
1、Chain-link fence:(铁丝网。。。会恶心死)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/kevin_dust/article/details/51903043

智能推荐

C++封装互斥锁和基于RAII机制能自动解锁的互斥锁_奇妙之二进制的博客-程序员资料

#include "base/mutex.h"Mutex::Mutex() { pthread_mutex_init(&amp;mutex_, NULL); }Mutex::~Mutex() { pthread_mutex_destroy(&amp;mutex_); }void Mutex::Lock() { pthread_mutex_lock(&amp;mutex_); }void Mutex::Unlock() { pthread_mutex_unlock(&amp;mutex_);

struts2出错java.lang.NoClassDefFoundError: org/apache/commons/lang3/StringUtils_weixin_30364147的博客-程序员资料

http://blog.csdn.net/nero_2012/article/details/7550436转载于:https://www.cnblogs.com/yidijimao/p/5709829.html

Eclipse(STS) 导入本地 spring boot (gradle)多项目_weixin_34148456的博客-程序员资料

1、Import-General-Project from Folder or Archive2、选择需要导入的项目(这里是一个多项目,选择主项目导入就行)3、选中后finish就行了。转载于:https://www.cnblogs.com/tt9527/p/7145982.html...

Java入门需掌握的30个基本概念_码农之屋的博客-程序员资料

我的公众号「码农之屋」(id: Spider1818),分享的内容包括但不限于 Linux、网络、云计算虚拟化、容器Docker、OpenStack、Kubernetes、SDN、OVS、DPDK、Go、Python、C/C++编程技术等内容,欢迎大家关注。​1.OOP中唯一关系的是对象的接口是什么,就像计算机的销售商她不管电源内部结构是怎样的,他只关系能否给你提供电就行了,也就...

舞伴配对问题c语言实训报告,1舞伴配對系统实训报告.doc_游戏干线的博客-程序员资料

1舞伴配對系统实训报告舞伴配对系统本题目设计目的是训练本人的基本编程能力,了解数据结构C++实现系统的开发流程,掌握数据结构和熟悉C++语言的面向对象各种基本操作。本程序中涉及结构体、单链表、类等方面的知识。通过本程序的训练,使本人能对C++语言的类操作有一个更深刻的了解,为进一步开发出高质量的有关数据结构方面系统打下坚实的基础。1、问题定义【内容与要求】假设在周末舞会上,男士们和女士们进入舞厅时...

关系抽取_完整项目_CodingPark编程公园_TEAM-AG的博客-程序员资料

#人名识别 #人物属性识别 #人与人的关系识别

随便推点

解析法实现一元线性回归、多元线性回归以及数据模型可视化操作_多元线性回归的可视化_拾牙慧者的博客-程序员资料

解析法实现一元线性回归代码:#加载样本数据x=[137.97,104.50,100.00,124.32,79.20,99.00,124.00,114.00,106.69,138.05,53.75,46.91,68.00,63.02,81.26,86.21]y=[145.00,110.00,93.00,116.00,65.32,104.00,118.00,91.00,62.00,133.00,51.00,45.00,78.50,69.65,75.69,95.30]meanX=sum(x)/len(x

Maven 构建错误 Cannot resolve plugin org.apache.maven.plugins:maven-clean-plugin:3.1.0_flyingdream123的博客-程序员资料

在构建文件pom.xml的 &lt;properties&gt;节中添加阿里的环境仓库: &lt;repositories&gt; &lt;repository&gt; &lt;id&gt;alimaven&lt;/id&gt; &lt;url&gt;https://maven.aliyun.com/repository/public&lt;/url&gt; &lt;/repository&gt; &lt;.

《Docker快速入门(基础篇)》Docker Hub实用指南_lewis2951的博客-程序员资料

​在《Windows下安装Docker》一文末尾,体验了一下Hello World,其过程只需两步:拉取镜像、创建并运行容器。其中,拉取的镜像hello-world,就来自Docker Hub官方仓库,地址为:https://hub.docker.com。

esp01s如何烧录、接线///arduino串口想输出字符串,但是输出了数字_esp01s烧录_嵌入式填坑指南的博客-程序员资料

esp01s与usb转ttl接线:esp01s连线usb转ttl3V3---------3V3GND---------GNDRX---------TXDTX---------RXDIO0---------GNDIO0接地作用是:进入烧录模式,接地之后需要断电,重新上电。完成烧录后需要 断开 IO0与GND否则程序无法运行。...

PowerMock概述_易生一世的博客-程序员资料

1.PowerMock的概念PowerMock包含两个彼此独立的扩展实现,一个基于EasyMock的扩展实现,另一个基于Mockito的扩展实现。此外,基于Mockito2的扩展实现还在实验过程中。所以在执行PowerMock测试时,需要同时使用EasyMock或Mockito。2.PowerMock的独特功能PowerMock可以实现对构造函数, static方法, final方

Guice笔记_补充_iteye_887的博客-程序员资料

1、关于标注绑定,如若不是属性,是方法上的注入,如下适用标注@[email protected] Service service;//方法上的如下@Injectvoid injectService(@Www Service service) { ...}2、隐式绑定,如果缺少显示绑定(即没有写任何binder),Guice会试图注入并创建一个所依赖的...

推荐文章

热门文章

相关标签