Unity SRP 管线【第七讲:URP LOD实现以及Reflections反射探针】

news2025/2/4 12:45:17

目录

  • 一、URP LOD 组件
    • 1、LOD Group的使用
    • 2、LOD切换原理
      • Cross Fade(淡入淡出)模式
        • Animated Cross-Fading
        • 如果未设置Clip,并且Fade Transition Width不为0
        • LOD物体烘培
      • SpeedTree 模式
  • 二、反射探针
    • 1. 获取反射探针数据
    • 2. 环境光照明 IBL
    • 3. 反射探针(Reflection Probes)
      • 解码探针
    • 4. Box Projection 盒体投影

在这里插入图片描述
中文版:https://edu.uwa4d.com/lesson-detail/282/1314/0?isPreview=0
英文原版:https://catlikecoding.com/unity/tutorials/custom-srp/lod-and-reflections/

一、URP LOD 组件

在这里插入图片描述

1、LOD Group的使用

1. 首先该组件需要将子类模型置于该组件物体子节点下
在这里插入图片描述
2. 可在单个LOD中设置其level的模型,并可设置它的距离范围,即可在不同距离下显示不同的模型
在这里插入图片描述

若模型变化时间不符合预期,有如下几种方式调节:

  1. 重新继续Bound,Unity会根据三种LOD模型计算该模型的包围盒,从而在计算物体占屏幕
    在这里插入图片描述2. Project Settings > Quality > Level of Detail > LOD Bias, 该变量增大物体的评估高度,从而导致LOD切换时占比与实践物体占比不同。将 LOD Bias设为1,可以使组件阈值与实际大小同步。
    在这里插入图片描述
  2. LOD过渡类型:
    在这里插入图片描述
    • Cross Fade(淡入淡出),Fade Transition Width可调节过渡区域占比
      在这里插入图片描述

2、LOD切换原理

Cross Fade(淡入淡出)模式

当启用Cross Fade(淡入淡出)模式,相邻两个LOD对象会同时渲染出来,着色器将以某种方式进行混合。Unity通常使用屏幕抖动或者混合来实现Cross Fade。

在URP通用管线中,LOD现只用于SpeedTree7XXX.shader,即大面积树木的渲染,其余Shader并未使用,但并不代表不可以自定义。

我们可以通过UnityPerDraw下的变量float4 unity_LODFade; 取得LOD信息

CBUFFER_START(UnityPerDraw)
	float4 unity_LODFade; 
	// x is the fade value ranging within [0,1]. 
	// y is x quantized into 16 levels
CBUFFER_END
  • x分量存储过渡因子(逐渐远离消失的LOD对象,x分量从1变换到0;渐入的LOD对象,x分量从0变换到 -1
  • y分量存储了相同的因子,只不过被量化为16步

即,若渐出LOD的x值为0.4,则渐入LOD的值为 -0.6

我们可以通过一个Noise图来决定使用哪一级LOD的选择。

通过如下内置函数,即可快速得到一个Noise图
float dither = InterleavedGradientNoise(positionCS.xy, 0);

使用屏幕抖动实现LOD混合

void ShadowCasterPassFragment (Varyings input) {
	UNITY_SETUP_INSTANCE_ID(input);
	ClipLOD(input.positionCS.xy, unity_LODFade.x);}

void ClipLOD (float2 positionCS, float fade) {
	#if defined(LOD_FADE_CROSSFADE)
		float dither = InterleavedGradientNoise(positionCS.xy, 0);
		clip(fade + (fade < 0.0 ? dither : -dither));
	#endif
}

Animated Cross-Fading

启用Animated Cross-Fading后,不再通过距离去设置渐入渐出的比例,当物体组比例超过LOD阈值就通过动画快速交叉渐变。

默认的动画持续时间为半秒,可以通过设置static LODGroup.crossFadeAnimationDuration来更改所有组的动画持续时间。然而,在unity2022中,当不在播放模式下,转换速度更快。

如果未设置Clip,并且Fade Transition Width不为0

则,当距离处于交叉切换之间,会使两个物体同时被渲染出来。
在这里插入图片描述
因此,如果未实现LOD交叉切换算法,请不要使用CrossFade选项。

LOD物体烘培

LOD0会被用于光照映射(Lightmapping)。其他LOD级别也会得到烘焙照明(Baked Light),但场景的其余部分只考虑LOD 0。你也可以决定只烘焙一些级别,让其他级别依靠光探针。

SpeedTree 模式

这种模式是专门针对SpeedTree树的,它使用自己的LOD系统来折叠树,并在3D模型和广告牌表示之间进行转换。
在这里插入图片描述

二、反射探针

1. 获取反射探针数据

  1. 如果未定义LightMap(烘培光照),则会使用球谐函数作为基础环境光颜色。此球谐函数即为环境球的球谐采样结果。
  2. 若想使用IBL作为镜面反射,需要添加反射探针标志。
perObjectData |= PerObjectData.ReflectionProbes;

2. 环境光照明 IBL

在Unity中,IBL环境光照贴图保存在UnityInput.hlsl

// Unity specific
TEXTURECUBE(unity_SpecCube0);
SAMPLER(samplerunity_SpecCube0);
TEXTURECUBE(unity_SpecCube1);
SAMPLER(samplerunity_SpecCube1);

在GlobalIllumination.hlsl中,使用函数

half3 CalculateIrradianceFromReflectionProbes(half3 reflectVector, float3 positionWS, half perceptualRoughness)

即可得到环境光照。函数中使用

half4 encodedIrradiance = half4(SAMPLE_TEXTURECUBE_LOD(unity_SpecCube0, samplerunity_SpecCube0, reflectVector, mip));

得到CubeMap Mipmap插值采样结果,并根据是否使用HDR解码。

#if defined(UNITY_USE_NATIVE_HDR)
        irradiance += weightProbe0 * encodedIrradiance.rbg;
#else
        irradiance += weightProbe0 * DecodeHDREnvironment(encodedIrradiance, unity_SpecCube0_HDR);
#endif // UNITY_USE_NATIVE_HDR

SAMPLE_TEXTURECUBE_LOD函数根据使用的API不同,实现各不相同
在这里插入图片描述

IBL在URP Shader中,通过如下函数得到包括环境光照在内的所有全局光照。

lightingData.giColor = GlobalIllumination(brdfData, brdfDataClearCoat, surfaceData.clearCoatMask,
                                          inputData.bakedGI, aoFactor.indirectAmbientOcclusion, inputData.positionWS,
                                          inputData.normalWS, inputData.viewDirectionWS);
half3 reflectVector = reflect(-viewDirectionWS, normalWS);
half NoV = saturate(dot(normalWS, viewDirectionWS));
half fresnelTerm = Pow4(1.0 - NoV);

half3 indirectDiffuse = bakedGI;
half3 indirectSpecular = GlossyEnvironmentReflection(reflectVector, positionWS, brdfData.perceptualRoughness, 1.0h);

half3 color = EnvironmentBRDF(brdfData, indirectDiffuse, indirectSpecular, fresnelTerm);
  • bakedGI值为LightMap烘培光照数据,或者是环境球谐的采样结果。
  • 通过GlossyEnvironmentReflection计算基于环境的镜面反射光照
  • 最后通过EnvironmentBRDF函数获取混合结果(漫反射颜色 * 漫反射系数 + 镜面反射颜色 * 镜面反射系数)。
half3 EnvironmentBRDF(BRDFData brdfData, half3 indirectDiffuse, half3 indirectSpecular, half fresnelTerm)
{
    half3 c = indirectDiffuse * brdfData.diffuse;
    c += indirectSpecular * EnvironmentBRDFSpecular(brdfData, fresnelTerm);
    return c;
}

3. 反射探针(Reflection Probes)

在场景中未使用反射探针时,场景中具有反射(包括镜面反射Specular和金属反射Metallic)的物体会使用天空贴图(包括天空面 Sky Plane / 天空盒 Sky Box / 天空球 Sky Dome)的信息来制作反射效果。

默认的 environment cube map 只包含天空盒。为了反射场景中的其他东西,我们必须通过GameObject / Light / reflection probe为其添加反射探针。这些探测器在它们的位置处看向场景,将场景渲染为立方体贴图。因此,只有在靠近探测器的表面上,反射才会显得或多或少正确。因此,通常需要在一个场景中放置多个探头。它们具有Importance和Box Size属性,可用于控制每个探针影响的区域。
在这里插入图片描述

探测器的Type默认设置为Baked,这意味着它只渲染一次,CubeMap在构建时渲染。你也可以将其设置为实时,这将使地图与动态场景保持同步。它像任何其他相机一样被渲染,使用我们的RP,对立方体地图的六个面分别渲染一次。所以实时反射探测器很昂贵。

每个对象只使用一个环境探针,但场景中可以有多个探针。因此,你可能不得不 split 对象以获得 acceptable(理想的) 的反射。例如,理想情况下,用于构建结构的立方体应该分成单独的内部和外部部分,这样每个部分都可以使用不同的反射探头。此外,这意味着GPU batching 会被反射探针破坏。不幸的是,网格球根本不能使用反射探针,所以渲染出来的总是天空盒。
在这里插入图片描述

MeshRenderer组件有一个Anchor Override(直接将带有Probe的物体拖上去就好),可以用来微调它们使用的探针,而不必担心盒子的大小和位置。还有一个Reflection Probes,默认设置为Blend Probes。我们的想法是,Unity允许在最好的两个反射探针之间进行混合。然而,这种模式与SRP批处理程序不兼容,所以Unity的其他rp不支持它,我们也不支持。如果你很好奇,我在2018年SRP教程的反射教程中解释了如何混合探针,但我希望这个功能在遗留管道被删除后消失。
在这里插入图片描述
我们将在将来研究其他反射技术。所以仅有的两个功能模式是Off,它总是使用天空盒子,和Simple,它选择最重要的探测器。其他的功能和Simple完全一样。

除此之外,反射探针还可以选择启用box projection mode。这将改变如何确定反射以更好地匹配其有限的影响区域,但SRP批处理程序也不支持这一点,因此我们也不支持它。

:物体在选择反射探针时,确定物体是否在探针包围盒内,如果在,则加入列表;再根据所有影响物体的反射探针的权重,只保留权重最大的一批(若有2个权重为5,3个权重为3,则只保留权重为5的探针),再根据交叉体积权重计算保留的反射探针的系数。
特别的,当大包围盒反射探针完全覆盖小包围盒反射探针,且物体处于小包围盒反射探针内,则默认最小包围盒探针为最重要探针。

解码探针

最后,我们必须确保正确地解释来自CubeMap的数据。它可以是HDR或LDR,其强度也可以调节。这些设置是通过unity_SpecCube0_HDR矢量提供的,它在UnityPerDraw缓冲区中的unity_ProbesOcclusion之后。

// Reflection Probe 0 block feature
// HDR environment map decode instructions
real4 unity_SpecCube0_HDR;
real4 unity_SpecCube1_HDR;

解码函数:

float3 SampleEnvironment (Surface surfaceWS, BRDF brdf) {return DecodeHDREnvironment(environment, unity_SpecCube0_HDR);
}

4. Box Projection 盒体投影

引自:技术美术杂谈 反射探针(Reflection Probe)

在未开启盒体投影时,反射贴图的图像通常是通过从无限远处投射的。

开启盒体投影允许我们使用探针包围盒尺寸Probe Size 、探针包围盒偏移 Probe Offset 以及镜头与反射物体的距离作为参数,控制反射探针所生成的反射贴图的尺寸和效果。

通常情况下,Unity默认开启反射探针的盒体投影支持。如果想自定义不同画面质量是否支持盒体投影效果,可以在编辑面板 Edit →项目设置 Project Settings →图像设置 Graphics →画面分级设置 Tier Settings 中取消勾选使用默认设置 Use Defaults ,并进行自定义设置。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1427240.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

创业公司的项目经理,如何有效争取股权激励

摘要&#xff1a;PM圆桌派&#xff0c;思考要快&#xff0c;行动要快。希赛聚集了一群有追求的PM校友&#xff0c;在一起谈天说地。在这里&#xff0c;我们无问对错&#xff0c;不论输赢&#xff0c;不分高下&#xff0c;每周四&#xff0c;一期一个话题battle&#xff0c;将真…

LeetCode--189

189. 轮转数组 提示 给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: [6,7,1,2,3,4,5] 向右轮转…

ele-h5项目使用vue3+vite开发:第一节、页面头部实现

实现页面 确认需求 顶部提示栏搜索框搜索提示 normalize.css:处理不同浏览器的默认样式 安装 npm i normalize.css 使用 src\App.vue<style scoped> import normalize.css;#app {/** 让字体抗锯齿&#xff0c;看起来更清晰 */-webkit-font-smoothing: antialiased;-moz-o…

面试中问到的算法题。————目录树生成

前言 我在面试中遇到了算法题&#xff0c;也是我第一次面试&#xff0c;也不知道是太紧张了还是太久没刷算法题了&#xff0c;感觉压有点懵的状态&#xff0c;所以当时面试的时候没有做出来或者说只做了一半没有做完。 面试完成后&#xff0c;我又重新审视了一下题目&#xff…

【送书福利-第三十一期】《区块链安全理论与实践(安全技术经典译丛)》

&#x1f60e; 作者介绍&#xff1a;我是程序员洲洲&#xff0c;一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主、前后端开发、人工智能研究生。公粽号&#xff1a;程序员洲洲。 &#x1f388; 本文专栏&#xff1a;本文…

Xline Jepsen 测试分析

Table of Contents 摘要背景介绍 XlineJepsen CheckersNemesisJepsen 测试设计 数据一致性 SerializabilityLinearizabilityStrict SerializabilityJepsen etcd test RegistersSetsAppendWRJepsen Xline test测试结果分析 测试结果异步落盘Revision生成 背景旧的实现分析1-RTT…

九、Qt图表使用

一、QCharts概述 Qt图表提供了&#xff1a;折线图、样条曲线图、面积图、散点图、条形图、饼图、方块胡须图、蜡烛图、极坐标图。1、QChart介绍 Qt Charts基于Qt的QGraphics View架构&#xff0c;其核心组件是QChartView和QChartQChartView是显示图标的视图&#xff0c;基类为…

如何用gpt快速做好数据分析?

由于技术限制&#xff0c;目前InfinitePaper AI仅支持上传1份文件&#xff0c;且大小不超过10M。但是&#xff0c;在强大的代码解释器面前&#xff0c;这都是小问题。我们只需要将可能用到的文件打包成压缩文件上传即可&#xff0c;之后要求GPT直接解压就能正常完成后续需求。 …

Vue学习之使用HBuilderX创建并使用vue3.0项目

Vue学习之使用HBuilderX创建并使用vue3.0项目 下文将简述如何使用HBuilderX创建并使用vue3.0项目&#xff0c;包含项目创建、目录介绍、如何引用组件、首页自定义设置。 1、创建vue3.0项目 具体操作之前章节已经阐述过不在冗余介绍&#xff0c;创建时选择vue3项目即可。vue2…

2023年03月CCF-GESP编程能力等级认证Python编程二级真题解析

Python等级认证GESP(1~6级)全部真题・点这里 一、单选题(共15题,共30分) 第1题 以下存储器中的数据不会受到附近强磁场干扰的是( )。 A:硬盘 B:U 盘 C:内存 D:光盘 答案:D 第2题 下列流程图,属于计算机的哪种程序结构?( ) A:顺序结构 B:循环结构 C:…

《Lua程序设计》-- 学习10

环境&#xff08;Environment&#xff09; 具有动态名称的全局变量 全局变量的声明 由于Lua语言将全局变量存放在一个普通的表中&#xff0c;所以可以通过元表来发现访问不存在全局变量的情况。 正如前面所提到的&#xff0c;我们不允许值为nil的全局变量&#xff0c;因为值为…

C语言·贪吃蛇游戏(上)

1. 游戏任务 使用C语言在Windows环境的控制台中模拟实现小游戏贪吃蛇 游戏中要包含以下功能&#xff1a; 1. 贪吃蛇地图绘制 2. 贪吃蛇上下左右移动和吃食物 3. 蛇撞墙&#xff0c;或撞到自身死亡 4. 计算得分 5. 蛇身加速、减速 6. 暂停游戏 2. Win32 API 介绍 Windows是一种多…

【MATLAB源码-第131期】基于matlab的淘金优化算法(GRO)机器人栅格路径规划,输出做短路径图和适应度曲线。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 淘金优化算法&#xff08;GoldRush Optimizer&#xff0c;简称GRO&#xff09;是一种启发式优化算法&#xff0c;它受到淘金过程的启发。在淘金过程中&#xff0c;淘金者在河流或矿区中寻找金矿&#xff0c;通过筛选沙砾来寻…

病历管理系统

技术架构&#xff1a; StrutsSpringHibernate 有需要该项目的小伙伴可以私信我你的Q。 功能描述&#xff1a; 企业财务管理系统主要用于电子病历来提高医院各项工作的效率和质量&#xff0c;促进医学科研、教学&#xff1b;减轻各类事务性工作的劳动强度&#xff0c;使他们…

2024美赛选题建议+ABCDEF思路分享

选题建议 A题 题目见&#xff1a; https://zxljhy.blog.csdn.net/article/details/135985116https://zxljhy.blog.csdn.net/article/details/135985116建议&#xff1a; A题是机理分析&#xff0c;需要去找到合适的数据对物种发展规律进行研究&#xff0c;结合生态学原理和动…

Windows SDK(三)GDI图形绘制基础

GDI介绍 GDI:图形设备接口&#xff1a;Windows的子系统&#xff0c;负责在视讯显示器和打印机上显示图形。 GDI常见名词解释&#xff1a; 直线 曲线 填入区域&#xff1a;直线或曲线构成的封闭区域&#xff0c;可以用画刷进行填充 位图&#xff1a;点阵图像 文字 映…

DEV-C++ ege.h库 绘图教程合集

一、目录 DEV-C ege.h库 绘图教程&#xff08;一&#xff09;——基本绘图函数 DEV-C ege.h库 绘图教程&#xff08;二&#xff09;——高级绘图函数&#xff08;上&#xff09; DEV-C ege.h库 绘图教程&#xff08;三&#xff09;——高级绘图函数&#xff08;下&#xff09;时…

探索自然语言处理在改善搜索引擎、语音助手和机器翻译中的应用

文章目录 每日一句正能量前言文本分析语音识别机器翻译语义分析自然语言生成情感分析后记 每日一句正能量 努力学习&#xff0c;勤奋工作&#xff0c;让青春更加光彩。 前言 自然语言处理&#xff08;NLP&#xff09;是人工智能领域中与人类语言相关的重要研究方向&#xff0c…

day07-CSS高级

01-定位 作用&#xff1a;灵活的改变盒子在网页中的位置 实现&#xff1a; 1.定位模式&#xff1a;position 2.边偏移&#xff1a;设置盒子的位置 left right top bottom 相对定位 position: relative 特点&#xff1a; 不脱标&#xff0c;占用自己原来位置 显示模…

最长的指定瑕疵度的元音子串 - 华为OD统一考试

OD统一考试&#xff08;C卷&#xff09; 分值&#xff1a; 200分 题解&#xff1a; Java / Python / C 题目描述 开头和结尾都是元音字母&#xff08;aeiouAEIOU&#xff09;的字符串为元音字符串&#xff0c;其中混杂的非元音字母数量为其瑕疵度。比如: “a” 、 “aa” 是元…