Sunday, December 21, 2014

Render M materials with N lights

12:51 AM Posted by shihchinw No comments
在 hardware render pipeline 中,若現在場景內有 M 個材質(material)相異的物件與 N 盞燈, render 的方式會有幾種選擇?
  • single-pass, multi-light
  • multi-pass, multi-light
  • deferred shading

Single-pass, Multi-light

for each object:
  render object with all lights in one shader
此種作法是最單純且直接,但是此方式會連 hidden surface 也一併 shading ,造成運算上的浪費。此外,當光源數目 N 很大的時候,shader code 必須擴展進而去計算每盞光源的作用。但若是指令數超過 shader model 的限制時(視 shader model 而定),就不得不拆成多個 render pass。

Multi-pass, Multi-light

for each light:
  for each object affected by light:
    render target += BRDF(object, light)
這方式是將每盞燈光的所影響的結果累加於 render target,+= 的部分是透過 ping-pong 的方式在兩個 render target 之間作替換。然而 invisible surface 所造成的計算浪費仍舊沒有獲得解決之道,新增的 geometry pass 也在 vertex transform 與 setup 的部分帶來了額外的開銷。這部份的問題,雖然可以透過粗略的 front-to-back sorting 獲得一些抒解,但 deferred shading 卻對此問題有著更根本的解決方案(當然也會帶來其他的限制)。

Deferred Shading

for each object:
  render lighting properties to G-buffer
  for each light:
    render target += BRDF(G-buffer, light)
Deferred shading 之所以能解決 hidden surface 所造成的 shading 浪費,主要是因為它在第一階段先輸出 position, normal 與其他參數至 G-buffer。使第二階段的 lighting 運算能完全作用在 visible 的 fragment 上,同時也有助於降低 light/object 之間的相依性,藉此達到 render 效率的提升。一切看起來似乎都很美好,但故事就這樣結束了嗎?喔!不,故事才剛開始...