计算机图形学入门18:阴影映射

1.前言

前面几篇关于光栅化的文章中介绍了如何计算物体表面的光照,但是着色并不会进行阴影的计算,阴影需要单独进行处理,目前最常用的阴影计算技术之一就是Shadow Mapping技术,也就是俗称的阴影映射技术。

2.阴影映射

Shadow Mapping是一种图像空间的算法。所谓图像空间就是使用Shadow Mapping在生成阴影的这一步,是不需要考虑场景中几何信息的。Shadow Mapping还会产生走样现象。

Shadow Mapping最重要的核心思想是:不在阴影中的点必须同时被光线和相机看到。

2.1 阴影映射过程

1.先从光源看向场景,得到深度图 。如下图所示,在一个点光源位置上放一个虚拟的相机看向场景,做一遍光栅化得到光源能看到的图,这张图不需要着色,只需要把深度记录下来即可,此时得到的这个深度图 即为Shadow Map

2.从相机视角渲染场景,得到对应深度图对应深度值。如下图所示,从相机视角渲染场景,将所有相机视角可见的点,利用光源视角下的那一套投影矩阵的逆矩阵,将坐标从世界坐标转换到光源视角的空间坐标,得到光源视角下的深度值,并找到在深度图上对应的深度值。

如果该点投影回光源视角的实际深度值不大于在深度图上对应的深度值(注意这里的深度值是浮点数,因为精度问题难以比较两个值相等),则说明此点可被光源照射,因此不在阴影中,如上图黄色线的这种情况。

如果该点投影回光源视角的实际深度值大于在深度图上对应的深度值,则说明该点前方有物体遮挡,因此在阴影中,如上图红色线这种情况。

这样就能判断哪些像素在阴影中了。下面举一个例子,如下图所示,是一个生成了阴影的场景。

先来比较有阴影和无阴影的区别,如下图所示。

从光线角度看生成的Shadow Map如下图所示。距离光源越近代表深度越小,所以颜色越黑,反之亦然。

将相机视角方向渲染的投影到光源视角,通过深度图得到对应的深度值。如下图所示,球上对应的阴影信息看起来很脏,那是因为判断浮点数相等是很难的,只能判断大于。还会存在精度和走样的问题。

2.2 Shadow Map的问题

1.Shadow Map只能产生硬阴影(Hard Shadows) 。虽然有其他办法可以用来生成软阴影(Soft Shadows),但是理论上只用来生成硬阴影,只适用于没有体积的点光源。

软硬阴影区别示意如下,上方棱角分明为硬阴影,下方为软阴影。软阴影效果更加真实。

产生这种问题的原因是因为光源具有体积,导致有的地方完全看不到光源**(本影, Umbra)** ,有的地方能看到一部分光源**(半影,Penumbra)**。所以阴影的边缘在本影与半影之间会有过渡的情况,从而产生软阴影现象,就像上图中太阳与地球的角度导致的日食现象一样。所以点光源也无法产生软阴影,因为点光源没有体积大小。

2.阴影质量取决于Shadow Map的分辨率。分辨率越高性能消耗也更多。

3.涉及相等比较的浮点深度值意味着尺度、偏差、容差等问题

相关推荐
梵尔纳多1 天前
视角的移动以及模型的平移,旋转,缩放
c++·图形渲染·opengl
_李小白1 天前
【OSG学习笔记】Day 3: OSG 实用工具
笔记·图形渲染
_李小白2 天前
【OSG学习笔记】Day 4: 矩阵变换
笔记·学习·矩阵·图形渲染
平行云PVT2 天前
数字孪生信创云渲染技术解析:从混合信创到全国产化架构
linux·unity·云原生·ue5·图形渲染·webgl·gpu算力
做cv的小昊2 天前
结合代码读3DGS论文(10)——ICLR 2025 3DGS加速&压缩新工作Sort-Free 3DGS论文及代码解读
论文阅读·人工智能·游戏·计算机视觉·3d·图形渲染·3dgs
郝学胜-神的一滴3 天前
走进计算机图形学的浪漫宇宙 | GAMES101 开篇课程全解析
c++·算法·图形渲染·计算机图形学
好家伙VCC6 天前
# 发散创新:用 Rust构建高并发虚拟世界引擎核心模块在当今游戏开发与元宇宙构建中,**虚拟世界的性能瓶颈往往不是图形渲染,而是底
java·开发语言·python·rust·图形渲染
懒洋洋在睡觉9 天前
Vulkan demo入门教程三:逻辑设备、队列与交换链
c++·图形渲染
wangzy19829 天前
一个高效稳定的多边形三角化算法(支持自交和孤岛检测)
算法·图形渲染