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

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

相关推荐
还是大剑师兰特15 小时前
Unity3D(Unity)完整详细介绍
unity·游戏引擎
ellis197018 小时前
u3d插件xLua[七]例6 Coroutine
unity
还是大剑师兰特19 小时前
Unity 从零搭建简易3D场景(新手分步教程)
3d·unity·游戏引擎
神码编程20 小时前
【Unity】TankBattle联机坦克大战(三)创建关卡(生成地块)
unity·游戏引擎·帧同步·坦克大战
淡海水20 小时前
C#与常用数据结构源码剖析-全篇导览
开发语言·数据结构·unity·面试·职场和发展·c#
玖玥拾2 天前
Unity3D RPG 入门项目(四)背包拖拽、物品悬浮提示、项目开发思维
3d·unity·游戏引擎
xcLeigh2 天前
Unity基础:Start与Update方法——Unity脚本生命周期初探
java·unity·游戏引擎·教程
郝学胜-神的一滴2 天前
[简化版 GAMES 104] 现代游戏引擎 05:游戏引擎世界构建核心机制深度解析
c++·程序人生·unity·游戏引擎·计算机图形学·opengl
LONGZETECH3 天前
无人机实训高成本痛点解法:虚拟仿真实现 70% 耗材损耗下降
大数据·算法·unity·架构·无人机
五仁烧饼3 天前
Unity Addressables 静默资源策略
游戏·unity·addressables