天天看點

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

目錄

一、概述

1.1 數字人類的概要

1.1.1 數字人類的曆史和現狀

1.1.2 數字人類的制作流程

1.2 Unreal Engine的數字人類

1.2.1 Unreal Engine數字人的曆史

1.2.2 《Meet Mike》項目

二、皮膚渲染

2.1 皮膚的構成和理論

2.1.1 皮膚構成

2.1.2 皮膚模組化

2.1.3 皮膚渲染流程

2.2 次表面散射2.2.1 BSSRDF

2.3 UE底層實作

2.3.1 SeparableSSS.ush

2.3.2 SeparableSSS.cpp

2.3.2.1 高斯和的擴散剖面(Sum-of-Gaussians Diffusion Profile)

2.3.2.2 源碼分析

2.3.3 PostProcessSubsurface.ush

2.3.4 UE次表面散射的限制

2.4 皮膚材質解析

2.4.1 基礎色(Base Color)

2.4.2 高光(Specular)

2.4.3 粗糙度(Roughness)

2.4.3.1 動作混合的粗糙度

2.4.3.2 基于微表面的粗糙度

2.4.3.3 粗糙度調整和邊緣粗糙度

2.4.3.4 微表面細節加強

2.4.4 次表面散射(Opacity)

2.4.5 法線(Normal)

2.4.6 環境光遮蔽(Ambient Occlusion)

2.5 皮膚貼圖制作

本系列文章其它部分

特别說明

參考文獻

數字人類(Digital Human)是利用計算機模拟真實人類的一種綜合性的渲染技術。也被稱為虛拟人類、超真實人類、照片級人類。

它是一種技術和藝術相結合的綜合性模拟渲染,涵蓋計算機圖形渲染、模型掃描、3D模組化、肢體驅動、AI算法等領域。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

數字人類概念圖

随着計算機渲染技術的發展,數字人類在電影領域早有應用。在上世紀80年代的《星球大戰》系列、《異形》系列等電影,到後來的《終結者》系列、《黑客帝國》系列、《指環王》系列等,再到近期的漫威、DC動畫電影,都存在着虛拟角色的身影,他們或是天賦異禀的人類,或是奇形怪狀的怪物。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

《星球大戰I》中的虛拟角色:尤達大師(Master Yoda)

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

《黑客帝國》的主角很多鏡頭是采用計算機渲染而成的虛拟數字人

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

電影《戰鬥天使》的畫面。主角阿麗塔也是虛拟角色。

由于近些年計算機硬體性能和渲染技術的提升,除了在離線渲染領域的電影和動漫的廣泛應用之外,實時領域的應用也得到長足的進步。例如,次世代遊戲、3A大作、VR遊戲以及泛娛樂領域的直播領域。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

《孤島驚魂5》中的虛拟遊戲角色

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

R&D和暴雪在GDC2013展示的次世代虛拟角色

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

Unreal Engine在GDC2018展示的虛拟角色Siren,可由演員實時驅動動作、表情、肢體等資訊。

數字人類的步驟多,工序繁瑣。但總結起來,通常有以下幾個步驟:

模型掃描。通常借助光學掃描器或由單反相機組成的360度的攝影包圍盒,對掃描對象進行全方位的掃描,進而獲得原始的模型資料。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

上圖展示了模型掃描器,由很多攝影和燈光裝置組成的球形矩陣。

模型調整。由掃描階段擷取的初始模型通常有瑕疵,無法直接投入渲染。需要美術人員利用3D模組化工具(如Maya、3DMax等)進行調整、優化、重新拓撲,最終調整成合适的可用模型。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

左:掃描的初始模型;中:調整後的中間模型;右:優化了細節的可用模型。

制作貼圖。在此階段,用模組化軟體或材質制作軟體(如Substance)采納高精度模型烘焙或制作出漫反射、法線、粗糙度、AO、散射、高光等等貼圖,為最後的渲染做準備。這些貼圖的原始尺寸通常都非常大,4K、8K甚至16K,目的是高精度還原虛拟人類的細節。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

漫反射貼圖

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

法線貼圖

導入引擎。在此階段,将之前制作的模型和貼圖導入到渲染引擎(如UE4、Unity等),加入光照、材質、場景等元素,結合角色的綜合性PBR渲染技術,獲得最終成像。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

Unreal Engine渲染出的虛拟角色

Unreal Engine作為商業渲染引擎的巨頭,在實時領域渲染數字人類做了很多嘗試,關鍵節點有:

2015年:《A Boy and His Kite》。展示了當時的開放世界概念和自然的角色動畫風格與憑借第一人稱射擊遊戲成名的Epic以前做過的任何項目都大不相同。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

《A Boy and His Kite》的畫面

2016年:《地獄之刃:塞娜的獻祭》。這是Unreal将數字人引入實時遊戲的一次嘗試,從畫質表現上,已經達到了異常逼真的程度。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

《地獄之刃:塞娜的獻祭》中的遊戲角色畫面

2017年:《Meet Mike》。在Siggraph 2017中,Epic Game憑借此項目為世人展示了數字人科技的最新研究:利用最先進的畫面捕捉技術、體感控制技術以及畫面渲染技術在計算機中塑造人類的化身。其中數字人Mike是著名電影特效大師以及Fx Guide網站創始人Mike Seymour的化身。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

Unreal Engine官方團隊制作的Mike虛拟角色

2018年:《Siren》。Siren是Epic Game、3Lateral、Cubic Motion、Vicon以及騰訊的NEXT工作室等多家跨國公司傾力合作,花費半年多打造的頂級實時渲染的虛拟角色。從畫質效果上看,已經與數位照片無異。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

《Siren》虛拟角色的細節,與數位相機攝制的照片如出一轍

筆者本想以《Siren》的虛拟角色為依托進行研究,奈何官方并未将此項目開源。

是以本文隻能用《Meet Mike》項目的角色作為研究對象。

《Meet Mike》項目的資源和源碼可以從Unreal Engine的Epic Games Launcher中下載下傳獲得。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

《Meet Mike》資源和源碼下載下傳具體步驟

若成功下載下傳了Mike工程,打開項目的DigitalHuman.uproject檔案,可以看到下面的畫面:

點選右上角World Outliner面闆的”final_mike“,可以檢視Mike模型及其所有材質的細節。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

如果要研究某個部分的材質(比如皮膚),輕按兩下對應的材質,即可打開材質節點。下圖是輕按兩下M_Head皮膚材質後的界面:

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

打材質編輯器後,便可以進行後續的研究。後面章節将着重研究數字人的皮膚、眼球、毛發以及身體其它部位的渲染技術。

Mike的一些資料:

57萬個三角形,69萬個頂點。其中大量三角形集中在臉部,特别是頭發,約占75%。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

每根頭發都是單獨三角形,大約有2萬多根頭發。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

臉部骨骼綁定使用了大約80個關節,大部分是為了頭發的運動和臉部毛發。

臉部模型大約隻用了10個關節,分别用在下巴、眼睛和舌頭,目的是為了運動更加圓滑。

臉部使用了Technoprop公司先進的配有立體紅外攝像頭的固定在頭部的面部捕捉裝置。

綜合使用了750個融合變形(blend shapes)。

系統使用了複雜的傳統軟體和三種深度學習AI引擎。

皮膚渲染技術經過數十年的發展,由最初的單張貼圖+倫勃朗的渲染方式到近期的基于實體的SSSSS(螢幕空間次表面散射)。由此衍生出的皮膚渲染技術層出不窮,其中最最基礎也最具代表性的是次表面散射(SSS)。

在虛拟角色渲染中,皮膚的渲染尤為關鍵。因為皮膚是人們每天親眼目睹的非常熟悉的東西,如果稍微渲染不好或細節處理不足,便會陷入恐怖谷(Uncanny Valley )理論。至于什麼是恐怖谷理論,參看這裡。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

上圖由于皮膚的細節處理不到位,陷入了恐怖谷理論

人類皮膚的實體構成非常複雜,其表層和内部都由非常複雜的構成物質,剖面圖如下:

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

絨毛(hair shaft)。附着于皮膚表面的細小的毛。

油脂(oil)。皮膚表層有一層薄薄的油脂覆寫,是皮膚高光的主要貢獻者。

表皮(epidermis)。油脂層下是表皮覆寫,是造成次表面散射的物質之一。

真皮(dermis)。表皮下面是真正的皮膚組織,也是造成次表面散射的物質之一。

毛囊(hair follicle)。絨毛的皮下組織和根基。

靜脈(vein)。呈深藍色的血管。

動脈(artery)。呈暗紅色的血管。

脂肪組織(fatty tissue)。脂肪組織也是造成次表面散射的次要貢獻物質。

其它:皮膚表面的紋理、皺紋、毛孔、雀斑、痘痘、黑痣、疤痕、油脂粒等等細節。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

真實皮膚包含了非常多的細節:毛孔、絨毛、痘痘、黑痣、油脂......

皮膚表面油脂層主要貢獻了皮膚光照的反射部分(約6%的光線被反射),而油脂層下面的表皮層和真皮層則主要貢獻了的次表面散射部分(約94%的光線被散射)。

雖然皮膚構成非常複雜,但圖形渲染界的先賢者們利用簡化的思維将皮膚模組化成若幹層。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

表面油脂層(Thin Oily Layer):模拟皮膚的高光反射。

表皮層(Epidermis):模拟次表面散射的貢獻層。

真皮層(Dermis):模拟次表面散射的貢獻層。

以上展示的是BRDF模組化方式,隻在皮膚表面反射光線,但實際上在三層模組化中,還會考慮表皮層和真皮層的次表面散射(BSSRDF),見下圖中間部分BSSRDF。

皮膚渲染涉及的進階技術有:

線性空間光照工作流。這部分可以參看《Technical Artist 的不歸路 —— 線性空間光照》。

基于實體的光照(PBR)。這部分的理論和實踐可以參看筆者的另一篇技術文章:《由淺入深學習PBR的原理和實作》

大量後處理。

1~5個實時光照和1個預計算光照探頭。

皮膚渲染的過程可以抽象成以下步驟:

皮膚反射。

直接反射部分采用Cook-Torrance的BRDF,公式:

\[f_{cook-torrance} = \frac {D(h)F(l,h)G(l,v,h)}{4(n\cdot l)(n\cdot v)}

\]

具體解析和實作請參看《由淺入深學習PBR的原理和實作》的章節3.1.3 反射方程。

UE的皮膚渲染采用雙鏡葉高光(Dual Lobe Specular)。雙鏡葉高光度為兩個獨立的高光鏡葉提供粗糙度值,二者組合後形成最終結果。當二者組合後,會為皮膚提供非常出色的亞像素微頻效果,呈現出一種自然面貌。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

其中UE預設的混合公式是:

\[Lobe1 \cdot 0.85 \ + \ Lobe2 \cdot 0.15

下圖顯示了UE4混合的過程和最終成像。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

左:較柔和的高光層Lobe1; 中:較強烈的高光層Lobe2; 右:最終混合成像

非直接反射部分采用預卷積的cube map。

具體解析和實作請參看《由淺入深學習PBR的原理和實作》的章節3.3.2 鏡面的IBL(Specular IBL)。

皮膚毛孔。

皮膚毛孔内部構造非常複雜,會造成反射(高光和漫反射)、陰影、遮擋、次表面散射等效應。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

人類毛孔放大圖,内部構造異常複雜,由此産生非常複雜的光照資訊

在渲染毛孔細節時,需注意很多細節,否則會渲染結果陷入恐怖谷理論。

理論上,接近實體真實的渲染,毛孔的渲染公式如下:

\[cavity \cdot Specular(gloss) \cdot Fresnel(reflectance)

其中:

\(cavity\)是凹陷度。可從cavity map(下圖)中采樣獲得。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

\(Specular(gloss)\)表明高光項。

\(Fresnel(reflectance)\)是與視覺角度相關的反射。

然而,這種實體真實,使得凹陷太明顯,視覺不美觀,有點讓人不适:

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

嘗試微調高光和cavity的位置,可獲得下面的渲染結果:

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

上圖可以看出,高光太強,凹陷細節不足,也是不夠真實的皮膚渲染結果。

實際上,可摒棄完全實體真實的原理,采用近似法:

\[Specular(gloss) \cdot Fresnel(cavity \cdot reflectance)

最終可渲染出真實和美觀相平衡的畫面:

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

UE4采用漫反射+粗糙度+高光度+散射+法線等貼圖結合的方式,以高精度還原皮膚細節。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

從左到右:漫反射、粗糙度、高光度、散射、法線貼圖

具體光照過程跟Cook-Torrance的BRDF大緻一樣,這裡不詳述。

全局光照。

皮膚的全局光照是基于圖像的光照(IBL)+改進的AO結合的結果。

其中IBL技術請參看3.3 基于圖像的光照(Image Based Lighting,IBL)。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

上圖:疊加了全局光照,但無AO的畫面

AO部分是螢幕空間環境光遮蔽(SSAO),其中AO貼圖混合了Bleed Color(皮膚通常取紅色)。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

增加了紅色Bleed Color的AO,使得皮膚渲染更加貼切,皮膚暗處的亮度和顔色更真實美觀。

次表面散射(BSSRDF)。

這部分内容将在2.2更較長的描述。

次表面散射(Subsurface scattering)是模拟皮膚、玉石、牛奶等半透光性物質的一種實體渲染技術。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

它與普通BRDF的差別在于,同一條入射光進入半透光性物質後,會在内部經過多次散射,最終在入射點附近散射出若幹條光線。

由于R、G、B在物質内擴散的曲線不一樣,由此産生了與入射光不一樣的顔色。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

紅色光由于穿透力更強,更容易在皮膚組織穿透,形成紅色光。

BSSRDF是基于次表面散射的一種光照模型,充分考慮了入射光在物質内部經過若幹次散射後重新反射出來的光。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

左:BRDF;右:BSSRDF,考慮了輸入光在物質内散射後重新射出的若幹條光

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

上圖描述了BRDF、BTDF、BSSRDF之間的關系:

BRDF:雙向反射分布函數,用于表述在媒體入射點的反射光照模型。

BTDF:雙向透射分布函數,用于描述光線透過媒體後的光照模型。

BSSRDF:雙向次表面反射分布函數,用于描述入射光在媒體内部的光照模型。

BSDF = BRDF + BTDF。

BSSRDF是BSDF的更新版。

下面兩圖展示了使用BRDF和BSSRDF的皮膚渲染結果:

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

BRDF光照模型渲染的皮膚

BSSRDF光照模型渲染的皮膚

可見BSSRDF渲染的皮膚效果更真實,更美觀,防止陷入恐怖谷效應。

回顧一下BRDF的方程,它是一次反射光照的計算是在光線交點的法線半球上的球面積分:

\[L_o(p,\omega_o) = \int\limits_{\Omega} f_r(p,\omega_i,\omega_o) L_i(p,\omega_i) n \cdot \omega_i d\omega_i

對于BSSRDF來說,每一次反射在物體表面上每一個位置都要做一次半球面積分,是一個嵌套積分:

\[L_o(p_o,\omega_o) = \int\limits_{A} \int\limits_{\Omega} S(p_o,\omega_o,p_i,\omega_i) L_i(p_i,\omega_i) n \cdot \omega_i d\omega_i dA

\(S(p_o,\omega_o,p_i,\omega_i)\)項表明了次表面散射的計算過程,具體公式:

\[\begin{eqnarray}

S(p_o,\omega_o,p_i,\omega_i) &\stackrel {def}{=}& \frac{dL_r(p_o,\omega_o)}{d\Phi_r(p_i,\omega_i)} \\

&=& \frac{1}{\pi}F_t(p_o,\omega_o)R_d(\parallel p_i-p_o\parallel)F_t(p_i,\omega_i) \\

\end{eqnarray}

\(\frac{dL_r(p_o,\omega_o)}{d\Phi_r(p_i,\omega_i)}\)表明BSSRDF的定義是出射光的輻射度和入射通量的比值。

\(F_t\)是菲涅爾透射效應。

\(R_d(\parallel p_i-p_o\parallel)\)是擴散反射(Diffuse reflectance),與入射點和出射點的距離相關。

\[R_d(\parallel p_i-p_o\parallel) = -D\frac{(n\cdot \triangle\phi(p_o))}{d\Phi_i(p_i)}

\(D\)是漫反射常量:

\[D=\frac{1}{3\sigma_t'}

由此可見,\(S\)項的計算過程比較複雜,對于實時渲染,是幾乎不可能完成的。由此可采用近似法求解:

\[S(p_o,\omega_o,p_i,\omega_i) \approx (1-F_r(\cos\theta_o))S_p(p_o,p_i)S_\omega(\omega_i)

\(F_r(\cos\theta_o)\)是菲涅爾反射項。

\(S_p(p_o,p_i)\)是點\(p\)處的次表面散射函數。它可以進一步簡化:

\[S_p(p_o,p_i) \approx S_r(\parallel p_o - p_i\parallel)

也就是說點\(p\)處的次表面系數隻由入射點\(p_i\)和出射點\(p_o\)相關。

\(S_r\)跟媒體的很多屬性有關,可用公式表達及簡化:

S_r(\eta,g,\rho,\sigma_t,r) &=& \sigma^2_t S_r(\eta,g,\rho,1,r_{optical}) \\

&\approx& \sigma^2_t S_r(\rho,r_{optical}) \\

r_{optical} &=& \rho_t r

簡化後的\(S_r\)隻跟\(\rho\)和\(r\)有關,每種材料的\(\rho\)和\(r\)可組成一個BSSRDF表。

上圖展示了\(\rho=0.2\)和\(r=0.5\)的索引表。

通過\(\rho\)和\(r\)可查詢到對應的\(S_r\),進而化繁為簡,實作實時渲染的目标。

\(S_\omega(\omega_i)\)是有縮放因子的菲涅爾項,它的公式:

\[S_\omega(\omega_i) = \frac{1-F_r(\cos\theta_i)}{c\cdot \pi}

其中\(c\)是一個嵌套的半球面積分:

c &=& \int_0^{2\pi} \int_0^{\frac{\pi}{2}} \frac{1-F_r(\eta,\cos\theta)}{\pi}\sin\theta \ \cos\theta \ d\theta \ d\phi \\

&=& 1 - 2 \int_0^{\frac{\pi}{2}} F_r(\eta,\cos\theta)\sin\theta \ \cos\theta \ d\theta \ d\phi

BSSRDF公式更具體的理論、推導、簡化過程可參看下面兩篇論文:

A Practical Model for Subsurface Light Transport

BSSRDF Explorer: A Rendering Framework for the BSSRDF

2.2.2 次表面散射的空間模糊

次表面散射本質上是采樣周邊像素進行權重計算,類似特殊的高斯模糊。也就是說,次表面散射的計算可以分為兩個部分:

(1)先對每個像素進行一般的漫反射計算。

(2)再根據某種特殊的函數\(R(r)\)和(1)中的漫反射結果,權重計算周圍若幹個像素對目前像素的次表面散射貢獻。

上述(2)中提到的\(R(r)\)就是次表面散射的擴散剖面(Diffusion Profile)。它是一個次表面散射的光線密度分布,是各向同性的函數,也就是說一個像素受周邊像素的光照影響的比例隻和兩個像素間的距離有關。

實際上所有材質都存在次表面散射現象,差別隻在于其密度分布函數\(R(r)\)的集中程度,如果該函數的絕大部分能量都集中在入射點附近(r=0),就表示附近像素對目前像素的光照貢獻不明顯,可以忽略,則在渲染時我們就用漫反射代替,如果該函數分布比較均勻,附近像素對目前像素的光照貢獻明顯,則需要單獨計算次表面散射。

利用擴散剖面技術模拟的次表面散射,為了得到更柔和的皮膚質感,需要對畫面進行若幹次不同參數的高斯模糊。從模糊空間劃分,有兩種方法:

紋理空間模糊(Texture Space Blur)。利用皮膚中散射的局部特性,通過使用紋理坐标作為渲染坐标展開3D網格,在2D紋理中有效地對其進行模拟。

螢幕空間模糊(Screen Space Blur)。跟紋理空間不同的是,它在螢幕空間進行模糊,也被稱為螢幕空間次表面散射(Screen Space SubSurface Scattering,SSSSS)。

紋理空間和螢幕空間進行0, 3, 5次高斯模糊的結果

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

上圖:螢幕空間的次表面散射渲染過程

2.2.3 可分離的次表面散射(Separable Subsurface Scattering)

次表面散射的模糊存在卷積分離(Separable Convolution)的優化方法,具體是将橫向坐标U和縱向坐标V分開卷積,再做合成:

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

由此産生了可分離的次表面散射(Separable Subsurface Scattering,也叫SSSS或4S),這也是UE目前采用的人類皮膚渲染方法。它将\(R_d\)做了簡化:

\[R_d(x,y) \approx A_g(x,y) = \sum_{i=1}^N \omega_i G(x,y,\sigma_i)

具體的推導過程請參看:Separable Subsurface Scattering。

該論文還提到,為了給實時渲染加速,還需要預積分分離的卷積核(Pre-integrated Separable Kernel):

\[A_p(x,y) = \frac{1}{\parallel R_d \parallel_1} a_p(x)a_p(y)

利用奇異值分解(Singular Value Decomposition,SVD)的方法将其分解為一個行向量和一個列向量,并且保證了分解後的表示方法基本沒有能量損失。下圖展示了它的計算過程:

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

本節将從UE的C++和shader源碼分析皮膚渲染的實作。UE源碼下載下傳的具體步驟請看官方文檔:下載下傳虛幻引擎源代碼。

再次給擁有充分共享精神的Epic Game點個贊!UE的開源使我們可以一窺引擎内部的實作,不再是黑盒操作,也使我們有機會學習圖形渲染的知識,對個人、項目和公司都大有裨益。

皮膚渲染的方法很多,UE使用的是可分離的次表面散射(Separable Subsurface Scattering,也叫SSSS或4S)。最先由暴雪的Jorge等人,在GDC2013的演講《Next-Generation Character Rendering》中首次展示了SSSS的渲染圖,并在2015年通過論文正式提出了Separable Subsurface Scattering。其通過水準和垂直卷積2個Pass來近似,效率更進一步提升,這是目前遊戲裡采用的主流技術。

UE源碼中,與SSSS相關的主要檔案(筆者使用的是UE 4.22,不同版本可能有所差别):

\Engine\Shaders\Private\SeparableSSS.ush:

SSSS的shader主要實作。

\Engine\Shaders\Private\PostProcessSubsurface.usf:

後處理階段為SeparableSSS.ush提供資料和工具接口的實作。

\Engine\Shaders\Private\SubsurfaceProfileCommon.ush:

定義了SSSS的常量和配置。

\Engine\Source\Runtime\Engine\Private\Rendering\SeparableSSS.cpp:

實作CPU版本的擴散剖面、高斯模糊及透射剖面等邏輯,可用于離線計算。

\Engine\Source\Runtime\Engine\Private\Rendering\SubsurfaceProfile.cpp:

SSS Profile的管理,紋理的建立,及與SSSS互動的處理。

SeparableSSS.ush是實作SSSS的主要shader檔案,先分析像素着色器代碼。(下面有些接口是在其它檔案定義的,通過名字就可以知道大緻的意思,無需關心其内部實作細節也不妨礙分析核心渲染算法。)

此檔案還有<code>SSSSTransmittance</code>,但筆者搜尋了整個UE的源代碼工程,似乎沒有被用到,是以暫時不分析。下面隻貼出其源碼:

SeparableSSS.cpp主題提供了擴散剖面、透射剖面、高斯模糊計算以及鏡像卷積核的預計算。

為了更好地了解源代碼,還是先介紹一些前提知識。

擴散剖面的模拟可由若幹個高斯和函數進行模拟,其中高斯函數的公式:

\[f_{gaussian} = e^{-r^2}

下圖是單個高斯和的擴散剖面曲線圖:

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

由此可見R、G、B的擴散距離不一樣,并且單個高斯函數無法精确模拟出複雜的人類皮膚擴散剖面。

實踐表明多個高斯分布在一起可以對擴散剖面提供極好的近似。并且高斯函數是獨特的,因為它們同時是可分離的和徑向對稱的,并且它們可以互相卷積來産生新的高斯函數。

對于每個擴散分布\(R(r)\),我們找到具有權重\(\omega_i\)和方差\(v_i\)的\(k\)個高斯函數:

\[R(r) \approx \sum_{i=1}^k\omega_iG(v_i,r)

并且高斯函數的方差\(v\)有以下定義:

\[G(v, r) := \frac{1}{2\pi v} e^{\frac{-r^2}{2v}}

可以選擇常數\(\frac{1}{2v}\)使得\(G(v, r)\)在用于徑向2D模糊時不會使輸入圖像變暗或變亮(其具有機關脈沖響應(unit impulse response))。

對于大部分透明物體(牛奶、大理石等)用一個Dipole Profile就夠了,但是對于皮膚這種擁有多層結構的材質,用一個Dipole Profile不能達到理想的效果,可以通過3個Dipole接近Jensen論文中的根據測量得出的皮膚Profile資料。

實驗發現,3個Dipole曲線可通過以下6個高斯函數拟合得到(具體的拟合推導過程參見:《GPU Gems 3》:真實感皮膚渲染技術總結):

R(r) &amp;=&amp; 0.233\cdot G(0.0064,r) + 0.1\cdot G(0.0484,r) + 0.118\cdot G(0.187,r) \\

&amp;+&amp; 0.113\cdot G(0.567,r) + 0.358\cdot G(1.99,r) + 0.078\cdot G(7.41,r)

上述公式是紅通道Red的模拟,綠通道Green和藍通道Blue的參數不一樣,見下表:

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

R、G、B通道拟合出的曲線有所不同(下圖),可見R通道曲線的擴散範圍最遠,這也是皮膚顯示出紅色的原因。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

首先分析<code>SeparableSSS_Gaussian</code>:

再分析<code>SeparableSSS_Profile</code>:

接着分析如何利用上面的接口進行離線計算Kernel的權重:

此檔案還實作了<code>ComputeTransmissionProfile</code>:

<code>ComputeMirroredSSSKernel</code>和<code>ComputeTransmissionProfile</code>的觸發是在<code>FSubsurfaceProfileTexture::CreateTexture</code>内,而後者又是在關卡加載時或者編輯器操作時觸發調用(也就是說預計算的,非運作時計算):

此檔案為<code>SeparableSSS.ush</code>定義了大量接口和變量,并且是調用<code>SeparableSSS</code>的使用者:

并且在調用<code>MainPS</code>前,已經由其它代碼計算好了漫反射顔色,後續還會進行高光混合。如果在預計算卷積核之前就混合了高光,會得到不好的渲染結果:

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

UE4的次表面散射雖然能提高非常逼真的皮膚渲染,但也存在以下限制(摘自官方文檔:次表面輪廓明暗處理模型):

該功能不适用于非延遲(移動)渲染模式。

将大螢幕設定為散射半徑,将會在極端照明條件下顯示出帶狀瑕疵。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

目前,沒有照明反向散射。

目前,當非SSS材質遮擋SSS材質時,會出現灰色輪廓。(經筆者測試,4.22.1并不會出現,見下圖)

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

本節将開始解析Mike的皮膚材質。皮膚材質主要是M_Head。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

皮膚材質節點總覽

它的啟用了次表面散射的着色模型,此外,還開啟了與骨骼動作和靜态光一起使用标記,如下:

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染
剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

對于基礎色,是由4張漫反射貼圖(下圖)作為輸入,通過MF_AnimatedMapsMike輸出混合的結果,再除以由一張次表面散射遮罩圖(T_head_sss_ao_mask)控制的系數,最終輸入到Base Color引腳。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

4張漫反射貼圖,每張都代表着不同動作狀态下的貼圖。

其中MF_AnimatedMapsMike是一個通用的材質函數,内部控制着不同動作下的貼圖混合權重,而混合不同動作參數的是<code>m_headMask_01</code>、<code>m_headMask_02</code>、<code>m_headMask_03</code>三個材質函數:

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

而<code>m_headMask_01</code>、<code>m_headMask_02</code>、<code>m_headMask_03</code>三個材質函數又分别控制了一組面部Blend Shape動作,其中以<code>m_headMask_01</code>為研究對象:

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

由上圖可見,<code>m_headMask_01</code>有5張貼圖(head_wm1_msk_01 ~ head_wm1_msk_04,head_wm13_msk_03),利用它們的共19個通道(head_wm1_msk_04的alpha通道沒用上)提供了19組blend shape遮罩,然後它們與對應的參數相作用。

此外,<code>m_headMask_02</code>有3張貼圖控制了10個Blend Shape動作;<code>m_headMask_03</code>有3張貼圖控制了12個Blend Shape動作。

至于遮罩資料和blend shape參數如何計算,還得進入<code>fn_maskDelta_xx</code>一探究竟,下面以<code>fn_maskDelta_01</code>為例:

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

不要被衆多的材質節點搞迷糊了,其實就是将每個Blend Shape遮罩與參數相乘,再将結果與其它參數相加,最終輸出結果。抽象成公式:

\[f = \sum_{i=1}^N m_i \cdot p_i

其中\(m_i\)表示第\(i\)個Blend Shape的遮罩值,\(p_i\)表示第\(i\)個Blend Shape的參數值。奏是辣麼簡單!

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

高光度主要由Mike_head_cavity_map_001的R通道提供,通過<code>Power</code>和<code>Lerp</code>調整強度和範圍後,再經過<code>Fresnel</code>菲涅爾節點增強角色邊緣的高光反射(下圖)。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

上述結果經過<code>T_head_sss_ao_mask</code>貼圖的Alpha通道控制高光度和<code>BaseSpecularValue</code>調整後,最終輸出到<code>Specular</code>引腳。(下圖)

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

其中鼻子區域的高光度通過貼圖<code>T_RGB_roughness_02</code>的R通道在原始值和<code>0.8</code>之間做插值。

粗糙度的計算比較複雜,要分幾個部分來分析。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

這部分跟基礎色類似,通過4張不同動作狀态的粗糙度貼圖(Toksvig_mesoNormal,Toksvig_mesoNormal1,Toksvig_mesoNormal2,Toksvig_mesoNormal3)混合成初始粗糙度值。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

如上圖,由<code>Toksvig_mesoNormal</code>的G通道加上基礎粗糙度<code>BaseRoughness</code>,再進入材質函數<code>MF_RoughnessRegionMult</code>處理後輸出結果。

其中,<code>MF_RoughnessRegionMult</code>的内部計算如下:

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

簡而言之,就是通過3張mask貼圖(head_skin_mask4,T_siren_head_roughmask_02,T_siren_head_roughmask_01)的10個通道分别控制10個部位的粗糙度,并且每個部位的粗糙度提供了參數調節,使得每個部位在\([1.0, mask]\)之間插值。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

上圖所示,<code>RoughnessVariation</code>通過<code>Mike_T_specular_neutral</code>的R通道,在<code>Rough0</code>和<code>Rough1</code>之間做插值;<code>EdgeRoughness</code>則通過<code>Fresnel</code>節點加強了角色視角邊緣的粗糙度;然後将它們和前倆小節的結果分别做相乘和相加。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

如上圖,将紋理坐标做偏移後,采用微表面細節貼圖<code>skin_h</code>,接着加強對比度,并将值控制在\([0.85, 1.0]\)之間,最後與上一小節的結果相乘,輸出到粗糙度引腳。

其中微表面細節貼圖<code>skin_h</code>見下:

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

首先需要說明,當材質着色模型是Subsurface Profile時,材質引腳Opacity的作用不再是控制物體的透明度,而變成了控制次表面散射的系數。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

由貼圖<code>T_head_sss_ao_mask</code>的G通道(下圖)提供主要的次表面散射資料,将它們限定在[<code>ThinScatter</code>,<code>ThickScatter</code>]之間。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

次表面散射遮罩圖。可見耳朵、鼻子最強,鼻子、嘴巴次之。

另外,通過貼圖<code>T_RGB_roughness_02</code>的B、A通道分别控制上眼睑(UpperLidScatter)和眼皮(LidScatter)部位的次表面散射系數。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

與漫反射、粗糙度類似,法線的主要提供者也是由4張圖控制。

此外,還提供了微觀法線,以增加鏡頭很近時的皮膚細節。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

主法線和微觀法線分别經過<code>NormalStrength</code>和<code>MicroNormalStrength</code>縮放後(注意,法線的z通道資料不變),再通過材質節點<code>BlendAngleCorrectedNormals</code>将它們疊加起來,最後規範化輸入到法線引腳。(見下圖)

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

不妨進入材質節點<code>BlendAngleCorrectedNormals</code>分析法線的混合過程:

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

從材質節點上看,計算過程并不算複雜,将它轉成函數:

另外,Normal Map Blending in Unreal Engine 4一文提出了一種更簡單的混合方法:

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

将兩個法線的XY相加、Z相乘即得到混合的結果。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

AO控制非常簡單,直接用貼圖<code>T_head_sss_ao_mask</code>的R通道輸入到AO引腳。其中<code>T_head_sss_ao_mask</code>的R通道如下:

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

可見,五官内部、下颚、脖子、頭發都屏蔽了較多的環境光。

前面可以看到,皮膚渲染涉及的貼圖非常多,多達幾十張。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

它們的制作來源通常有以下幾種:

掃描出的超高清貼圖。例如漫反射、高光、SSS、粗糙度、法線等等。

轉置貼圖。比如粗糙度、副法線、微觀法線等。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

粗糙度貼圖由法線貼圖轉置而成。

遮罩圖。這類圖非常多,辨別了身體的各個區域,以便精準控制它們的各類屬性。來源有:

PS等軟體制作。此法最傳統,也最容易了解。

插件生成。利用Blend Shape、骨骼等的權重資訊,自動生成遮罩圖。

剖析Unreal Engine超真實人類的渲染技術Part 1 - 概述和皮膚渲染

Blend Shape記錄了頂點的權重,可以将它們對應的UV區域生成遮罩圖。

剖析Unreal Engine超真實人類的渲染技術Part 2 - 眼球渲染

剖析Unreal Engine超真實人類的渲染技術Part 3 - 毛發渲染及其它

本系列還有眼球、毛發、其它身體部位的分析,未完待續。

感謝參考文獻的作者們。

Next-Generation-Character-Rendering (ACM Transactions on Graphics, Vol. 29(5), SIGGRAPH Asia 2010)

Separable Subsurface Scattering

Real-Time Realistic Skin Translucency

《GPU Gems 3》:真實感皮膚渲染技術總結

角色渲染技術——皮膚

細緻到毛孔 ! 深度揭秘超真實皮膚的實時渲染技術(上篇)

細緻到毛孔 ! 深度揭秘超真實皮膚的實時渲染技術(下篇)

《由淺入深學習PBR的原理和實作》

Fast subsurface scattering

BRDF representation and acquisition

A BSSRDF Model for Efficient Rendering of Fur with Global Illumination

Parameter Estimation of BSSRDF for Heterogeneous Translucent Materials

NVIDIA官方展示HairWorks“海飛絲”(1.1 by Tarkan Sarim)

Q132:PBRT-V3,BSSRDF(雙向散射表面反射分布函數)(5.6.2章節、11.4章節)

BSSRDF Importance Sampling

Digital Mike頭發制作及渲染的深度揭秘

SIGGRAPH 2017|迄今為止最高品質實時數字人

NEXT Story S02.03 - 虛拟人(1)

虛幻引擎在GDC教你做人

數字人類

照片級角色

次表面輪廓明暗處理模型

Gaussian Models

《Technical Artist 的不歸路 —— 線性空間光照》

Kim Libreri暢談虛拟制片、數字化人物和Epic Games的後續發展

Siren亮相FMX 2018:實時穿越《恐怖谷》

Star Wars

Facial Action Coding System

探究《地獄之刃:塞娜的獻祭》(Hellblade: Senua's Sacrifice)背後的理念

EPIC win: previs to final in five minutes

恐怖谷理論

Normal Map Blending in Unreal Engine 4

繼續閱讀