Unity5中的软阴影烘焙

Unity5中的软阴影烘焙,第1张

       此文分享在unity5中烘焙光照时关于软阴影的一些见解。光照烘焙是计算机图形学领域的一种技术,用于为计算量巨大的虚拟光照 *** 作生成纹理,称为光照贴图。光照贴图信息被烘焙到这些纹理中,用来展现就像受实时灯光影响的虚拟场景,而开销只是使用实时灯光的一小部分。通常结合烘焙光及实时光使用以创建更真实的虚拟环境。

观察灯光与环境中的物体交互时会发现,很明显阴影几乎不会完全平直。灯光以直线传播,但它几乎不可能无限小到可以产生完全平直的阴影。为了使场景看起来更加可信,如果软件支持就有必要考虑使用软阴影。此文将展示一些对比案例,以更好地理解如何烘焙软阴影及如何设置。虽然此教程着重于unity5,但这些内容同样适用于其它软件。

先来讨论下Unity中灯光的衰减,以及它如何加强场景中烘焙灯光的表现。为了更直观地解释软阴影,下面展示一张关于灯光的图片。这张图片很好的展示了阴影是如何随着距离的延伸变得更加柔和。看一下如何在Unity5中实现类似的效果。

创建测试环境

在研究不熟悉的技术或解决没把握的问题时,比较好的做法是新建工程进行尝试,这样能很好的避免影响到现有的工程。为了更好地理解Unity中的软阴影,我将新建工程做一个对比性的设置。

如果想继续实现这些效果,请遵循如下步骤。

1.新建Unity5项目并设为3D,依次点击Edit >Project Settings >Player将渲染路径更改为”Deferred”,颜色空间(Color Space)设置为 “Linear”。

2.通过禁用环境光亮度(Ambient Intensity)和天空盒(Skybox )让场景完全黑暗,这样就可以控制灯光对场景的影响。依次点击Window >Lighting按下图设置场景:

3.场景包含一个简单的面片(Plane)和一个立方体(Cube),为了将这些物体包含进灯光烘焙中,必须将它们设为静态(Static)。摄像机是可选的,如果场景包含摄像机,需要将背景设为黑色。说到摄像机,如果在Game和Scene视图中,立方体下方的阴暗处,最终的烘焙效果出现带状,可以通过在摄像机组件中打开HDR来解决这个问题。

4.最后,本例场景中的光源是点光。将点光源的Baking设置设为Baked,阴影类型(Shadow Type)设为Soft Shadows。所有这些设置完成后就可以开始测试了。

点光和聚光灯---烘焙的阴影半径

为了在Unity5中实现点光和聚光灯的光照衰减,需要将灯光的阴影类型设为软阴影。做以上 *** 作时会出现一个叫做阴影半径(Baked Shadow Radius)的变量。下面你将看到这些设置会如何影响光照烘焙的效果。

这些设置的目的是演示在Unity5中如何控制点光的软阴影。白色球体充当一个半径可视器,它对应烘焙的阴影半径均匀缩放。这意味着如果烘焙的阴影半径设置为0.5,这可通过将球体均匀缩放0.5表现出来。

方向光-烘焙阴影角度

方向光在虚拟场景中常用作日光。在将方向光做为场景中的日光前,有必要思考一下日光的特点。尽管光是直线传播的,太阳无限远,但下图的阴影也不会是完全平直的。

方向光可以使用烘焙阴影角度(Baked Shadow Angle)变量来表示软阴影的效果。仔细看下图了解不同设置的不同表现。

区域光

区域光在Unity5中才可烘焙,自带软阴影,只需按照下图所示进行瞄准和烘焙即可。将区域光放置在窗户外,可以很好的为室内场景再添一束光。

希望你看完本文后对软阴影有了一定概念,并学会了如何在Unity 5中创建及应用软阴影以增强场景的真实感。

原文链接: http://www.gamasutra.com/blogs/TinoVanderKraan/20151120/259935/Baked_Sof...

1.实时光照

实时光照属于真阴影,一般来说效果是最好的,但是开销也是最大的

2.脚底放置阴影面片模拟阴影

一般是无光照小型游戏的常见解决方案,开销较小,表现形式较差,面片是死的,无法根据人物动作变化

3.通过顶点shader变换成面片模拟阴影

如上图Gif所示

优点 : 表现形式上比方案2强,阴影可跟随顶点动画,开销比实时阴影要少

缺点 : 无法在 "非平面" 使用,比如在斜坡上,会穿帮

4.通过 Projector 或者 Decal 来模拟投射阴影

优点 : 表现效果更近一步,也可以在斜面上进行投影了

缺点 : 开销也更近一步

思路

1.我们通过2个Pass来渲染,第二个Pass正常渲染角色,第一个Pass模拟渲染阴影

2.我们需要将模型的所有 Y 值压到地面高度,这样就形成了一个头顶俯视图的阴影效果

3.我们再对 XZ 方向进行偏移,偏移量根据模型原先 Y 值高度为参考做插值

4.阴影的方向我们规定在 XZ 平面上 (X=0,Z=1) 为初始默认方向,以这个向量为基准进行旋转

5.旋转我们可以通过 二维旋转矩阵 来计算

过程中遇到的问题:

1.我在对以Y值高度为参考做XZ方向偏移的插值的时候,由于Y值低于地面取到了负值而这些值有没有被裁剪掉就导致了上图的问题,然后首先想到的是对插值做 max(0,插值结果),然后我们又得到了如下结果

2.上面第一个问题好像是解决了,但是实际上人物到地面以下之后人物还是有一个顶部投影的值,即XZ平面未偏移的结果,那么解决方案自然而然的想到,通过 Y 值和地面的值比较,Y值如果小于地面那么就Clip掉当前片段 Clip( Y值_ws - 地面Y高度_ws) , ws表示世界空间,那么实际上第一个问题也就处理掉了,无需多一步max函数了

3.紧接着,我们需要考虑降低阴影的透明度,但是出现上图问题,导致该问题的原因是,由于将人物顶点变换的同一个Y值后,部分片段是有重叠,就相当于如果直接把人压扁后那么就前胸贴后背,我们需要的是前胸或者后背只渲染依次就可以了,那么自然想到了模板测试Stencil,模板缓存的初始值都为0,我们将渲染阴影通道的Pass中的Ref引用值设为1,当我们的值 [大于] 模板缓存的值就替换,那么假设我们前胸进来一看发现缓冲区里的值为0,自己是1,然后进行替换,但是后背再进来发现已经是1了,不满足[大于]的条件了,所以就不写入了...

4.紧接着,又得到了一些奇怪的问题,在我已经将Blend模式设置为SrcAlpha OneMinusSrcAlpha后发现将影子的颜色Alpha值设置为拖动到0的时候并不会让影子消失,而是颜色更深了,很奇怪,想了很久不知道为什么,但是左边就很正常,左边人物和右边人物的shader唯一差别在于:

左边Shader的两个Pass先渲染人物再渲染阴影

右边出错的Pass先渲染阴影再渲染人物

然后我尝试将左边Shader中的Pass1删除掉,只渲染阴影,我发现它也不正常了...真特娘的奇怪,而且FrameDebug逐Draw渲染的结果也有点奇怪

然后改变摄像机颜色后,发现阴影颜色跟随摄像机颜色改变,于是我发现那可能那不是阴影而是透过去的背面,于是我在地面下方放置了一个小球,然后发现确实是看到地面下方的内容了,再通过FrameDebug调试发现问题所在,将镜头拉近的时候,先渲染的小球,然后紧接着就渲染了右边人物的阴影通道,所以结果是不正确的,因为我们需要阴影渲染在地面上,但是地面还没有渲染,所以我们Blend的时候是和背后的天空盒还有小球混合了导致阴影出错的,但是问题又来了,为什么左边的就没有问题呢,原因是这样的...

地面,左侧人物,右侧人物...由于他们的渲染队列Queue都是Geometry,且值都为2000,所以他们在渲染的时候会随着距离摄像头的远近而可能出现不同的Draw绘制顺序,但是针对多通道的Shader

所以,第一个通道Pass会随着摄像机的远近而变化,但是由于左侧人物的阴影绘制是放在了第2个通道里的,所以绘制的时候,地面是肯定已经绘制完了的,而右侧人物第1个Pass就是阴影,具体是绘制在Plane之前还是之后会随着摄像机远近而不同

该问题解决方案 :

1.将右侧的阴影通道放到第二个Pass中渲染

2.手动修改右侧Shader的渲染排序"Queue" = Gemotry+1" ,让它排在Plane后面渲染

3.将"Queue" = "Transparent",这个实际和2相同,但是不清楚原理的情况下比较容易想到这个方案


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/bake/11782164.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-18
下一篇 2023-05-18

发表评论

登录后才能评论

评论列表(0条)

保存