再來我們來考慮物體對環境的realtime reflection問題。
首先在PBS中,要實現realtime reflection 很簡單。
我們只要在物件中心點,放置一個reflection Probe。
並且將Metallic與Smoothness調成1,
如果需要即時反射,將type改成Realtime。
有關reflection Probe,我們可以看官網的資料(參考資料一)。
其中最主要的 :
reflection Probe會將自己範圍內所偵測到,
能夠被反射的物件,將它更新到場景的skybox中。
因此只要能取出skybox的資料,
就能完成realtime reflection的功能。
由於是要對場景中的skybox取樣:
half4 skyData = UNITY_SAMPLE_TEXCUBE(unity_SpecCube0, i.worldRefl);
half3 skyColor = DecodeHDR(skyData,unity_SpecCube0_HDR);
將skyColor輸出後,我們會發現。
雖然反射有了,但效果並不令人滿意 ,
那如果我們直接拿用來設定skybox的cubemap取樣。
結果會發現,雖然物體對背景的反射效果較好,
但反射探針並不會將資料更新到此cubemap中。
(最左邊的膠囊體)
因此我們需要對shader做一些處理。
想法很簡單,我們只需要:
1.物體對背景skybox的反射,我們使用到cubemap取樣。
2.而對周圍會變化的物件,我們取reflectionProbe的資料。
3.最後再將它們合併就好。
首先對cubemap取樣:
fixed3reflection = texCUBE(_Cubemap, worldRefl).rgb;
再來,由於是要對reflection Probe偵測到的反射物體取樣。
因此reflection Probe的資料更新,
不應該包含對周圍skybox的背景資料。
因此將reflection Probe的
ClearFlags改為SolidColor。
並將Background Color改為黑色(0,0,0)。
這樣,我們只要將reflection Probe中,
大餘0(非黑色)的部分取出及可。
再來是組合的部分。
要組合2張貼圖,我們利用一個choose參數。
float choose = step(_ReflectBlend, skyColor.x);
_ReflectBlend 用來控制取樣的範圍。
因為我們並不知道 ,背景與反射資料的色差該為多少,
才能完美將reflection Probe中,非Background的部分完全濾掉。
最後結合2筆資料:
float3 finalcolor = lerp(skyData,reflection,1-choose);
choose參數 >0 取樣cubemap
choose參數 <0 取樣reflection Probe
參考資料: