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中可找到定义

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

相关推荐
躺下睡觉~9 小时前
Unity-Transform类-父子关系
java·unity·游戏引擎
躺下睡觉~9 小时前
Unity-Transform类-缩放和看向
unity·游戏引擎
君莫愁。11 小时前
【Unity】检测鼠标点击位置是否有2D对象
unity·c#·游戏引擎
咩咩觉主12 小时前
Unity实战案例全解析:PVZ 植物卡片状态分析
unity·c#·游戏引擎
蓝裕安15 小时前
伪工厂模式制造敌人
开发语言·unity·游戏引擎
谢泽浩19 小时前
Unity 给模型贴上照片
unity·游戏引擎
z2014z19 小时前
Unity Resource System 优化笔记
unity·游戏引擎
王维志19 小时前
Unity 高亮插件HighlightPlus介绍
unity·游戏引擎
zaizai100720 小时前
我的demo保卫萝卜中的技术要点
unity
菌菌巧乐兹1 天前
Unity 百度AI实现无绿幕拍照抠像功能(详解版)
人工智能·百度·unity