阴影大小计算

Unity 计算阴影贴图大小的方法如下:

首先计算屏幕上灯光的“覆盖范围”。以下是灯光在屏幕上照亮的矩形范围:

  • 方向 (Directional) 灯照亮整个屏幕。
  • 聚光 (Spot) 灯照亮灯光投射到屏幕的圆锥型包围矩形。
  • 点 (Point) 光源照亮灯光投射到屏幕的球形包围矩形。

然后选择该范围的宽和高的较大值,调用像素大小。

处于“高 (High)” 阴影分辨率时,阴影贴图的大小为:

  • 方向 (Directional) 灯:NextPowerOfTwo( pixel size * 1.9 ),但不超过 2048。
  • 聚光 (Spot) 灯:NextPowerOfTwo( pixel size ),但不超过 1024。
  • 点 (Point) 光源:NextPowerOfTwo( pixel size * 0.5 ),但不超过 512。

当图形卡有 512MB 或更高显存,阴影贴图的上限增加(方向 (Directional) 灯为 4096,聚光 (Spot) 灯为 2048,点 (Point) 光源为 1024)。

处于“中 (Medium)” 阴影分辨率时,阴影贴图的大小比“高 (High)” 阴影分辨率的贴图小两倍,“低 (Low)” 阴影分辨率时比“高 (High)” 阴影分辨率的贴图小四倍。

表面看来点 (Point) 光源的低限值是因为使用了立方体阴影贴图。这就意味着处于该分辨率的六面立方体贴图必须在显存内。渲染时也非常耗费性能,因为潜在阴影投射器必须渲染到最多六面立方体贴图上。

接近显存限值运行时的阴影大小计算

接近显存限值运行时,Unity 会自动降低以上计算的阴影贴图分辨率。

一般来说,屏幕内存(后台缓冲、前台缓冲、深度缓冲)和渲染纹理内存位于显存中。Unity 使用这两项来确定阴影贴图允许的内存使用量。根据以上计算的大小分配阴影贴图,其大小将减少,直至适合总显存 (TotalVideoMemory) – 屏幕内存 (ScreenMemory) – 渲染纹理内存 (RenderTextureMemory) / 3。

假设所有常规纹理、顶点数据和其他图形对象可从显存中换出,阴影贴图可使用最大 VRAM 总显存 (TotalVideoMemory) – 屏幕内存 (ScreenMemory) – 渲染纹理内存 (RenderTextureMemory) / 3。但屏幕和渲染纹理占用的确切内存量无法确定,某些对象无法换出。如果所有纹理总是换进换出,性能会变得很差。因而 Unity 不允许单个阴影贴图超过“一般可用”显存的三分之一,这规则实践起来效果很好。