unity3d软阴影和硬阴影的原理_阴影生成技术原理(软渲染笔记十)

unity3d软阴影和硬阴影的原理_阴影生成技术原理(软渲染笔记十)_第1张图片

回顾:

之前提到着色,着色是局部的现象,就只考虑着色点自己,考虑光源,考虑摄像机,我们要算出它的着色完全不需要考虑其他物体,甚至这个物体的其他部分对这个着色点的影响(比如AO),而事实上来说不对,因为有其他物体当在着色物体和光源之间,那它就会挡住光线,光源就到达不了着色部分,自然算出的结果就是黑色,这就是为什么会有阴影,我们之前的着色解决不了阴影,那么我们现在来解决这个问题,我们限制在光栅化里面,人们发明了解决这个阴影问题的方法,就叫做Shadow mapping,对应的结构叫做shadowmap

阴影能给人一种物体和物体接触的感觉,就不会感觉是飘在空中。

内容:

Shadow Mapping(阴影贴图生成原理以及存在的问题)

Shadow Mapping:

unity3d软阴影和硬阴影的原理_阴影生成技术原理(软渲染笔记十)_第2张图片

unity3d软阴影和硬阴影的原理_阴影生成技术原理(软渲染笔记十)_第3张图片
Shadow Mapping它本质是图像空间的做法,所谓图像空间是什么意思?这里只要我用了shadowmapping,在生成阴影的这一步我是不需要知道场景的几何信息的。

会出现的问题:

shadowmapping会产生走样现象。

shadowmapping最重要的思想

如果有的点不在阴影里,你又能看到这个点,说明你可以从摄像机看到这个点,并且光源也可以看到这个点,这个才不在阴影里。如果这个点在阴影里,就说明你看得到这个点,但是光线看不到这个点。这就是阴影图观察到最重要的一个现象,利用这个现象就可以把阴影做出来。

我们要说的是如何处理一个点光源投射的阴影,要么在阴影里,要么不在阴影里,非0即1,我们把这种叫做硬阴影,之后还有一种软阴影。

两步操作:

从光源看向场景,就是说比如说有一个点光源,我们就虚拟的放了个相机在点光源处,然后对准整个场景,然后做一遍光栅化,就可以得到这个光源看到什么,生成一张图,这个图我们不用做着色,我们把这个不同位置看到的点对应的深度记下来。

unity3d软阴影和硬阴影的原理_阴影生成技术原理(软渲染笔记十)_第4张图片

第一步操作:

从光源看向场景记录你看到的任何点它的深度是多少,也就是说我们只需要它的速度图。

unity3d软阴影和硬阴影的原理_阴影生成技术原理(软渲染笔记十)_第5张图片

第二步操作:

我们从真正的眼睛或者说摄像机,再次看向这个场景,我们会看到另外一些东西,比如上图的两个黑点(其他点也会看到先以这个为例),当我们看到偏左侧的点的时候,做这么一个操作:把它投影回光源(使用虚拟相机)看到的成像平面上,什么意思呢:也就是说如果我从光源看这个点它应该出现在图像上的哪一个位置上,就是这么一个意思。把它投影回图像上就可以知道它在图像的哪一个像素上,就可以知道我记录了这个点多长的深度,同样也可以计算这个点到光源的深度,这两个深度肯定是一致的,那说明这个点完全可以被所看到的,可以被眼睛看到也可以被光源看到。

unity3d软阴影和硬阴影的原理_阴影生成技术原理(软渲染笔记十)_第6张图片
我们看到里面的那个点,同样可以投影回虚拟相机图像上,目前这个点实际的深度和我们从虚拟相机看到的深度是不一样的,这就说明这个点一定是虚拟相机看不到的点,光源看不到这个点,那不就是在阴影中吗,所以 Shadow Mapping就是这样一个道理。

总结

分两步,它会做两次不同的投影,第一次我认为光源处有一个虚拟相机并且有一个虚拟的图(不同位置和不同方向我能看到的深度)。第二次从实际场景的相机出发,然后再去渲染整个场景,渲染场景中的这些不同的点我都重新投影回光源,然后我就知道我应该在哪个像素上,也就是说光源之前成像出来的深度图的哪个像素上去寻找这个点,然后我就 会比较之前记录的深度到底是和我当前看到的这个点是否一致,还是不一致

实际的做法中:

unity3d软阴影和硬阴影的原理_阴影生成技术原理(软渲染笔记十)_第7张图片
有阴影和没阴影的区别

第一步:

unity3d软阴影和硬阴影的原理_阴影生成技术原理(软渲染笔记十)_第8张图片
从光源的位置看过去

unity3d软阴影和硬阴影的原理_阴影生成技术原理(软渲染笔记十)_第9张图片
我们记录的是深度,只需要记录深度。

unity3d软阴影和硬阴影的原理_阴影生成技术原理(软渲染笔记十)_第10张图片

第二步:

记录从观察相机所看到的点,再把它连到虚拟相机,得到第二套深度值。

最后通过深度对比得到阴影。

unity3d软阴影和硬阴影的原理_阴影生成技术原理(软渲染笔记十)_第11张图片
当我从实际相机看向场景的时候,我们会看到上图这样的几何形状,这些几何形状在不同的位置打到不同的像素,每一个像素都去连一根光线,连到光源上去或者说每一个像素对应的实际位置都投影回光源生成的shadowmap上,然后就可以知道在哪一个shadowmap上的哪一个像素可以找到这个方向,然后就可以对比在shadowmap上我记录的深度和实际这个点与光源的距离或者说深度它们之间的关系。

判断精度问题:

如上图会有数值精度的问题,一个解决方法,不判断是否相等,判断大小,实际距离大于已经记录的距离,那我就认为这个点在阴影里,这样也仍然解决不了问题,

阴影贴图的分辨率要多大?

如果分辨率特别小阴影就会产生锯齿,用比较大分辨率的阴影贴图开销会比较大。

总结:

核心思想:用Shadow Mapping做两趟光栅化,也就是渲染场景两遍,记录两趟深度信息,对于任何一个点来测试实际距离是不是和前面记录的距离是一样的,这样来判断是否在阴影中。这样的开销是比较大的。

unity3d软阴影和硬阴影的原理_阴影生成技术原理(软渲染笔记十)_第12张图片
得到广泛应用的ShaderMapping

unity3d软阴影和硬阴影的原理_阴影生成技术原理(软渲染笔记十)_第13张图片
阴影贴图常见的问题

unity3d软阴影和硬阴影的原理_阴影生成技术原理(软渲染笔记十)_第14张图片

硬阴影:

我们有一个点光源,照亮场景,边缘非常锐利(光源看不到的地方为黑色0,这里不考虑衰减的情况下光源可以看到的地方就为白色1)。

软阴影:

阴影还是有阴影,阴影会慢慢过渡到有阴影到完全没阴影,它不是非0即1,它有一个过渡性,越靠近物体根部的阴影越硬,这就是软阴影。 软阴影怎么来的: 其实软阴影是一种自然现象,在物理上软阴影称为半影,物理上区分阴影为两种:在一个地方完全看不到光源就叫本影,如果一些区域只能看到部分光源就叫做半影。 软阴影就是本影,半影和没阴影影响部分的过渡。

阴影程度取决于有多大的光源你能够看到,又说明另外一个问题,对于点光源来说是不可能出现软阴影的,如果有软阴影一定是因为光源有一定的大小。

关于具体软阴影的制作在后面的课程会讲。

下一章技术预告:光线追踪技术

unity3d软阴影和硬阴影的原理_阴影生成技术原理(软渲染笔记十)_第15张图片

为什么我们要用光线追踪,为什么不用光栅化的方法继续做?

因为光栅化有很多现象并不好做,光线追踪会提供更好的效果,代价后面慢慢分析。

你可能感兴趣的:(unity3d软阴影和硬阴影的原理_阴影生成技术原理(软渲染笔记十))