srp中使用lightprobe和light probe proxy volume(簡稱LPPV)

本節主要參考:
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編譯正常。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章