Unity SRP 管线【第九讲:URP 点光源与聚光灯】

2024-02-02 22:52

本文主要是介绍Unity SRP 管线【第九讲:URP 点光源与聚光灯】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • CPU数据搜集
  • GPU数据使用
  • 光照计算

在这里插入图片描述

CPU数据搜集

我们只能支持有限数量的其他灯。并将这些灯光数据(位置、颜色、阴影强度、方向光光源、灯光遮蔽Probe、灯光层级Mask)发送到GPU以供场景中所有物体渲染使用。

//ForwardLights.cs
在这里插入图片描述
额外光源数量与使用的平台以及API有关

  • 如果是移动端 并且 使用OpenGLES2、OpenGLES3(小于OpenGLES30版本),则最大额外光源数为16
  • 否则,如果是移动端 或着 PC端使用OpenGLCore、OpenGLES2、OpenGLES3,则最大额外光源数为32
  • 否则,最大额外光源数为256(即PC端使用OpenGL3.0以上版本、或其他API)

//UniversalRenderPipeline.cs
在这里插入图片描述
遍历场景获取所有光源数据

// ForwardLights.cs
//Setup() > SetupShaderLightConstants() > SetupAdditionalLightConstants()
循环遍历所有光源
在这里插入图片描述
InitializeLightConstants() > InitializeLightConstants_Common()
处理单个光源数据,获取数据保存到LightConstantBuffer中

关于SpotLight的衰减值,定义在
//UniversalRenderPipelineCore.cs
在这里插入图片描述
最终,将Buffer发送到GPU
在这里插入图片描述

GPU数据使用

输入的光线信息变量保存在Input.hlsl
在这里插入图片描述
获取这些信息的函数保存在realtimeLights.hlsl

// Fills a light struct given a perObjectLightIndex
Light GetAdditionalPerObjectLight(int perObjectLightIndex, float3 positionWS)

因为我们计算逐个对象需要的并不是所有光源,而是对该对象贡献最大的几个光源(Unity中一般设置为4个),因此,需要告诉管线我们需要这些数据。
在drawingSettings 中设置

perObjectData |= PerObjectData.LightData | PerObjectData.LightIndices;

即可得到Unity定义在UnityInput中的数据

// Light Indices block feature
// These are set internally by the engine upon request by RendererConfiguration.
half4 unity_LightData;
half4 unity_LightIndices[2];

half4 unity_LightData;

  • x : GetPerObjectLightIndexOffset(),一般为0
  • y:影响单个物体灯光的数量保存在unity_LightData.y。GetAdditionalLightsCount(),该数量可能超过最大渲染灯光数。
  • z: light.distanceAttenuation = unity_LightData.z; // unity_LightData.z is 1 when not culled by the culling mask, otherwise 0.

half4 unity_LightIndices[2];
每个需要计算的灯光下标保存在half4 unity_LightIndices[2]中,共8个int,因此最大支持每个物体8个光源。
该下标通过RealtimeLights.hlsl中的GetPerObjectLightIndex()获得

int GetPerObjectLightIndex(uint index)
{
//一般情况float4 tmp = unity_LightIndices[index / 4];return int(tmp[index % 4]);
}

额外光源信息获取,全套使用流程:

#if defined(_ADDITIONAL_LIGHTS)uint pixelLightCount = GetAdditionalLightsCount();LIGHT_LOOP_BEGIN(pixelLightCount)// lightIndexLight light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers)){lightingData.additionalLightsColor += LightingPhysicallyBased(brdfData, brdfDataClearCoat, light,inputData.normalWS, inputData.viewDirectionWS,surfaceData.clearCoatMask, specularHighlightsOff);}LIGHT_LOOP_END
#endif

其中使用的函数:

  1. 获取额外光源数量(_AdditionalLightsCount.x为我们设置的对象可接受的最大额外光源数)
int GetAdditionalLightsCount()
{
#if USE_CLUSTERED_LIGHTING// Counting the number of lights in clustered requires traversing the bit list, and is not needed up front.return 0;
#else// TODO: we need to expose in SRP api an ability for the pipeline cap the amount of lights// in the culling. This way we could do the loop branch with an uniform// This would be helpful to support baking exceeding lights in SH as wellreturn int(min(_AdditionalLightsCount.x, unity_LightData.y));
#endif
}
  1. 获取光源下标后,获取光照信息
Light GetAdditionalLight(uint i, float3 positionWS)
{
#if USE_CLUSTERED_LIGHTINGint lightIndex = i;
#elseint lightIndex = GetPerObjectLightIndex(i);
#endifreturn GetAdditionalPerObjectLight(lightIndex, positionWS);
}

光照计算

此处便不再说明光照计算

unity会根据是否添加额外光照,添加关键字_ADDITIONAL_LIGHTS

这篇关于Unity SRP 管线【第九讲:URP 点光源与聚光灯】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/672224

相关文章

Unity Post Process Unity后处理学习日志

Unity Post Process Unity后处理学习日志 在现代游戏开发中,后处理(Post Processing)技术已经成为提升游戏画面质量的关键工具。Unity的后处理栈(Post Processing Stack)是一个强大的插件,它允许开发者为游戏场景添加各种视觉效果,如景深、色彩校正、辉光、模糊等。这些效果不仅能够增强游戏的视觉吸引力,还能帮助传达特定的情感和氛围。 文档

Unity协程搭配队列开发Tips弹窗模块

概述 在Unity游戏开发过程中,提示系统是提升用户体验的重要组成部分。一个设计良好的提示窗口不仅能及时传达信息给玩家,还应当做到不干扰游戏流程。本文将探讨如何使用Unity的协程(Coroutine)配合队列(Queue)数据结构来构建一个高效且可扩展的Tips弹窗模块。 技术模块介绍 1. Unity协程(Coroutines) 协程是Unity中的一种特殊函数类型,允许异步操作的实现

OpenGL ES 2.0渲染管线

http://codingnow.cn/opengles/1504.html Opengl es 2.0实现了可编程的图形管线,比起1.x的固定管线要复杂和灵活很多,由两部分规范组成:Opengl es 2.0 API规范和Opengl es着色语言规范。下图是Opengl es 2.0渲染管线,阴影部分是opengl es 2.0的可编程阶段。   1. 顶点着色器(Vert

培训第九周(部署k8s基础环境)

一、前期系统环境准备 1、关闭防火墙与selinux  [root@k8s-master ~]# systemctl stop firewalld[root@k8s-master ~]# systemctl disable firewalldRemoved symlink /etc/systemd/system/multi-user.target.wants/firewalld.servi

Unity 资源 之 Super Confetti FX:点亮项目的璀璨粒子之光

Unity 资源 之 Super Confetti FX:点亮项目的璀璨粒子之光 一,前言二,资源包内容三,免费获取资源包 一,前言 在创意的世界里,每一个细节都能决定一个项目的独特魅力。今天,要向大家介绍一款令人惊艳的粒子效果包 ——Super Confetti FX。 二,资源包内容 💥充满活力与动态,是 Super Confetti FX 最显著的标签。它宛如一位

Unity数据持久化 之 一个通过2进制读取Excel并存储的轮子(4)

本文仅作笔记学习和分享,不用做任何商业用途 本文包括但不限于unity官方手册,unity唐老狮等教程知识,如有不足还请斧正​​ Unity数据持久化 之 一个通过2进制读取Excel并存储的轮子(3)-CSDN博客  这节就是真正的存储数据了   理清一下思路: 1.存储路径并检查 //2进制文件类存储private static string Data_Binary_Pa

Unity Adressables 使用说明(一)概述

使用 Adressables 组织管理 Asset Addressables 包基于 Unity 的 AssetBundles 系统,并提供了一个用户界面来管理您的 AssetBundles。当您使一个资源可寻址(Addressable)时,您可以使用该资源的地址从任何地方加载它。无论资源是在本地应用程序中可用还是存储在远程内容分发网络上,Addressable 系统都会定位并返回该资源。 您

『功能项目』更换URP场景【32】

上一章已经将项目从普通管线升级到了URP管线 现在我们打开上一篇31项目优化 - 默认管线转URP的项目, 进入战斗场景 将Land的子级全部隐藏 将新的URP场景预制体拖拽至Land子级 对场景预制体完全解压缩 将Terrain拖拽至Land的直接子级 将Terrain设置为Land 与 静态Static 清除烘培 重新烘培 修改脚本:LoadRe

Unity Adressables 使用说明(六)加载(Load) Addressable Assets

【概述】Load Addressable Assets Addressables类提供了加载 Addressable assets 的方法。你可以一次加载一个资源或批量加载资源。为了识别要加载的资源,你需要向加载方法传递一个键或键列表。键可以是以下对象之一: Address:包含你分配给资源的地址的字符串。Label:包含分配给一个或多个资源的标签的字符串。AssetReference Obj

在Unity环境中使用UTF-8编码

为什么要讨论这个问题         为了避免乱码和更好的跨平台         我刚开始开发时是使用VS开发,Unity自身默认使用UTF-8 without BOM格式,但是在Unity中创建一个脚本,使用VS打开,VS自身默认使用GB2312(它应该是对应了你电脑的window版本默认选取了国标编码,或者是因为一些其他的原因)读取脚本,默认是看不到在VS中的编码格式,下面我介绍一种简单快