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编译正常。

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