本節主要參考:
https://catlikecoding.com/unity/tutorials/custom-srp/baked-light/
這真實一個很好的unity教程網址。
本節主要重點講解,兩個知識點:
1、light probe的使用
2、light probe proxy volume的使用
這兩個都是給gi使用的,所謂gi就是全局光照,爲了彌補gi對動態物件的影響,unity爲我們提供了light probe和light probe proxy volume的兩個組件。
1、light probe的使用
如下圖:
可以添加多個小球:
這準備好了LightProbe,下面是準備好燈光、和一個靜態物件。
我們先不考慮燈光,只有一個靜態物件。
然後進行烘焙了,烘焙了,烘焙的是啥呀?我記錄的是光的信息呢?還是物體表面的自發光信息呢?還是物體表面漫反射的信息呢?
首先烘焙是記錄的是光經過多次反射之後的結果。
烘焙使用的shader裏我們之前試驗過,必須使用light mode=meta的pass。
也說明過了,在片段着色器中的如何進行光照、自發光、物體表面漫反射的顏色。
所以,至於最後烘焙成啥,完全看這個meta pass的寫法如何。這裏我們不妨讓這個靜態物件的meta pass就返回一個顏色:
float4 frag(v2f input) : SV_TARGET
{
return float4(1, 1, 0, 1);
}
這是返回的一個黃色。
ok,也行這時候,你看到的是一個漆黑的光照貼圖。
沒關係,who care這個貼圖的顏色呢?我們繼續。
下面是採樣,這個光照貼圖:
float3 SampleLightProbe(SurfaceProperty sp)
{
#if defined LIGHTMAP_ON
return 0.0f;
#else
float4 coefficients[7];
coefficients[0] = unity_SHAr;
coefficients[1] = unity_SHAg;
coefficients[2] = unity_SHAb;
coefficients[3] = unity_SHBr;
coefficients[4] = unity_SHBg;
coefficients[5] = unity_SHBb;
coefficients[6] = unity_SHC;
return max(0.0, SampleSH9(coefficients, sp.normal));
#endif
}
這裏使用SampleSH9的方法。
當然,還需要物體表面的法線(世界法線)。
最後的結果,可以在片段着色器中直接返回LightProbe的顏色:
咦,這樣就採樣處理,light probe的顏色了。
2、light probe proxy volume的使用
上面是對小物件的使用light probe的信息,計算出顏色。然而對於大物件,這種方式不足了。因爲大物件,很難通過一個位置,去計算收到哪幾個球的影響,所以unity提供了Light probe proxy volume的組件,讓其大物件能夠收到多個球的影響。
如下:
如圖所示,這物體掛了一個LightProbeProxyVolume組件,然後設置了
ok,這是第一步,如何採樣呢?
如下所示:
float3 SampleLightProbe(SurfaceProperty sp)
{
#if defined LIGHTMAP_ON
return 0.0f;
#else
if (unity_ProbeVolumeParams.x) //這個x分量爲1,表示使用LPPV組件了,unity自動判斷
{
//return float3(1, 1, 0);
return SampleProbeVolumeSH4(
TEXTURE3D_ARGS(unity_ProbeVolumeSH, samplerunity_ProbeVolumeSH),
sp.position, sp.normal,
unity_ProbeVolumeWorldToObject,
unity_ProbeVolumeParams.y, unity_ProbeVolumeParams.z,
unity_ProbeVolumeMin.xyz, unity_ProbeVolumeSizeInv.xyz
);
}
else
{
//return float3(1, 0, 0);
float4 coefficients[7];
coefficients[0] = unity_SHAr;
coefficients[1] = unity_SHAg;
coefficients[2] = unity_SHAb;
coefficients[3] = unity_SHBr;
coefficients[4] = unity_SHBg;
coefficients[5] = unity_SHBb;
coefficients[6] = unity_SHC;
return max(0.0, SampleSH9(coefficients, sp.normal));
}
#endif
}
函數:SampleProbeVolumeSH4需要諸多參數:
unity_ProbeVolumeSH——圖,由unity自動提供(後面再看看,如何動態的設置)
samplerunity_ProbeVolumeSH——採樣器
sp.position, sp.normal——物體世界座標位置,世界法線
unity_ProbeVolumeWorldToObject,
unity_ProbeVolumeParams.y, unity_ProbeVolumeParams.z,
unity_ProbeVolumeMin.xyz, unity_ProbeVolumeSizeInv.xyz————————都是unity的內置變量
ok,最後效果:
如果不使用LPPV則是:
可見,不使用LPPV,顏色稍微單調了許多,好像就一個顏色,而使用了LPPV在顏色又明顯的起伏效果。這大概就是LPPV的作用了。
注意點:
1、如何查看一個物體收到的light probe的影響呢?
第一要在srp中畫gizmos:
private void RenderOneCamera(Camera camera)
{
……
DrawGizmos(camera);
m_context.Submit();
}
private void DrawGizmos(Camera camera)
{
if(Handles.ShouldRenderGizmos() && camera.cameraType == CameraType.SceneView)
{
m_context.DrawGizmos(camera, GizmoSubset.PreImageEffects);
m_context.DrawGizmos(camera, GizmoSubset.PostImageEffects);
}
}
2、如何正確採樣lightprobe、LPPV、以及光照貼圖呢?
要讓畫物體的時候,讓其傳遞給shader數據:
DrawingSettings drawingSettings = new DrawingSettings(m_shaderTagId, sortingSettings);
drawingSettings.perObjectData = PerObjectData.Lightmaps | PerObjectData.LightProbe | PerObjectData.LightProbeProxyVolume;
3、如果scene下的選中的物體,受到的light probe影響的四面體線,有偏移了咋辦呢?
這可能是你的shader,沒有使用:
#pragma multi_compile_instancing
以及,頂點着色器要正確的設置:
v2f vert (appdata input)
{
v2f output;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
ok,講到這裏差不多了,後面有新的內容,繼續再更新。
本文是在srp的基礎上講解,當然要正確的導入core rp的包,然後,#include對應的函數文件,才能使shader編譯正常。