阴影锥(Shadow Volume)

2024-06-21 11:32
文章标签 volume 阴影 shadow

本文主要是介绍阴影锥(Shadow Volume),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Shadow Map和Shadow Volume是当今比较流行的实时阴影渲染方法,跟Shadow Map相比,Shadow Volume最大的优点是没有阴影锯齿问题,但由于它是基于几何的方法,每帧都有可能要构造和渲染阴影锥,而且有些工作必须由CPU完成,使得它在效率上没有Shadow Map高,因为其计算都是在GPU端完成的;不过对于室内场景或者objects不多的室外场景,Shadow Volume仍有用武之地,阴影锥的实现有多种算法,而且可以做比较多种优化,这里学习一下Z-PASS和Z-FAIL算法,它们都是multipass的,暂时没考虑优化问题。

Z-PASS算法

pass1:打开depth test,按正常方式渲染整个场景,得到depth map。

pass2:打开stencil test,关掉z writing和color buffer writing,渲染shadow volumes;设置stencil test always pass,对于front faces,若z test pass,则stencil value +1,若z test fail,则不更新stencil value;对于back faces,若z test pass,则stencil value -1。

pass3:pass2完成之后,stencil buffer中value不为0的像素就处于阴影区域,据此绘制阴影效果即可。

                               图1:Z-PASS算法

Z-PASS算法在视点位于阴影锥内或者跟近裁剪面相交时,会得到错误的stencil values,如下图所示:

                                             图2:Z-PASS算法失效的情况

Z-FAIL算法

Z-FAIL算法是 John Carmack,Bill Bilodeau 和 Mike Songy 各自独立发明的,其目的就是解决视点进入 shadow volume 后 Z-PASS 算法失效的问题;

pass1:跟Z-PASS算法一样

pass2:打开stencil test,关掉z writing和color buffer writing,渲染shadow volumes;设置stencil test always pass,对于front faces,若z test fail,则stencil value -1,若z test pass,则不更新stencil value;对于back faces,若z test fail,则stencil value +1。

pass3:跟Z-PASS一样

如图3所示,Z-FAIL算法不论视点位于阴影锥外面,里外还是近裁剪面与阴影锥相交,都可以正确得到stencil values。

                                                            图3:Z-FAIL算法

Z-FAIL要求Shadow Volume必须是闭合的,图4左将得到错误的stencil values,加上阴影锥caps(图4右)可以纠正。

                        图4:Z-FAIL算法的失效场景以及补救措施

阴影锥实现(Z-PASS)

Shadow Map与Shadow Volume的比较

Shadow Map的优势:

实现简单,不需要任何几何计算,shadow map可以完全由GPU生成。

不需要模板缓存,只需要为每个光源保存一张shadow map,没有缓存高填充率问题。

Shadow Map的劣势:

在阴影边缘容易形成锯齿,降低了阴影质量,特别在光源离阴影投射体很远的时候更明显。

对于每个光源,场景都需要渲染一次以得到shadow map,对于点光源,需要做更多的工作。


Shadow Volume的优势:

可获得高质量的阴影效果,没有阴影边缘锯齿问题;

能方便处理聚光照,方向光等多种光源。

Shadow Volume的劣势:

当光源或者投射物体的几何信息发生变化时,阴影锥都需要重新计算,占据比较多的CPU时间;

对几何体的拓扑有要求,即几何体必须是闭合的;

需要模板缓存,不优化的情况下存在高填充率问题,常见的优化方法有:有限阴影锥(Finite Volumes)、XY裁剪(XY Clipping)、Z限定(Z-Bounds);

无法处理具有透明材质物体的阴影投射,如公告板,粒子系统,树叶,grass等;

要求场景中的所有物体都接收投射的阴影,即使接收不到的情况下。


参考链接

http://http.developer.nvidia.com/GPUGems/gpugems_ch09.html

http://blog.donews.com/yyh/archive/2005/05/19/387143.aspx

这篇关于阴影锥(Shadow Volume)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1081100

相关文章

UE5 半透明阴影 快速解决方案

Step 1: 打开该选项 Step 2: 将半透明材质给到模型后,设置光照的Shadow Resolution Scale,越大,阴影的效果越好

Google Earth Engine——高程数据入门和山体阴影和坡度的使用

目录 山体阴影和坡度 对图像应用计算 应用空间减速器 高程数据 通过从“重置”按钮下拉菜单中选择“清除脚本”来清除脚本。搜索“elevation”并单击 SRTM Digital Elevation Data 30m 结果以显示数据集描述。单击导入,将变量移动到脚本顶部的导入部分。将默认变量名称“image”重命名为“srtm”。使用脚本将图像对象添加到地图: Map

CSS学习9[重点]--盒子模型大小、布局稳定性、CSS3盒模型以及盒子阴影

盒子模型2 一、content宽度和高度二、盒子模型的布局稳定性三、CSS3盒模型四、盒子阴影 一、content宽度和高度 使用宽度属性和高度属性可以对盒子的大小进行控制。 width和height的属性值可以为不同单位的数值或相对于父元素的百分比%,实际工作中最常用的是像素值。 大多数浏览器都采用了W3C规范,符合CSS规范的盒子模型的总宽度和总高度的计算原则是: 外

css-方形组件圆形阴影和动画

css-方形组件圆形阴影和动画 目录 文章目录 前言效果代码 前言 CSS特效思路:1个div包裹4个,最外层作为阴影来源,内部4个作为补齐补板。主要用到以下: border-radiusbox-shadow@keyframe, animationz-indextransitionposition, top, left 效果 代码 <!DOCTYPE html>

WebView滑动过程中去掉上下左右边界阴影(倒影)

WebView滑动过程中去掉上下左右边界阴影(倒影)   我们在用WebView加载含大量文字的html文件时,需要上滑下滑才能看到更多内容。这时会出现一个比较特别显眼的现象,就是webView滑动到顶端、底部、左右的时候出现阴影(倒影,颜色会根据设置的主题颜色变化)了,这是Android高版本自带的“特性”。   去除阴影的方法很简单,只要与ScrollView的滑动去除阴影的方法一致的操作就行

iOS xib设置阴影

原理和xib中设置边框一样,我大概说一下流程。废话不多说,看图: 相当于代码:         view.layer.shadowOffset = CGSizeMake(0, 5);         view.layer.shadowColor = [UIColor blackColor].CGColor;         view.layer.shadowOpaci

记录 PyQt6 / PySide 6 自定义边框窗口的 Bug 及可能可行的解决方案:窗口抖动和添加 DWM 环绕阴影的大致原理

前言: 本篇文章将要讨论我在前不久发表的关于 PyQt6 / PySide6 自定义边框窗口代码及内容中的问题: (终)PyQt6 / PySide 6 + Pywin32 自定义标题栏窗口 + 完全还原 Windows 原生窗口边框特效_pyside6 win32 无边框窗口-CSDN博客https://blog.csdn.net/2402_84665876/article/details/

k8s - Volume 简介和HostPath的使用

K8S 的持久化 K8S 实现持久化存储的方法有很多种 例如 卷 (Volume), 持久卷(PV), 临时卷(EV) 等, 还有很多不常用的选项上图没有列出来 其中Volume 本身也分很多种 包括 Secret, configMap(之前的文章covered了), hostPath, emptyDir等 本文主要focus on hostPath HostPath 的简介 官

canvas(3)阴影和渐变

(1)阴影 var drawing = document.getElementById('drawing');if(drawing.getContext){//获取绘图的上下文var context = drawing.getContext('2d');//设置阴影context.shadowOffsetX = 5;context.shadowOffsetY = 5;context.

自定义控件(7)---BlurMaskFilter边界阴影

Android中的很多自带控件都有类似软阴影的效果,比如说Button,使用BlurMaskFilter就可以得到类似的效果 activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"andro