Table of Contents

阴影

初级 设计师 美术人员

阴影为场景带来重要的信息量和真实感。

阴影关闭 阴影开启
media/SceneNoShadows.png media/SceneWithShadows.png

只有平行光、点光源和聚光灯才能投射阴影。

阴影贴图

Stride 使用**阴影映射(Shadow mapping)**来渲染阴影。要理解阴影贴图,可以想象一个位于太阳中心的摄像机,让你从太阳的视角向下俯视。

光与影

太阳看到的一切都处于光照中。被隐藏在太阳视线之外的一切(即位于遮挡物之后)都处于阴影中。

从这个视角出发,Stride 会为每个投射阴影的光源创建一张阴影贴图(Shadow map)。它告诉我们每个可见像素距离光源有多远。当 Stride 渲染场景时,它会检查阴影贴图中每个像素的位置,以了解该像素是否能被光源"看到"。如果光源能看到该像素,该像素就被照亮;如果不能,该像素就处于阴影中。

例如,以下是 Stride 中包含的第一人称射击游戏示例中的阴影贴图,由平行光生成。

FPS 场景

FPS 场景阴影贴图

Note

注意,上例中的平行光创建了四张阴影贴图,每个级联一张。更多信息请参阅平行光页面。

阴影图集

每个投射阴影的光源的阴影贴图都保存在**阴影图集(shadow atlas)**纹理的某个区域中。你可以选择每个光源使用阴影图集的多大部分。阴影贴图越大,阴影质量越好,但留给其他光源阴影贴图的空间就越少。

更高质量的阴影(占用阴影图集的较大区域) 更低质量的阴影(占用阴影图集的较小区域)
高分辨率阴影 低分辨率阴影
FPS 场景阴影贴图 FPS 场景阴影贴图

通常,你应该给产生最明显阴影的光源分配更多空间。

阴影贴图中每个区域的大小取决于以下几个因素:

  • 基于 LightShadowMap.Size 属性的 shadowMapSizeFactor(/8、/4、/2、x1 或 x2)
  • 光源在屏幕空间中的投影大小(lightSize)
    • 对于平行光,lightSize 等于 max (screenWidth, screenHeight)
    • 对于聚光灯,lightSize 等于在目标聚光灯光锥处投影球体的投影大小
  • ShadowMapBaseSize 等于 1024

阴影贴图的最终大小按如下方式计算:

// 计算尺寸系数
var shadowMapSizeFinalFactor = shadowImportanceFactor * shadowMapSizeFactor;
// 将光源投影大小乘以尺寸系数
var shadowMapSize = NextPowerOfTwo(lightSize * shadowSizeFinalFactor);
// 钳制到最大尺寸
shadowMapSize = min(shadowMapSize, ShadowMapBaseSize  * shadowSizeFinalFactor);

如果你已经在场景中的某个光源上启用了阴影,但它没有投射阴影,请确保阴影图集中有足够的空间为该光源创建阴影贴图。更多信息请参阅疑难解答 — 光源不投射阴影。

另请参阅