之前我的所有文章中使用的光線演算法都是Tri-Ace的版本 ,但上一篇測試camera曝光的時候發現有些不對勁,粗糙物體上的反光太強,簡直不能見人。當時只能將所有物體表面設定得光滑一點來因應,搞得每樣東西看起來......更光滑了。
後來去找了Mitsuba這個免費軟體做為參考點,測試我的程式和Mitsuba生成的結果差多少,結果發現我的程式中反光確實都過於強烈。Tri-Ace版演算法可能本來就有這個特性,也有可能我有哪裡寫錯了,但是我把Tri-Ace的文件翻出來比對還是找不出錯在哪裡。
我實作寒霜的版本後發現比較接近Mitsuba的結果,這讓我下定決心將光線計算全部改成寒霜的版本。寒霜版的演算法還考慮到表面上的微小突起的高度,越粗糙的表面越會受此影響。再加上採用Disney的diffuse演算法,結果就是以大角度觀看粗糙表面的時候,能看到更多光被彈回。下圖為演算法修改後的畫面:
後來去找了Mitsuba這個免費軟體做為參考點,測試我的程式和Mitsuba生成的結果差多少,結果發現我的程式中反光確實都過於強烈。Tri-Ace版演算法可能本來就有這個特性,也有可能我有哪裡寫錯了,但是我把Tri-Ace的文件翻出來比對還是找不出錯在哪裡。
我實作寒霜的版本後發現比較接近Mitsuba的結果,這讓我下定決心將光線計算全部改成寒霜的版本。寒霜版的演算法還考慮到表面上的微小突起的高度,越粗糙的表面越會受此影響。再加上採用Disney的diffuse演算法,結果就是以大角度觀看粗糙表面的時候,能看到更多光被彈回。下圖為演算法修改後的畫面:
▲Color grading前
▲Color grading後
點光源作完後就能將演算法推廣到ambient BRDF上,不過這次只製作了BRDF的積分,Environment map的積分則暫時擱置。這回不用CubeMapGen來處理env map的原因是希望將來能動態生成light probe,所以打算自己寫程式來處理。不過因為不想繼續用OpenGL,而Vulkan又還沒出,所以這回只有BRDF是新的,等於IBL只做了一半。
▲粗糙表面的邊緣比起舊版反射更多光線
▲套用新演算法的米卡莎
接下來的部分建議點開圖片比較能看出和上圖有何差異,
寒霜版又考慮到光線的角度會因為粗糙度而變化,此處使用了簡單的近似法來計算,不考慮角度變化的話就會這樣:
▲不考慮粗糙度對光線角度的影響
之前偷懶把SSAO的結果直接乘上specular light,但specular light通常比diffuse要強許多,因此即使乘上AO項還是能看到反光。這次翻新就順便一起套用寒霜的方法,下圖是關閉Specular Occlusion的結果:
▲關閉Specular Occlusion之後,可看到脖子附近圍巾的反射光無法只以AO壓制住
至於與米卡莎與skybox的交界出現AO,代表我得更新SSAO演算法了...
至於與米卡莎與skybox的交界出現AO,代表我得更新SSAO演算法了...
題外話,話說我原本想實作GPU Pro 5的screen-space reflection,但是文章裡面講的東西、程式碼還有示意圖都搭不太起來,所以擱置許久。今天閒晃時看到論壇上也有些人摸不著頭緒,我感到很欣慰...(毆