实时阴影渲染(一):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方向得到的长度(此图没画出来)
也可以将视锥体的八个顶点直接转到相机空间计算轴对称包围盒、相机位置,然后再将相机位置变换回世界空间
不过当场景很大时,正反两次变换造成的误差会非常的大,直接在世界坐标系内计算则不会有这种问题
实时阴影渲染(一):PSSM平行分割阴影图的更多相关文章
- Unity3D手游开发日记(1) - 移动平台实时阴影方案
阴影这个东西,说来就话长了,很多年前人们就开始研究出各种阴影技术,但都存在各种瑕疵和问题,直到近几年出现了PSSM,也就是CE3的CSM,阴影技术才算有个比较完美的解决方案.Unity自带的实时阴影, ...
- Unity局部高效实时阴影的思考和实现
http://game.ceeger.com/forum/read.php?tid=23305&fid=2 无意间看到一篇文章,说是Unity5 demo中为了实现角色的良好阴影,单独给角色设 ...
- .NET实时2D渲染入门·动态时钟
.NET实时2D渲染入门·动态时钟 从小以来"坦克大战"."魂斗罗"等游戏总令我魂牵梦绕.这些游戏的基础就是2D实时渲染,以前没意识,直到后来找到了Direct ...
- 【实时渲染】实时3D渲染如何加速汽车线上体验应用推广
在过去,一支优秀的广告片足以让消费者对一辆汽车产生兴趣.完美的底盘线条或引擎的轰鸣声便会让潜在买家跑到经销商那里试驾.现在,广告还是和往常一样,并没有失去其特性,但86%的买家在与销售交流之前会在网上 ...
- (转)阴影锥(Shadow Volume)
转自:http://blog.csdn.net/zjull/article/details/11819923 Shadow Map和Shadow Volume是当今比较流行的实时阴影渲染方法,跟Sha ...
- Unity Shader 卡通渲染 基于退化四边形的实时描边
从csdn转移过来,顺便把写过的文章改写一下转过来. 一.边缘检测算法 3D模型描边有两种方式,一种是基于图像,即在所有3D模型渲染完成一张图片后,对这张图片进行边缘检测,最后得出描边效果.一种是基于 ...
- Shadow Map阴影贴图技术之探 【转】
这两天勉勉强强把一个shadowmap的demo做出来了.参考资料多,苦头可不少.Shadow Map技术是目前与Shadow Volume技术并行的传统阴影渲染技术,而且在游戏领域可谓占很大优势.本 ...
- 剖析虚幻渲染体系(14)- 延展篇:现代渲染引擎演变史Part 1(萌芽期)
目录 14.1 本篇概述 14.1.1 游戏引擎简介 14.1.2 游戏引擎模块 14.1.3 游戏引擎列表 14.1.3.1 Unreal Engine 14.1.3.2 Unity 14.1.3. ...
- Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第二十章:阴影贴图
原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第二十章:阴影贴图 本章介绍一种在游戏和应用中,模拟动态阴影的基本阴影 ...
随机推荐
- POJ #1042 Gone Fishing - WA by a DP solution. TODO
I used DP instead of Greedy. But got WA on PoJ, though it passed all web-searched cases. Maybe I hav ...
- golang的ssh例子
package main import ( "github.com/dynport/gossh" "log" ) func MakeLogger(prefix ...
- html中select标签获取选中value和text
$("#id").find("option:selected").text(); //获取Select选择的Text$("#id").val ...
- ORA-04031案例一则
ORA-04031这个错误,几乎每一个专业的DBA都遇到过.这是一个相当严重的错误,Oracle进程在向SGA申请内存时,如果申请失败,则会报这个错误.大部分情况下是在向SGA中的shared poo ...
- java定时器和多线程实践记录
这几天因为需要测试mongodb读写分离的问题,因此写了个定时查询程序,并且用到了多线程,以达到定时启动多个线程查询数据库的效果,下边代码记录备忘: package timmer; import ja ...
- 一个SQLSERVER触发器的示例
CREATE TRIGGER WoStateChange on T_PD_WorkOrder AFTER UPDATE AS BEGIN declare @WorkOrderID varchar(20 ...
- JavaScript权威指南 第二章 词法结构
这章主要把保留字说一下 JavaScript 把一些标识符拿出来用做自己的关键字.因此,就不能再在程序中把这些关键字用做标识符了: break delete function return typeo ...
- Oracle-decode函数
decode函数 简单例子:管理员登录Oracle select sid, username, decode(command, 0, 'None', 2, 'Insert', 3, 'Select', ...
- java命令行HPROF Profiler
The HPROF Profiler The Heap and CPU Profiling Agent (HPROF)是JAVA2 SDK自带的一个简单的profiler代理,它通过与Java Vir ...
- MarkDowdPad 破解
一部小心把markdown破解了,把破解后的主程序发出来吧,放到安装根目录即可.点击升级到专业,随意输入邮箱和8位注册码,确定后会显示失败,返回即可,然后你就会发现已经变成专业版了. 不知道博客园怎么 ...