DX杂记之延迟渲染

  • 描述:这次来记录一下延迟渲染的部分,说是延迟渲染,其实包括了 Deferred Rendering,Light PrePass Deferred Rendering,Tile Based Deferred Rendering 等三部分,大体的做法都是相似,都是通过多个 Render Targets 存储图形表面的信息和光照信息至 GBuffer,然后计算,这几种方式不断改进是为了平衡gbuffer 占用的内存与对应的性能优化操作。
  • 为什么需要用延迟渲染,前向渲染的缺陷:
    • 复杂度高O(m*n),每一个 Light 要对所有图形计算光照,所以在灯光多的情况下性能很差
    • 延迟渲染通过 Multi Pass,将所有的信息合并起来计算,复杂度O(m+n)
  • Classic Deferred Rendering
    • 步骤(Passes):
      • 需要四个 Render Targets,将 Position,Normal,Diffuse,Specular(Albedo 和 Power)写入GBuffer
      • 绘制一个 Quad 覆盖屏幕,将四个 Target 通过纹理传入该 Quad 的 Shader,以及相机位置和灯光位置,遍历所有的Light,在此为每个 Light 对每一个像素进行光照计算
    • 缺点:
      • 全屏的所有像素,GBuffer 存储的内存带宽消耗很大,所以需要平衡性能
  • Light PrePass Deferred Rendering
    • 步骤(Passes):
      • 需要两个 Render Targets 存储 Normal 带上 Specular 的 Power 信息 和 Position 信息至 GBuffer
      • 绘制一个 Quad,遍历每一个灯光,利用传入的 Position 和 Normal 属性累积计算每个像素的光照信息,计算光照信息所需要的几个向量  L,V,N,H 都可以由 Position,Normal 和 CameraPosition 得到,
      • 绘制 Quad,再次绘制一次所有图形,根据之前计算所有灯光得到光照信息和当前图形的材质信息去计算最终的光照结果
  • Optimizations
    • 描述:这是对于 Classic Deferred Rendering 的一种优化手段
    • 优化途径:
      • 球坐标系与笛卡尔坐标系的转换,三维向量可以变为二维向量
      • 使用更短字节数的类型,比如用R8G8B8A8代替R32G32B32A32
      • Position 优化:由于它是高精度要求的,可以使用 深度信息重建位置信息的方式
        • 第一种 直接保存距离
          • 计算像素到相机的距离 viewDistance,写入贴图中
          • 在计算光照的 Pass 中,根据深度值,ViewRay = normalize(PositionWS - CameraPos) 和 CameraPos 可以在任何坐标系中重建:CameraPos + ViewRay * viewDistance
        • 第二种 在 View Spce 中 z 与 视锥体对齐
          • 保存缩放因子 scale = farPlane / z,
          • ViewRay = Position.xyz;CameraPos + ViewRay * viewDistance
        • 第三种作为第二种的优化手段,在 Vertex Shader 中计算,比在 Pixel 中节约性能,不过用于体积空间,绘制Quad则没有区别
    • 裁剪测试:基于灯光的种类做裁剪测试,如果在灯光的影响范围内则通过测试,否则不通过来节约性能。
      • 做法:基于屏幕空间的包围区域
    • 模板测试:绘制GBuffer 的时候开启写入,然后再渲染光照的时候开启比较,如果等于引用值则保留,不然就裁剪掉
      • light masking:特定的光照影响特定的物体
    • 分块延迟渲染
      • 主要思想则是把屏幕分拆成细小的栅格,例如每 32 × 32 象素作为一个分块(tile)。然后,计算每个分块会受到哪些光源影响,把那些光源的索引储存在分块的光源列表里,最后,逐个分块进行着色,对每像素读取 G-buffer 和光源列表及相关的光源信息
      • G-buffer的数据只会被读取1次且仅1次
      • 写入 color buffer也是1次且仅1次,大幅降低内存带宽用量
      • 不过,这种方法需要计算光源会影响哪些分块,这个计算又称为光源剔除(light culling),可以在 CPU 或 GPU(通常以 compute shader 实现)中进行。用GPU计算的好处是,GPU 计算这类工作比 CPU 更快,也减少 CPU/GPU 数据传输。而且,可以计算每个分块的深度范围(depth range),作更有效的剔除。

猜你喜欢

转载自blog.csdn.net/weixin_42561030/article/details/82085662
今日推荐