实时阴影渲染(一):PSSM平行分割阴影图

PSSM(Parallel Split Shadow Map)平行分割阴影图,是一种根据距离远近采用多个深度纹理渲染阴影的方法

适合用于室外大场景中的平行光比如太阳形成的阴影

本系列需要读者了解基本的深度阴影渲染方面的知识

1 视锥划分

如下图,以采用三个划分为例:

这里将视锥体平行划分为3个区域,代号分别为1、2、3

这三个区域在渲染阴影的时候分别采用不同的阴影图sm1、 sm2、sm3

这样将1、2、3对应的距离数据打包为一个float3变量splits.xyz,传入片段shader,然后通过以下的代码实现阴影图的选择:

if (z <= splits.x)
{
    shadow = depthShadow(sm1,...);
}
else if (z <= splits.y)
{
    shadow = depthShadow(sm2,...);
}
else if (z <= splits.z)
{
    shadow = depthShadow(sm3,...);
}

这里z 、depthShadow函数和单个深度纹理阴影的实现类似,区别是相关参数都变成了三份

图上的三个划分并没有包含全部的渲染区域,因为没有必要渲染特别远的阴影

各个阴影区域的大小可以根据需要选择合理的算法

根据实际情况也可以将阴影区域划分为两个或者更多个

为了平滑 ,最后一级阴影(本例的3)可根据z值做线性淡入淡出

2 投影矩阵计算

渲染阴影前需要分别渲染三个深度纹理

对每一个阴影区域都需要计算对应的正投影矩阵

计算正投影矩阵可以理解为计算正投影相机的位置、投影大小和相机的up矢量

下面以单个投影区域为例说明如何计算这三个要素

如上图,彩色阴影部分为视锥体的单个划分区域

根据当前相机的位置、FOV、纵横比和远近截面距离可以算出该视锥体的八个顶点(这里为了简化仅画出四个)

根据光照方向可以用任一垂直矢量作为投影相机up矢量,不过不同的up矢量得到的投影体大小不同,你可以设计专门的算法计算最优的up矢量

然后再通过光照方向和up矢量的叉积计算出right矢量

任选一参照点(此例为左下的O点),通过up\right矢量和光照方向可以计算出其它7个点在投影相机空间相对于O点的最大、最小值也就是最小包围盒

如图所示,相机的位置应在AB的中点D所在的中心线上,其相对于D点的距离为AC的长度加上阴影可能的投影距离(视锥体外的物体投影)

投影体的长为AB的长度,宽为right方向得到的长度(此图没画出来)

也可以将视锥体的八个顶点直接转到相机空间计算轴对称包围盒、相机位置,然后再将相机位置变换回世界空间

不过当场景很大时,正反两次变换造成的误差会非常的大,直接在世界坐标系内计算则不会有这种问题

时间: 2024-08-06 20:05:23

实时阴影渲染(一):PSSM平行分割阴影图的相关文章

实时阴影渲染(二):软阴影

软阴影是通过对阴影图进行多次采样实现的 因为多个片段经常会对应同一个阴影纹理像素,单次采样会产生严重的锯齿问题 另外软阴影还可以产生比较柔和的边界,看起来比较自然 锯齿产生的原因 仔细思考阴影锯齿产生的原因,可以想到多个片段对应同一个阴影像素时,其在该阴影像素中对应的的位置是不同的 如下示意图,黑色的大方格表示单个阴影纹理像素,虚线分割的部分表示对应到该阴影像素的9个片段 显然对于AB来说其阴影值和C应该是不同的,算法中应该把这个因素考虑进去 可以想到,当纹理坐标没有对应到正中心时,通过与相邻像

Unity3D手游开发日记(1) - 移动平台实时阴影方案

阴影这个东西,说来就话长了,很多年前人们就开始研究出各种阴影技术,但都存在各种瑕疵和问题,直到近几年出现了PSSM,也就是CE3的CSM,阴影技术才算有个比较完美的解决方案.Unity自带的实时阴影,也是这种技术,在电脑上很成熟的.我也是目睹了阴影技术的发展,以前也自己写过一些阴影,本来以为以后再也不用担心阴影了,结果做移动游戏以后,发现情况没那么乐观.这种基于深度的shadow map 技术,需要浮点纹理的支持,但有的移动平台不支持浮点纹理,即使支持,这种技术开销也特别大.所以我们需要重新思考

一个实用的实时毛发渲染及着色方法

一个实用的实时毛发渲染及着色方法 Thorsten scheuermann ATI Resarch,Inc. 翻译:潘曦 (译文里的(pancy:XXX)为译者注) 介绍: 我们提出了一个使用多边形模型的实时毛发渲染算法,并且将其应用于今年SIGGRAPH动画节上的一个实时动画<ruby:The Double Cross>上面.该毛发渲染算法是基于Kajiya-Kay 毛发渲染模型的算法,但是在其之上添加了一个实时的接近现实高光的镜面反射效果(pancy:原始算法可能没有考虑到头发的高光只计算

.NET实时2D渲染入门&#183;动态时钟

.NET实时2D渲染入门·动态时钟 从小以来"坦克大战"."魂斗罗"等游戏总令我魂牵梦绕.这些游戏的基础就是2D实时渲染,以前没意识,直到后来找到了Direct2D.我的2D实时渲染入门,是从这个动态时钟开始的. 本文将使用我写的"准游戏引擎"FlysEngine完成.它是对Direct2D和.NET库SharpDX浅层次的封装,隐藏了一些细节,简化了一些调用.同时还保留了Direct2D的原汁原味. 本文的最终效果如下: 绘制动态时钟 要绘制动

[OpenGL] shadow mapping(实时阴影映射)

source:原文地址 code:点击可以直接下载源代码 1978年,Lance Williams在其发表的论文<Casting curved shadows on curved surfaces>中提出了Shadow mapping算法,从那以后,该算法在离线渲染和实时渲染两个领域都得到了广泛的应用.皮尔斯动画工作室的Renderman渲染器.以及一些知名电影如<玩具总动员>都使用了shadow mapping技术. 在众多图形应用的阴影技术中,shadow mapping只是产

Unity5.0实时阴影的优化

修改灯光属性Strength(投影力度)值越大投影越清晰越黑Bias(偏斜)值越大投影越往外偏斜 修改质量面板的ShadowsShadoe Resolution(投影分辨率)在不考虑资源的情况下可开大Shadow Cascades(阴影级别)级别越高,性能越大Shadow Distance(可见阴影距离)值越小摄像机可见阴影距离越短,此方法常用,提高性能 注意:被投射阴影的物体面积越小,投影清晰度越高

Ogre参考手册(十一) 7 Shadows阴影

7 Shadows阴影 阴影渲染是很重要且很活跃的领域.渲染阴影的技术有很多,各有优点和缺点.为此Ogre提供了多种阴影实现,并提供大量的配置选项,以便根据场景选择最合适的方式. 根据阴影形状产生方式阴影可分为两类:模板和纹理.另外还由多种将阴影渲染到场景中的方法: 1 调制阴影(Modulative),将阴影区域变暗(将没有灯光照射的部分变暗,多个光源时,共同阴影会更暗:这样如果阴影调制色固定,灯光越多,阴影越暗.这种情况下,开灯的同时,需要同时变亮调制色) 2 灯光叠加(Additive),

(转)阴影锥(Shadow Volume)

转自:http://blog.csdn.net/zjull/article/details/11819923 Shadow Map和Shadow Volume是当今比较流行的实时阴影渲染方法,跟Shadow Map相比,Shadow Volume最大的优点是没有阴影锯齿问题,但由于它是基于几何的方法,每帧都有可能要构造和渲染阴影锥,而且有些工作必须由CPU完成,使得它在效率上没有Shadow Map高,因为其计算都是在GPU端完成的:不过对于室内场景或者objects不多的室外场景,Shadow

Shadow Volume( 阴影体)渲染技术的实现细节及感受(一)之 阴影体生成

首先贴一个链接,该链接内有大量基于OpenGL的渲染技术教程和Code Sample,本文基本上在其Tutorial 40的基础上进行了翻译,并加入了部分自己的理解.原文在此: http://ogldev.atspace.co.uk/index.html Shadow Volume,即阴影体技术.是CG中非常常见的阴影渲染技术.在自己动手实现之前,也看了好多原理上的东西.但是纸上得来终觉浅,绝知此事要躬行啊! 以此文记录下Shadow Volume实现过程中的种种. 简单地讲,光线照射空间几何物