日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Cocos 实用渲染实战(一):高性价比的人物皮肤渲染

發(fā)布時(shí)間:2024/8/26 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Cocos 实用渲染实战(一):高性价比的人物皮肤渲染 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

無(wú)論何等類型或規(guī)模,人物渲染都是項(xiàng)目中難以替代的重要組成部分。

有趣的是,對(duì)比世間萬(wàn)物,我們理應(yīng)對(duì)自己的身體更加熟悉,然而遠(yuǎn)自文藝復(fù)興以來(lái),無(wú)論在美術(shù)層面還是技術(shù)層面,人物渲染一直是一個(gè)令人撓頭的癢點(diǎn)——即便是從真人模特身上以尖端儀器掃描,并賦予極高貼圖精度的加持下,我們依然時(shí)常難以擺脫“恐怖谷”的困擾。

那么,有什么“奇技淫巧”,能夠讓我們?cè)?Cocos Creator 中更容易地產(chǎn)出可信的人物渲染效果呢?Cocos 布道師葡萄干將從皮膚、頭發(fā)、眼睛三個(gè)方面,同大家分享一套 Cocos 「次世代」人物渲染方案。
?


今天先從皮膚說(shuō)起。

確立目標(biāo)

我們將在 Cocos Effect 中編寫一個(gè)次表面散射著色器,用于表現(xiàn)人物渲染中的皮膚材質(zhì)效果。Cocos Creator 已經(jīng)自帶了標(biāo)準(zhǔn) Metal/Roughness 流程的 PBR 著色器,我們將在此基礎(chǔ)上增加新的 GLSL 代碼,這樣既可以使用所有 Metal/Roughness 流程的 PBR 功能和特性,同時(shí)也兼?zhèn)浯伪砻嫔⑸涞男Ч尸F(xiàn)。

所謂次表面散射,最直觀的視覺(jué)觀感是:物體內(nèi)部自發(fā)光由內(nèi)而外把物體照亮了,因此使用我們的著色器除了可以配合環(huán)境制作寫實(shí)的次表面散射效果之外,在特定數(shù)值的配合下,還可以產(chǎn)生更特別、更戲劇化的效果:
?


我們的著色器將配合兩張新貼圖 Thickness 和 Curvature 使用。這兩個(gè)名詞對(duì)于美術(shù),尤其是角色美術(shù)的同學(xué),想必是不陌生了。同時(shí),我們會(huì)附加上菲涅爾反射的功能,在 PBR 反射算法的基礎(chǔ)上賦予更靈活的調(diào)節(jié)選項(xiàng)。最后,我們會(huì)賦予一個(gè) Diffuse Profile 功能,其細(xì)節(jié)會(huì)在后文詳說(shuō)。目前我們只需要知道它是一個(gè)隨數(shù)值調(diào)節(jié)顏色輸出的功能。

那么,Cocos Effect 又如何使用呢?

快速上手

Cocos Effect 是 Cocos Creator 存儲(chǔ)著色器的一種格式,它使用 YAML 編寫。Cocos Effect 將頂點(diǎn)著色器、片元著色器和編輯器中的參數(shù)整合在一個(gè)文件中,并且會(huì)根據(jù)目標(biāo)平臺(tái)不同轉(zhuǎn)換為不同版本的 OpenGL ES Shader。YAML 只傳輸數(shù)據(jù),它本身不包含邏輯,畢竟 YAML 的全稱是“YAML Ain't a Markup Language” (YAML 不是一種標(biāo)記語(yǔ)言),真正表達(dá)邏輯的還是 GLSL 頂點(diǎn)和片元著色器。

Cocos Effect 的詳細(xì)信息何以從官方文檔「Effect 語(yǔ)法」[1]中獲得,以Cocos Creator 內(nèi)置的標(biāo)準(zhǔn) PBR 著色器為例,我們可以參考以下的信息,快速開(kāi)始編寫自己的著色器:

所有頂點(diǎn)著色器代碼需要在“CCProgram standard-vs”標(biāo)簽下用 GLSL 編寫,同時(shí)也可以使用 Cocos Creator 內(nèi)置的 Shader 參數(shù),具體的列表可以在「常用 shader 內(nèi)置 Uniform」[2]獲得;
?


類似的,所有的片元著色器代碼需要在“CCProgram standard-fs”標(biāo)簽下用 GLSL 編寫;
?


自定義參數(shù)需要在“properties”標(biāo)簽下聲明,在“properties”標(biāo)簽下聲明的變量都會(huì)在 Cocos Creator 內(nèi)的編輯面板中出現(xiàn);
?


我們需要為新聲明的參數(shù)聲明一個(gè)相應(yīng)的 uniform,這需要在“CCProgram shared-ubo”標(biāo)簽下實(shí)現(xiàn),聲明的 uniform 無(wú)論頂點(diǎn)著色器還是片元著色器都可以訪問(wèn);
?


我們也可以聲明自定義函數(shù),但是記得:YAML 是不包含邏輯的。所以自定義函數(shù)應(yīng)該放在頂點(diǎn)著色器(“CCProgram standard-vs”)或者片元著色器(“CCProgram standard-fs”)之內(nèi)。

奠定理論

首先,我們需要解答一個(gè)問(wèn)題:什么樣的效果能夠讓皮膚更真實(shí)?

我們可以從現(xiàn)實(shí)生活中找到一些參考:
?


觀察上圖,首先你可能會(huì)注意到的是:他的耳朵是紅色的。而且在結(jié)構(gòu)越陡峭、線條越堅(jiān)硬的部分,紅色顯得更加濃艷。另外,在他的鼻梁明暗交界線的部分,也可以看到一條紅色聚集的色帶。
?


在上圖中,我們同樣能夠在鼻梁的明暗交界線上觀察到紅色的色帶,她的鼻梁的線條并不是特別陡峭,因此色帶似乎也比上一個(gè)例子更寬一些。
?


在這個(gè)例子中,我們同樣可以觀察到紅色聚集的部分,不過(guò)在她的臉上,紅色聚集在鼻翼和鼻尖的位置。
?


而在這個(gè)例子當(dāng)中,我們可以在他的臉頰明暗交界線的位置看到大面積的粉紅色聚集(至于為什么是粉紅色,是因?yàn)檫@張照片在后期調(diào)色中混入了冷色調(diào)的緣故)。而這種粉紅色在他鼻梁線條鋒利的部分同樣可以看到。

綜合起來(lái),我們似乎可以觀察到一定的規(guī)律:

人的皮膚在明暗交接線的部分,會(huì)出現(xiàn)紅色聚集;

紅色聚集在人臉結(jié)構(gòu)陡峭,線條鋒利的部分,會(huì)更明顯和鮮艷;

耳朵、鼻尖、鼻翼等區(qū)域是紅色聚集常見(jiàn)的地方。

那么,為什么會(huì)出現(xiàn)這種現(xiàn)象?這些紅色是從何而來(lái)的?
?


我們知道,當(dāng)光線從一種介質(zhì) A 射入另一種介質(zhì) B 時(shí),一部分光線被介質(zhì) B 吸收,另一部分在介質(zhì) B 中經(jīng)過(guò)多次反射和折射,最終一部分光線從介質(zhì) B 折返重新射入介質(zhì) A 中。而這些在介質(zhì) B 中經(jīng)過(guò)反復(fù)反射折射而重新回到介質(zhì) A 的光線被人眼所捕捉到,所以人眼可以觀察到介質(zhì) B 的顏色。這些光線雖然原理上屬于反射光線(Specular),但二手手游拍賣平臺(tái)實(shí)際表現(xiàn)的是散射(Diffuse)的特質(zhì),所以被稱為漫反射(Diffuse Reflectance)光線。

你大概已經(jīng)注意到:當(dāng)漫反射光線經(jīng)過(guò)在介質(zhì) B 中的種種流程,重新射入介質(zhì) A 時(shí),距離原來(lái)射入介質(zhì) B 的入射點(diǎn)已經(jīng)有了一段距離。對(duì)于絕大多數(shù)材質(zhì)來(lái)說(shuō),這個(gè)距離非常微小,完全可以忽略不記,所以我們可以理解為漫反射光線是由原入射點(diǎn)射出的。


然而對(duì)一小部分材質(zhì)來(lái)說(shuō),這個(gè)距離就不能忽略了。當(dāng)光線射入時(shí),這類材質(zhì)會(huì)表現(xiàn)一種透光的特質(zhì),仿佛物體內(nèi)部自帶光源,把物體從內(nèi)部照亮了。自然界中有很多有機(jī)材質(zhì)會(huì)表現(xiàn)這種特質(zhì),比如蜂蠟、樹(shù)葉、果蔬等,當(dāng)然也包括人的皮膚。

這種特別的散射特質(zhì),即被稱為次表面散射(Sub-surface Scattering)。
?


原理似乎挺簡(jiǎn)單,但我們應(yīng)該如何實(shí)現(xiàn)呢?

在計(jì)算機(jī)圖形學(xué)的歷史上,我們可以找到多種多樣表現(xiàn)次表面散射的技巧和手法。其中一個(gè)較早的例子來(lái)自與電影《黑客帝國(guó)》(The Matrix)。特效人員發(fā)現(xiàn),可以簡(jiǎn)單地對(duì)皮膚的 Diffuse 貼圖做一次模糊,再疊加到原貼圖上,就可以有效降低貼圖的人工質(zhì)感,做出光線在表皮下散射的效果。

而對(duì)于明暗交界線上的紅色堆積,你大概已經(jīng)想到可以輕松利用“N·L”方法,通過(guò)光照方向和物體表面法線計(jì)算得明暗交界線的位置,再疊加以一個(gè)顏色即可。這種方法也被稱為 Wrap Lighting 方法,在經(jīng)典游戲《半衰期2》(Half-life 2)中廣泛應(yīng)用。

而與“N·L”非常類似的“N·V”方法,可以通過(guò)攝像機(jī)方向和物體表面法線得到物體正對(duì)攝像機(jī)觀察角度的部分,這可以幫助我們輕松獲得菲涅爾(Fresnel)反射的效果。

講到這里,我們的目標(biāo)已經(jīng)比較明確了:

我們需要一個(gè)模糊,用于達(dá)到 Diffuse 貼圖的漫反射效果;

我們需要一張 Thickness 貼圖和一張 Curvature 貼圖,幫助我們識(shí)別物體那些部位容易出現(xiàn)次表面散射;

我們需要一個(gè)菲涅爾反射效果,這將幫助我們實(shí)現(xiàn)皮膚的 Specular 部分;

最后,我們需要一個(gè) Diffuse Profile,這將幫助我們確定次表面散射的強(qiáng)度和顏色。

實(shí)現(xiàn)模糊效果

如何實(shí)現(xiàn)模糊的效果?其背后的邏輯其實(shí)很簡(jiǎn)單:我們只要把需要被模糊的圖像的 UV 向各個(gè)方向偏移一點(diǎn)距離,把所有偏移的結(jié)果相加,求一個(gè)平均值即可:

vec3 boxBlur( sampler2D diffuseMap, float blurAmt ){

vec2 uv01 = vec2(v_uv.x - blurAmt * 0.01, v_uv.y - blurAmt * 0.01);

vec2 uv02 = vec2(v_uv.x + blurAmt * 0.01, v_uv.y - blurAmt * 0.01);

vec2 uv03 = vec2(v_uv.x + blurAmt * 0.01, v_uv.y + blurAmt * 0.01);

vec2 uv04 = vec2(v_uv.x - blurAmt * 0.01, v_uv.y + blurAmt * 0.01);

vec3 blurredDiffuse = (SRGBToLinear(texture(diffuseMap, uv01).rgb) + SRGBToLinear(texture(diffuseMap, uv02).rgb) + SRGBToLinear(texture(diffuseMap, uv03).rgb) + SRGBToLinear(texture(diffuseMap, uv04).rgb)) / 4.0;

return blurredDiffuse;

}

在上面的示例代碼中,“v_uv”是 Vertex Shader 傳遞的 UV 數(shù)據(jù),我們基于 Cocos Creator 的內(nèi)置 PBR 著色器編寫我們的 Shader,所以有很多準(zhǔn)備工作已經(jīng)做好了,我們直接拿來(lái)用即可。“SRGBToLinear”是 Cocos Creator 內(nèi)置函數(shù),將 sRGB 空間的顏色數(shù)據(jù)轉(zhuǎn)換為線性空間,在 PBR 流程當(dāng)中,所有的顏色計(jì)算需要在線性空間中進(jìn)行。

當(dāng)然,僅僅做一次平均值的計(jì)算,最終效果可能不是特別好。你也可以用同樣的方法循環(huán)2-3次,以獲得更細(xì)膩的效果:

vec3 blurPass = vec3( 0.0, 0.0, 0.0 );

for( float i = 1.0; i < 4.0; i++ ){

blurPass += boxBlur(diffuseMap, blurAmt * i);

}

blurPass = blurPass / 3.0;

這種單刀直入的模糊方式,稱之為方形模糊(Box Blur),其特點(diǎn)就是所有像素一視同仁,被處于同樣等級(jí)的模糊處理。雖然簡(jiǎn)潔明了效率高,但視覺(jué)上不一定是我們想要的。

如果你用過(guò) Adobe 系列的圖像處理工具,你一定很熟悉最常用的模糊工具高斯模糊(Gaussian Blur)。高斯模糊的邏輯與方形模糊一脈相承,不同的是:像素偏移的距離越大,模糊的程度越高,反之則越小,而模糊程度的權(quán)重則呈正態(tài)分布排列。這樣我們得到的結(jié)果中間模糊程度低,四周模糊程度高,并且呈現(xiàn)出一種從中間向四周自然衰減的效果。

用代碼從頭實(shí)現(xiàn)一個(gè)正態(tài)分布函數(shù),似乎還是太麻煩了。所幸的是,我們只需要幾個(gè)呈正態(tài)分布的數(shù)值作為我們模糊的權(quán)重,直接代入我們的方形模糊函數(shù)當(dāng)中即可,網(wǎng)上有諸多正態(tài)分布數(shù)值生成器可供挑選。

vec3 gaussianBlur( sampler2D diffuseMap, float blurAmt ) {

float gOffset[5];

gOffset[0] = 0.0;

gOffset[1] = 1.0;

gOffset[2] = 2.0;

gOffset[3] = 3.0;

gOffset[4] = 4.0;

float gWeight[5];

gWeight[0] = 0.2270270270;

gWeight[1] = 0.1945945946;

gWeight[2] = 0.1216216216;

gWeight[3] = 0.0540540541;

gWeight[4] = 0.0162162162;

vec3 baseDiffuse = SRGBToLinear(texture(diffuseMap, v_uv).rgb);

for( int i = 0; i < 5; i++ ){

baseDiffuse += SRGBToLinear(texture(diffuseMap, v_uv + vec2(gOffset?* 0.01 * blurAmt, 0.0)).rgb) * gWeight;

baseDiffuse += SRGBToLinear(texture(diffuseMap, v_uv - vec2(gOffset?* 0.01 * blurAmt, 0.0)).rgb) * gWeight;

baseDiffuse += SRGBToLinear(texture(diffuseMap, v_uv + vec2(0.0, gOffset?* 0.01 * blurAmt)).rgb) * gWeight;

baseDiffuse += SRGBToLinear(texture(diffuseMap, v_uv - vec2(0.0, gOffset?* 0.01 * blurAmt)).rgb) * gWeight;

}

return baseDiffuse / 5.0;

}

探索 Diffuse Profile

讓我們回到之前觀察到的明暗交界線上的紅色聚集上面。我們已經(jīng)想到可以用“N·L”+ 顏色疊加的方法實(shí)現(xiàn)這種效果,但這里有一個(gè)問(wèn)題:這里的紅色是常量的紅色嗎?

讓我們來(lái)看一個(gè)實(shí)驗(yàn):有一個(gè)呈現(xiàn)次表面散射的球體,被單一光源照射。光源的位置和強(qiáng)度不變,放大和縮小球體的大小,觀察次表面散射顏色的變化。
?


結(jié)果略微出乎意料:在球體極大和極小的情況下,散射顏色較深,近乎于純黑色;隨著球體的縮放接近于極大和極小之間的一個(gè)范圍,散射的顏色逐漸變得明亮和鮮艷,直到達(dá)到一個(gè)峰值。

這似乎告訴我們:次表面散射的顏色變化也遵循一條鐘形曲線(正態(tài)分布曲線),在某個(gè)臨界點(diǎn)達(dá)到峰值,向兩邊遞減。

那么,這個(gè)臨界點(diǎn)是由什么決定的呢?這就取決于我們?nèi)绾卫斫鈱?shí)驗(yàn)中球體大小的變化。

首先,在光源位置不變的情況下,球體的大小變化,意味著光線到達(dá)球體表面?zhèn)鞑サ木嚯x變化,也就是說(shuō),光線傳播的距離是因素之一。

另外,一個(gè)半徑較大的球體,可以看作其表面的曲率(Curvature)也更大,反之則更小。一個(gè)半徑無(wú)限小的球體,表面的曲率也無(wú)限小,可以看作是一個(gè)平面。也就是說(shuō),物體表面的曲率,即彎曲的程度,也是因素之一。這也與我們之前在觀察參考圖中得到的結(jié)論相契合。

理論很美好,但是我們?nèi)绾螌?shí)現(xiàn)呢?

所幸的是,我們已經(jīng)有基于現(xiàn)實(shí)觀測(cè)的皮膚次表面散射數(shù)據(jù)供我們使用:
?


這張表看上去有點(diǎn)不明覺(jué)厲,簡(jiǎn)單地說(shuō):我們所觀察到的皮膚上的紅色,其實(shí)是皮膚的不同截層以不同的顏色和強(qiáng)度曲線分別進(jìn)行散射,再疊加而成。這張表列舉了六層不同的顏色和曲線。而所有截層的散射強(qiáng)度都以正態(tài)分布排列,所以我們可以在右圖看到自然衰減的暈染。

既然數(shù)據(jù)已經(jīng)給到我們了,我們就可以根據(jù)正態(tài)分布公式,計(jì)算出散射強(qiáng)度,再疊加以顏色,散射的最終輸出就解決了。
?


上圖即是正態(tài)分布(高斯分布)公式,簡(jiǎn)單地說(shuō):μ 為中位數(shù),在我們的計(jì)算中也就是散射顏色變化的峰值,我們知道它由光線傳播的距離和物體表面的曲度相關(guān),目前可以取0;σ^2為方差,它決定了鐘形曲線的陡峭程度,這個(gè)數(shù)值已經(jīng)為我們提供了。由此,我們可以直接帶入公式:

#define M_PI 3.1415926535897932384626433832795

vec3 Profile( float dis ){

return??vec3(0.233, 0.455, 0.649) * 1.0 / (abs(sqrt(0.0064)) * abs(sqrt(2.0 * M_PI))) * exp(-dis * dis / (2.0 * 0.0064)) +

vec3(0.1, 0.366, 0.344) * 1.0 / (abs(sqrt(0.0484)) * abs(sqrt(2.0 * M_PI))) * exp(-dis * dis / (2.0 * 0.0484)) +

vec3(0.118, 0.198, 0.0) * 1.0 / (abs(sqrt(0.187)) * abs(sqrt(2.0 * M_PI))) * exp(-dis * dis / (2.0 * 0.187)) +

vec3(0.113, 0.007, 0.007) * 1.0 / (abs(sqrt(0.567)) * abs(sqrt(2.0 * M_PI))) * exp(-dis * dis / (2.0 * 0.567)) +

vec3(0.358, 0.004, 0.0) * 1.0 / (abs(sqrt(1.99)) * abs(sqrt(2.0 * M_PI))) * exp(-dis * dis / (2.0 * 1.99)) +

vec3(0.078, 0.0, 0.0) * 1.0 / (abs(sqrt(7.41)) * abs(sqrt(2.0 * M_PI))) * exp(-dis * dis / (2.0 * 7.41));

}

到目前為止,我們已經(jīng)得到了實(shí)現(xiàn) Diffuse 散射效果的模糊,得到了解決次表面散射顏色和強(qiáng)度的 Diffuse Profile,現(xiàn)在的問(wèn)題是:次表面散射應(yīng)該出現(xiàn)在哪里?

在這里我們需要引入兩張貼圖:Thickness 和 Curvature。Thickness 通過(guò)以法線反方向發(fā)射射線的方式計(jì)算物體的厚度,Curvature 表現(xiàn)的是物體表面的曲率。這兩張圖,我們無(wú)需考慮如何在引擎中計(jì)算和生成,因?yàn)槲覀兛梢栽诘谌杰浖?#xff0c;比如 Substance Painter 中離線渲染他們。
?


獲得烘焙完成的貼圖之后,我們把 Curvature 放在一邊,先處理 Thickness。

vec4 bDepth = gaussianBlur(thicknessMap, 0.0);

float deltaDepth = abs(SRGBToLinear(texture(thicknessMap, v_uv).rgb).x - bDepth.x);

我們先用之前的高斯模糊處理 Thickness,再用原貼圖減去被模糊后的 Thickness 貼圖。回憶一下高斯模糊的原理,我們得到的結(jié)果是:模糊后偏離較小的像素被減去了,留下的是偏離較大的像素。這些Δ值可以作為我們次表面散射的遮罩。

我們?nèi)匀钡囊画h(huán)是菲涅爾反射。如上所述,我們可以使用“N·V”方法實(shí)現(xiàn)這一效果。

vec4 v_normal_cam = normalize(cc_matView * vec4(v_normal, 0.0));

float NVdot = dot(vec3(0.0, 0.0, 1.0), normalize(v_normal_cam).xyz);

在上面的示例代碼中,“cc_matView”是Cocos Creator自帶參數(shù),返回的是試圖矩陣。“v_normal”是從 Vertex Shader 傳遞的法線數(shù)據(jù)。

所有組件已經(jīng)基本就緒了,下面是讓他們聯(lián)動(dòng)起來(lái)的環(huán)節(jié)。

完成 Shader

漫反射效果,用我們的模糊處理一下 Diffuse 貼圖,疊加到 Albedo 通道即可。

vec4 bDiffuse = gaussianBlur(diffuseMap, blurAmt);

s.albedo += bDiffuse;

菲涅爾反射的效果,用我們“N·V”計(jì)算得出的權(quán)重,乘以一個(gè)自定義參數(shù),疊加到 roughness 通道即可。

pbr.y += NVdot * roughnessGain;

s.roughness = clamp(pbr.y, 0.04, 1.0);

漫反射的顏色,我們已經(jīng)得到了 Diffuse Profile 的函數(shù),問(wèn)題是:用什么參數(shù)帶入這個(gè)函數(shù)?

我們已經(jīng)知道光線傳播的距離和物體表面的曲率是影響次表面散射的因素。光傳播的距離似乎比較難把控,但我們至少知道物體本身的前后關(guān)系也算在光傳播的距離當(dāng)中,因此代入頂點(diǎn)位置數(shù)據(jù)(v_position)是順理成章的。

至于物體表面的曲率,我們并不知道曲率與次表面散射的直接數(shù)值關(guān)系,但我們通過(guò)觀察實(shí)驗(yàn)得知:曲率與次表面散射強(qiáng)度大致呈線性關(guān)系,因此我們姑且把曲率(由 Curvature 貼圖提供)當(dāng)作一般的數(shù)值權(quán)重,再輔以我們自定義的權(quán)重加以調(diào)節(jié)。

除了 Diffuse Profile 的輸出之外,我們還可以利用 Cocos Creator 內(nèi)置的 cc_mainLitColor 參數(shù),在散射中加入光源顏色和強(qiáng)度的影響。

最后,在顏色輸出上再疊加上物體自身的 Diffuse 顏色,就基本確立了次表面散射的顏色和強(qiáng)度。

vec3 curvatureMap = SRGBToLinear(texture(curvatureMap, v_uv).rgb);

vec3 sssColor = Profile(length(v_position) * curvatureMap.x) *

cc_mainLitColor.rgb *

cc_mainLitColor.w *

s.albedo.rgb;

然而,問(wèn)題又出現(xiàn)了:次表面散射該從哪個(gè)通道輸出?

Cocos Creator 遵循標(biāo)準(zhǔn) PBR 的 Metal/Roughness 流程,因而默認(rèn) Pipeline 中并沒(méi)有 Translucency 通道,但這并不會(huì)對(duì)我們?cè)斐商笥绊?#xff1a;我們可以利用 Emissive 通道達(dá)到相同的效果。

下一個(gè)問(wèn)題是:次表面散射應(yīng)該在哪里出現(xiàn)?

我們知道次表面散射的成因是入射光線在物體內(nèi)部反射和折射而產(chǎn)生內(nèi)部發(fā)光現(xiàn)象,所以我們的第一步是計(jì)算“N·L”,利用我們已得到的 Thickness Δ值,我們可以得到一個(gè)明面為0,暗面為 Thickness 的遮罩。這也符合次表面散射的原理:光線從明面射入,所以我們可以從暗面觀察到次表面散射現(xiàn)象。

最后,利用遮罩將次表面散射顏色疊加到暗面上,我們的效果就已經(jīng)出來(lái)了。

float sssMask = mix(deltaDepth, 0.0, NLdot);

vec3 sssGain = mix(vec3(0.0, 0.0, 0.0), sssColor, sssMask);

s.emissive += sssGain;

次表面散射確實(shí)是一個(gè)經(jīng)久不衰的話題。毫無(wú)疑問(wèn),我們今天的成果還有許多可以糾正、改進(jìn)和繼續(xù)發(fā)掘的地方。希望你讀到這里,已經(jīng)激發(fā)了一些奇思妙想,開(kāi)始動(dòng)手制作屬于自己的 Cocos Creator 著色器了。

總結(jié)

以上是生活随笔為你收集整理的Cocos 实用渲染实战(一):高性价比的人物皮肤渲染的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。