關於Wrap Lighting與面板SSS

2021-08-03 10:23:47 字數 1415 閱讀 6836

最近在弄手機上的sss**,查資料的時候碰到wrap lighting這個概念,這裡簡單總結一下。

這個說白了就是half lambert的高階版,或者說half lambert是wrap lighting的乙個特例。wrap light直譯的話就是用光包裹住整個物體,讓原來黑暗(即n*l<=0)的部分亮起來的意思。如果是標準lambert的話,有很大一部分地方是黑的,讓整個物體顯得比較平,而wrap light會有乙個光的過度,並且"soft「整個物體的感覺。如下圖:

引用自valve的half life 2引擎技術分享,最右邊的上下兩張圖可以看出來,使用half lambert效果更好一點。

wrap light公式為:

float

diffuse = max

(0, dot

(l, n));

float

wrap_diffuse = max

(0, (dot

(l, n) + wrap) / (1 + wrap));

所以half lambert相當於wrap值為1的情況,具體專案中,wrap值會按照美術的感覺來走。

早期的**材質就是用這樣的方法來製作的,並沒有什麼道理可講,就是粗暴的覺得這樣很好看而已。其中還包括,使用wrap後的n*l來去取樣乙個一維的貼圖,類似下面的圖:

下面的圖是使用效果,c圖就是用了這樣的取樣貼圖:

在黑白交接的地方給一點紅色,用於模擬**的感覺,這個也是現實中出現的情況。所以最後diffuse的公式變成了wrap後的n*l再加上這個取樣過後的scatter數值,或者直接是用取樣後的數值作為diffuse數值(當然這個取樣貼圖本身需要好好製作)。具體公式每個遊戲都不一樣,但是原理就是這樣:使用wrap light的diffuse。

這樣的演算法還是很實用的,但是在現在,已經有點不夠用了,其中原因有:在pbr大行其道的今天,這種完全沒有能量守恆的演算法會讓整個物體過於明亮,所以有大牛就據此修改了wrap light,讓其保證能量守恆:

並且,在現如今都使用sh作為環境光的情況下,環境光如何使用wrap light呢:

還有,如果這個演算法是用於模擬**的sss效果的話,並沒有考慮到真正

的skin diffusion profiles和**表面的curvature,僅僅是看起來有點像的樣子,這些都需要進行修改:

上面這篇文章是在forward rendering的情況下如何做**sss的,和大行其道的後處理sssss並不一樣,效果也還不錯,order 1886,nv的facework外掛程式均使用了這個演算法。

引用:1.

2. 

關於兄弟與朋友

最近很忙很忙,星期五晚上幾乎徹夜加班,沒有一段完整的時間讓自己靜下心來思考,說說心裡話。有些東西有必要記下,因為時間長了,會遺忘的,甚至連回憶也留不下。很多年都沒有坐下來認真動筆寫字了,包括前幾篇寫的,我是用鍵盤敲出來的。前幾天想寫 one fine day,考慮到坐在電腦前沒有那麼多時間,我選擇用...

關於工作與生活

普通人 我發現中國人的勵志和國外的勵志存在非常大的不同,中國的勵志比較鼓勵人立下大志願,臥薪嘗膽,有朝一日成富成貴。而國外的勵志比較鼓勵人勇敢面對現實生活,面對普通人的困境,雖然結果也是成富成貴,但起點不一樣,相對來說,我覺得後者在操作上更現實,而前者則需要用999個失敗者來堆砌乙個成功者的故事。我...

關於errno與perror,strerror函式

為什麼,要強調errno看起來好像是乙個整形變數呢?因為有的標準 如iso c 只規定了errno的作用,而沒有規定它的實現方式,它可能被定義成乙個變數,也有可能被定義成乙個巨集,這個具體要看編譯器自己的實現。早些時候,posix.1曾把errno定義成extern int errno這種形式,但現...