About Render Path

目录
  • Forward Shading
    • 优化Overdraw – Early Z
    • 优化Overdraw – Pre Z
  • Deferred Shading
    • Deferred Lighting
  • Tile Based Shading
    • Tile Based Deferred Shading
    • Forward+
  • Cluster Based Shading
  • 对比
  • 高效的渲染算法要点总结
Forward Shading
  • 伪代码
    foreach object in scene 
        foreach light in scene
            do shading(object, light)
  • 优点
  1. 算法好理解
  2. 支持MSAA
  3. 支持半透明物体
  • 缺点
  1. 算法复杂度高 O(m*n)
  2. Overdraw显著
  • 适用场景
  1. 光源不多;场景简单的场景
优化Overdraw – Early Z
  • 对于不透明物体提早深度测试,来减少PS阶段消耗。
  • 但是对于一个大物体和很多小物体的情况会排序失败;并且可能因为开启了AlphaTest等原因打断Early Z。
优化Overdraw – Pre Z
  • 伪代码
    // Pass 1
    foreach object in scene 
        if object.z < depthBuffer.z 
            do depthOnly(object)

    // Pass 2
    foreach object in scene 
        if object.z == depthBuffer.z 
            foreach light in scene
                do shading(object, light)
  • 缺点
  1. DrawCall增加
  2. VS计算开销增加
Deferred Shading (光照计算与物体解耦
  • 伪代码
    foreach object in scene 
        if object.z < depthBuffer.z 
            do writeGBuffer(object)

    foreach pixel in screen
        do readGBuffer(pixel)
        foreach light in scene
            do shading(pixelGBuffer, light)
  • 优点
  1. 支持更多灯光
  2. 没有Overdraw
  3. 光照计算与物体解耦,算法复杂度低 O(m+n)
  4. 对各种屏幕空间算法友好(各种后处理
  • 缺点
  1. 带宽高
  2. 无法处理半透明物体
  3. 无法支持很多材质
  • 适用场景
  1. 光源数量多
  2. 场景简单
  3. 材质较为单一
Deferred Lighting

Deferred lighting approaches

Tile Based Shading (基于tile优化灯光裁剪
  • 伪代码
    // method 1 - screen space
    foreach tile in screen
        foreach light in scene
            if light in this tile
                tile += light

    // method 2 - frustum space
    foreach tile in screen
        get boundingbox for this tile in frustum
        calculate zmin and zmax
        foreach light in scene
            if light.z in zmin and zmax
                tile += light

    do shading(tiles)
  • 如何确定tile的大小?
  1. 与GPU中的线程组中的线程数大小相关
  2. 应该是64的倍数
  3. 不超过1024(DX11上的数,不同的硬件数据不同
  • 优点
  1. 支持的光源数量多
  2. 可扩展性强
  • 缺点
  1. 深度不连续
  2. 光源剔除不精确
Tile Based Deferred Shading (Tile Based Shading + Deferred Shading
  • 伪代码
    // writeGBuffer
    foreach object in scene 
        if object.z < depthBuffer.z 
            do writeGBuffer(object)

    // light culing
    // method 1 - screen space
    foreach tile in screen
        foreach light in scene
            if light in this tile
                tile += light

    foreach tile in screen
        foreach pixel in tile 
            do readGBuffer(pixel)
            foreach light in tile
                do shading(pixelGBuffer, light)
Forward+ (Tile Based Shading + Forward Shading
  • 伪代码
    // pre z - pass 1
    foreach object in scene 
        if object.z < depthBuffer.z 
            do depthOnly(object)

    // light culing
    // method 1 - screen space
    foreach tile in screen
        foreach light in scene
            if light in this tile
                tile += light

    // pre z - pass 2
    foreach object in scene 
        if object.z == depthBuffer.z 
            foreach light in tile
                do shading(object, light)
Cluster Based Shading (基于tile和深度优化灯光裁剪
  • 伪代码
    // build clusterArray

    // light culling
    foreach cluster in clusterArray
        foreach light in scene
            if light in this cluster
                cluster += light

    do shading(clusterArray)
  • Cluster 的构建

    • 基于视线方向,将Tile做深度上的切割(每一个三维的块叫Cluster
    • 不同深度的选择方法
      1. 基于NDC:近平面Cluster小且密,远平面大且疏,非线性
      2. 基于ViewSpace:近平面Cluster大且疏,远平面小且密
      3. 基于指数:用指数抵消基于NDC的非线性
  • 优点

  1. 支持大规模光源数量
  • 缺点
  1. Cluster构建有固定开销
  2. 光源裁剪开销大
  • 适用场景
  1. 适合光源数量多的场景
  2. 对移动端不友好
高效的渲染算法要点总结
  • 适当的网格管理和剔除操作
  • 减少不必要的像素着色器调用
  • 减少着色期间的光照计算数量
  • 减少不必要的IO读写

Add a Comment

您的电子邮箱地址不会被公开。 必填项已用*标注