Unity SRP 管线【第三讲:URP 光照】

3.2.3 以前属于Shader部分,Shader部分不进行讲解。

这里只涉及Unity内部管线的设置问题。

文章目录

3.2.3 向GPU发送灯光数据

UniversalRenderPipeline.cs > RenderSingleCamera()下调用函数renderer.Execute()

该函数走向ScriptableRenderer.cs>Execute()函数,该函数调用了SetupLights()函数

SetupLights()函数为一个虚函数

具体实现在UniversalRenderer.cs>SetupLights()

该方法调用了m_ForwardLights实例下的_ForwardLights.Setup(context, ref renderingData);方法

URP中关于前向渲染的灯光设置,即在ForwardLights.cs

SetUp()函数将来自于ref RenderingData renderingData中的灯光数据发送到GPU。

csharp 复制代码
public void Setup(ScriptableRenderContext context, ref RenderingData renderingData)
{
	CommandBuffer cmd = CommandBufferPool.Get();
	using (new ProfilingScope(null, m_ProfilingSampler))
	{
		// 设置ClusteredRendering(Forward+)属性参数
		if (useClusteredRendering){
			...
		}
	
		// 设置Shader常量属性
		SetupShaderLightConstants(cmd, ref renderingData);
		
		// 设置Shader关键字
	    bool lightCountCheck = (renderingData.cameraData.renderer.stripAdditionalLightOffVariants && renderingData.lightData.supportsAdditionalLights) || additionalLightsCount > 0;
	    CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.AdditionalLightsVertex,
	        lightCountCheck && additionalLightsPerVertex && !useClusteredRendering);
	    CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.AdditionalLightsPixel,
	        lightCountCheck && !additionalLightsPerVertex && !useClusteredRendering);
	    CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.ClusteredRendering,
	        useClusteredRendering);
	    ...
	
		// 设置LightCookie(灯光遮罩)
		m_LightCookieManager.Setup(context, cmd, ref renderingData.lightData);
	 }
	 context.ExecuteCommandBuffer(cmd);
	 CommandBufferPool.Release(cmd);
}

其中,关键字【ShaderKeywordStrings.AdditionalLightsVertex】 在 UniversalRenderPipelineCore中定义

设置光源数据

注意:这里使用引用传递传递RenderingData ,因为RenderingData 结构的数据量很大。

csharp 复制代码
void SetupShaderLightConstants(CommandBuffer cmd, ref RenderingData renderingData)
{
    m_MixedLightingSetup = MixedLightingSetup.None;

    // 主光源有一个优化的主光源着色器路径。这将有利于那些只关心单一光线的游戏。
    // 通用管道也只支持单个阴影光,如果可用,它将是主光源。
    SetupMainLightConstants(cmd, ref renderingData.lightData);
    
    SetupAdditionalLightConstants(cmd, ref renderingData);
}

设置主光源

在ForwardLight中设置了如下GPU参数

csharp 复制代码
void SetupMainLightConstants(CommandBuffer cmd, ref LightData lightData)
{
    Vector4 lightPos, lightColor, lightAttenuation, lightSpotDir, lightOcclusionChannel;
    uint lightLayerMask;
    // 根据visibleLights[mainLightIndex]数据,获取out的如下数据
    InitializeLightConstants(lightData.visibleLights, lightData.mainLightIndex, 
    	out lightPos, out lightColor, out lightAttenuation, 
    	out lightSpotDir, out lightOcclusionChannel, out lightLayerMask);

	// 将数据
    cmd.SetGlobalVector(LightConstantBuffer._MainLightPosition, lightPos);
    cmd.SetGlobalVector(LightConstantBuffer._MainLightColor, lightColor);
    cmd.SetGlobalVector(LightConstantBuffer._MainLightOcclusionProbesChannel, lightOcclusionChannel);
    cmd.SetGlobalInt(LightConstantBuffer._MainLightLayerMask, (int)lightLayerMask);
}

其中,InitializeLightConstants函数如下

csharp 复制代码
void InitializeLightConstants(NativeArray<VisibleLight> lights, int lightIndex, out Vector4 lightPos, out Vector4 lightColor, out Vector4 lightAttenuation, out Vector4 lightSpotDir, out Vector4 lightOcclusionProbeChannel, out uint lightLayerMask)
{
	// 得到前5个数据
    UniversalRenderPipeline.InitializeLightConstants_Common(lights, lightIndex, out lightPos, out lightColor, out lightAttenuation, out lightSpotDir, out lightOcclusionProbeChannel);

	// 得到lightLayerMask 
    lightLayerMask = 0;
    ...
    lightLayerMask = (uint)additionalLightData.lightLayerMask;
}

设置额外点光源

额外光源与主光源相同,只是传入的数据是一个数组,数组长度与最大额外光源数相同。

核心函数:

csharp 复制代码
InitializeLightConstants(lights, i, 
				out m_AdditionalLightPositions[lightIter],
				out m_AdditionalLightColors[lightIter],
			    out m_AdditionalLightAttenuations[lightIter],
			    out m_AdditionalLightSpotDirections[lightIter],
			    out m_AdditionalLightOcclusionProbeChannels[lightIter],
			    out lightLayerMask);

Shader中的数据

在URP>Input.hlsl中可找到定义

之后便可以用这些光照数据计算着色~~~

相关推荐
Sator15 小时前
Unity关于射击游戏人物动画的设计经验
游戏·unity·游戏引擎
冰凌糕5 小时前
Unity3D Shader 坐标空间详解
unity
心前阳光1 天前
Unity之ScrollRect简易实现
unity·游戏引擎
WarrenMondeville1 天前
9.Unity面向对象-对象池
unity
KaGme1 天前
生成3DGS场景在unity中的呈现
3d·unity·游戏引擎
zyh______2 天前
关于unity的序列化
unity·游戏引擎
星夜泊客2 天前
C# : 引用类型都存在堆上吗
unity·c#
点量云实时渲染-小芹2 天前
Unity模型数字孪生虚拟仿真webgl推流卡实时云渲染推流
unity·webgl·数字孪生·实时云渲染·虚拟仿真·云推流
mxwin2 天前
Unity Shader 齐次坐标与透视除法理解 SV_POSITION 的 w 分量
unity·游戏引擎·shader
NPUQS2 天前
【Unity 3D学习】Unity 与 Python 互通入门:点击按钮调用 Python(超简单示例)
学习·3d·unity