您當前的位置:首頁 > 攝影

神作面部陰影渲染還原

作者:由 黑魔姬 發表于 攝影時間:2020-11-08

神作面部陰影渲染還原

前幾年學過兩天渲染,昨天花了一個晚上,學Unity的shaderlab,做的這個還原。

結果折騰了半天我也沒訪問到shadowmap,只好裝了URP然後在這個專案上寫的程式碼

這個面部陰影看上去是非常簡單的實現,網上卻沒找到相關資料,其他人的還原好像也都是什麼修改法線。沒辦法自己想想辦法,希望B站上MMD能做的好看點。

原理

面部陰影的來源

神作面部陰影渲染還原

就這張圖了,這是張閾值圖,存了不同角度下陰影覆蓋臉上哪些部分。

用photoshop閾值功能可以看的更清楚一點。

神作面部陰影渲染還原

神作面部陰影渲染還原

生成

這張圖生成不算複雜,可以插值手繪圖得到

首先手繪一下幾個特定角度下陰影的覆蓋情況,然後生成SDF,這樣對於圖片上每個點,都知道我現在在手繪的圖的陰影的裡面還是外面,距離最近的點有多遠。

比方說我一個畫素點在30°陰影圖裡面,在60°陰影圖外,距離30°的圖是-50,距離60°的圖是50(一個正一個負,負的說明在陰影圖裡面),那麼我在45°的時候就應該在陰影裡,46°之後就不在陰影裡面了。

最後生成0-90°的所有陰影圖,加在一起除以圖片數量,就可以得到這張所謂的lightmap了。

理論上是這樣,我也沒有試。

使用

需要有lightDir,跟角色朝向Front。 垂直方向UP

dot(Front, lightDir)小於0說明光在角色背面,不應用lightmap(全部是陰影)

cross(Front , UP)可以得到角色的左向跟右向, Left 與 Right

dot(Left , lightDir)小於lightmap的值 說明當前片元在陰影下面。

不過由於這個lightmap只存了0-90°光照下的陰影,所以左半邊臉右半邊臉得各來一次。

shader

float3

UP

=

float3

0

1

0

);

// cs腳本里動態修改

float3

Front

=

float3

0

0

1

);

float3

Left

=

cross

UP

Front

);

float3

Right

=

-

cross

UP

Front

);

float

FrontL

=

dot

normalize

Front

xz

),

normalize

L

xz

));

float

LeftL

=

dot

normalize

Left

xz

),

normalize

L

xz

));

float

RightL

=

dot

normalize

Right

xz

),

normalize

L

xz

));

float

lightAttenuation

=

FrontL

>

0

*

min

surfaceData

_lightMap

r

>

LeftL

),

1

-

1

-

surfaceData

_lightMap

r

<

RightL

);

不是搞圖形學的,程式碼比較奔放,意會即可。

不過看起來unity用起來還挺簡單的?(小聲:要不轉行做遊戲算了。

最後,為啥這shader寫出來全是鋸齒啊

神作面部陰影渲染還原

之前陰影方向搞反了,現在改了一下。

float3

Front

=

unity_ObjectToWorld

_12_22_32

float3

Right

=

unity_ObjectToWorld

_13_23_33

float

FrontL

=

dot

normalize

Front

xz

),

normalize

L

xz

));

float

RightL

=

dot

normalize

Right

xz

),

normalize

L

xz

));

RightL

=

-

acos

RightL

/

3。14159265

-

0。5

*

2

float

lightAttenuation

=

FrontL

>

0

*

min

surfaceData

_lightMap

r

>

RightL

),

surfaceData

_lightMap

g

>

-

RightL

);

鋸齒問題也解決了,取樣shaodwRamp的時候,貼圖得把mipmaps關掉,本身貼圖就特別窄,不知道他給生成了個啥mip

標簽: normalize  xz  陰影  front  dot