接着上篇文章,我们实现了SSR效果。

其中的在屏幕空间进行光线追踪的方法是通用的。借此我们再实现一种屏幕空间的效果,即屏幕空间阴影。

文中的图片来自Catlike coding
http://catlikecoding.com/unity/tutorials/rendering/part-7/

完成的工程: https://github.com/yangrc1234/ScreenSpaceShadow

原生阴影

首先我们要了解一下原生的阴影是怎么实现的,这里我们只讨论Directional Light。

首先,我们将Directional Light视作一个相机,对整个场景进行绘制。我们只需要其中的深度信息。(如果你尝试过自己写一个可以产生阴影的Shader,应该知道这个绘制是通过调用ShadowCaster类型的pass来实现的)

通过这样渲染的一张ShadowMap,在我们渲染主相机的画面时,对每一个像素,我们获得它的世界坐标,然后将该世界坐标转换到Directional Light的坐标系下,采样对应的ShadowMap中的点。如果我们采样出来的深度,大于该坐标的深度,我们认为该点没有被阻挡。否则认为该点处于阴影中。

这就是ShadowMap方法的简单描述。在Unity的Directional Light流程中,采用的是Cascade ShadowMap,此时会有若干个不同分辨率的ShadowMap被生成,分别对应与相机距离不同的区域,这样可以做到相机较近的区域,分辨率较高,阴影质量更好;较远的区域分辨率较低,质量一般(但是远了你也看不出来)。


Cascade ShadowMap示例

不同于其他类型的光源,在主相机渲染时,我们求一个点的光照度,并不是直接去转换坐标系然后采样ShadowMap。在Directional Light流程中,在主相机渲染之前,Unity会将Cascade ShadowMap转化为一张屏幕空间的阴影贴图(Screen Space Mask,当然该过程也需要转换坐标系去比较深度等等)。然后在主相机渲染时直接取采样这张屏幕空间阴影贴图获得光照度。


屏幕空间的阴影贴图示例

我们待会儿会通过操作这张屏幕空间阴影来实现我们的效果。

这种阴影实现毫无疑问是目前的主流方法。但是它也有不少问题,比如Shadow Acne现象。我们之前说到,判断一个点是否在阴影中,是通过深度比较进行的。但是我们要判断一个像素是否在阴影中时,因为深度贴图的精度问题,可能会出现被周围的差异极小的像素遮挡的情况。

屏幕空间阴影

屏幕空间阴影基于屏幕空间光线追踪实现阴影效果。

最大的好处就是让不参与ShadowMap绘制的物体也可以投出阴影。

而且作为一个屏幕效果,其效率与场景复杂度无关。

在绘制大量的小型物体时,这一优势是很明显的。

下图是一个效果关闭开启的对比。图中的草是Unity的Terrain系统绘制的,默认不开启阴影。可以看到开启屏幕空间阴影后画面提升明显。

在Unity中实现屏幕空间阴影(1)的更多相关文章

  1. 在Unity中实现屏幕空间阴影(2)

    参考文章: https://www.imgtec.com/blog/implementing-fast-ray-traced-soft-shadows-in-a-game-engine/ 完成的工程: ...

  2. 在Unity中实现屏幕空间反射Screen Space Reflection(4)

    第四部分讲一下如何在2D屏幕空间步进光线. http://casual-effects.blogspot.com/2014/08/screen-space-ray-tracing.html 中的代码感 ...

  3. 在Unity中实现屏幕空间反射Screen Space Reflection(1)

    本篇文章我会介绍一下我自己在Unity中实现的SSR效果 出发点是理解SSR效果的原理,因此最终效果不是非常完美的(代码都是够用就行),但是从学习的角度来说足以学习到SSR中的核心算法. 如果对核心算 ...

  4. 在Unity中实现屏幕空间反射Screen Space Reflection(3)

    本篇讲一下相交检测的优化.有两个措施. 线段相交检测 之前的检测都是检测光线的终点是否在物体内.我们可以尝试检测光线的线段是否与物体相交. 比如说有一个非常薄的物体,光线差不多垂直于它的表面.如果用普 ...

  5. 在Unity中实现屏幕空间反射Screen Space Reflection(2)

    traceRay函数 在上一篇中,我们有如下签名的traceRay函数 bool traceRay(float3 start, float3 direction, out float2 hitPixe ...

  6. 关于Unity中的屏幕适配

    一.Game视图的屏幕分辨率可以先自定义添加,供以后选择,以下是手游经常用到的分辨率: 1.1136X640,iPhone5 2.1920X1080,横屏,主流游戏都是这个分辨率 3.1080X192 ...

  7. 浅谈unity中gamma空间和线性空间

    转载请标明出处:http://www.cnblogs.com/zblade/ 一.概述 很久没有写文章了,今天写一篇对gamma空间和线性空间的个人理解总结,在查阅和学习了各个资料后,算是一个个人笔记 ...

  8. 【Unity技巧】Unity中的优化技术

    http://blog.csdn.net/candycat1992/article/details/42127811 写在前面 这一篇是在Digital Tutors的一个系列教程的基础上总结扩展而得 ...

  9. Unity中的优化技术

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

随机推荐

  1. inux下mysql的root密码忘记解决方法

    1.首先确认服务器出于安全的状态,也就是没有人能够任意地连接MySQL数据库. 因为在重新设置MySQL的root密码的期间,MySQL数据库完全出于没有密码保护的 状态下,其他的用户也可以任意地登录 ...

  2. 敏捷开发之Scrum站立会议

    Scrum是迭代式增量软件开发过程,通常用于敏捷开发.站立会议通常指Scrun方法中的每日站立会议.顾名思义,是每天以站姿的方式召开的会议.以下从功能及要点方面对其进行解释说明: 功能:     1. ...

  3. HDU 2105 The Center of Gravity

    http://acm.hdu.edu.cn/showproblem.php?pid=2105 Problem Description Everyone know the story that how ...

  4. 安恒杯-babysql

    1. 库名 ?id= and extractvalue(,(select group_concat(0x3a,schema_name) from information_schema.schemata ...

  5. 使用java程序模拟页面发送http的post请求

    在web应用程序中,一般都是通过页面发送http的post请求,但也可以使用java程序来模拟页面发送请求,代码如下: import java.io.BufferedReader; import ja ...

  6. hash值

    任何类都继承public int hashCode()方法,该方法返回的值是通过将该对象的内部地址转换为一个整数来实现的,hash表的主要作用就是在对对象进行散列的时候作为key输入.我们需要每个对象 ...

  7. MySQL 分组排序问题

    SQL好久不写了,有些生疏了,一个分组排序问题想了快半天,整理下. 学生表 CREATE TABLE `t_student` ( `id` bigint(20) NOT NULL AUTO_INCRE ...

  8. 【移动端debug-2】Flexbox在移动端的兼容实践

    最近在项目中用到了flexbox,总结一下使用心得. 一.什么是flexbox,干嘛使的? 曾几何时,我们特别希望能像word一样,在排版时有个分散对齐选项(平均分配子元素宽度)这样我就可以任意在父元 ...

  9. 深入理解JVM一内存模型、可见性、指令重排序

    一.内存模型 首先我们思考一下一个java线程要向另外一个线程进行通信,应该怎么做,我们再把需求明确一点,一个java线程对一个变量的更新怎么通知到另外一个线程呢?我们知道java当中的实例对象.数组 ...

  10. 【刷题】洛谷 P3807 【模板】卢卡斯定理

    题目背景 这是一道模板题. 题目描述 给定\(n,m,p( 1\le n,m,p\le 10^5)\) 求 \(C_{n+m}^{m}\ mod\ p\) 保证 \(p\) 为prime \(C\) ...