当前位置: 首页 > news >正文

Unity SRP 管线【第五讲:自定义烘培光照】

文章目录

  • 一、自定义烘培光照
    • 1. 烘培光照贴图
    • 2. 获取光照贴图
    • 3. 获取物体在光照贴图上的UV坐标
    • 4. 采样光照贴图
  • 二、自定义光照探针
  • 三、 Light Probe Proxy Volumes(LPPV)
  • 四、Meta Pass
  • 五、 自发光烘培

一、自定义烘培光照

细节内容详见catlikecoding.com
这里只做效果展示!!!!

1. 烘培光照贴图

  • 在Lighting中设置LightingSettingsAsset,
  • 并且将需要烘培的物体设置为ContributeGI
  • 将光照设置为Mixed或Baked
  • 最后点击GenerateLighting烘培,得到光照贴图
    在这里插入图片描述

2. 获取光照贴图

通过定义unity_Lightmap纹理即可获取光照贴图,整个场景的光照贴图全部集成在一张贴图中。

TEXTURE2D(unity_Lightmap);
SAMPLER(samplerunity_Lightmap);

因为整个场景的光照贴图都在一张贴图上,所以物体的UV坐标也不再是原本的UV坐标

3. 获取物体在光照贴图上的UV坐标

首先,需要Unity将每个烘培了光照的物体的光照贴图UV发送到GPU。
我们在CameraRenderer中设置drawingSettings 中的perObjectDataPerObjectData.Lightmaps

var drawingSettings = new DrawingSettings(unlitShaderTagID, sortingSettings)//使用哪个ShaderTagID,以什么一定顺序渲染的设定
{//动态合批enableDynamicBatching = useDynamicBatching,//实例化enableInstancing = useGPUInstancing,//光照贴图UV坐标perObjectData = PerObjectData.Lightmaps,
};

当开启 Lighting 窗口下的Baked Global Illumination按钮时,Unity会对打开Comtribute Global Illumination的物体写入宏_LIGHTMAP_ON
在这里插入图片描述
因此需要在需要光照烘培的Shader中定义

#pragma multi_compile _ LIGHTMAP_ON

Unity会将UV坐标作为顶点数据发送到顶点着色器
顶点着色器中作为TEXCOORD1(第二个纹理通道)进行输入

以下定义宏,来避免未开启光照烘培时的UV计算和输入

#if defined(LIGHTMAP_ON)#define GI_ATTRIBUTE_DATA float2 lightMapUV : TEXCOORD1;#define GI_VARYINGS_DATA  float2 lightMapUV : VAR_LIGHT_MAP_UV;#define TRANSFER_GI_DATA(input, output) output.lightMapUV = input.lightMapUV;#define GI_FRAGMENT_DATA(input)         input.lightMapUV
#else#define GI_ATTRIBUTE_DATA #define GI_VARYINGS_DATA  #define TRANSFER_GI_DATA(input, output) #define GI_FRAGMENT_DATA(input)				0.0      
#endif

并在着色器输入输出中添加GI_ATTRIBUTE_DATA、GI_VARYINGS_DATA

struct Attributes
{float3 positionOS : POSITION;float2 baseUV : TEXCOORD0;float3 normalOS : NORMAL;GI_ATTRIBUTE_DATAUNITY_VERTEX_INPUT_INSTANCE_ID
};struct Varyings{float4 positionCS : SV_POSITION;float2 baseUV : VAR_BASE_UV;float3 normalWS : VAR_NORMAL;float3 positionWS : VAR_POSITION;GI_VARYINGS_DATAUNITY_VERTEX_INPUT_INSTANCE_ID
};

将UV坐标传入片元着色器

Varyings LitPassVertex(Attributes input)
{Varyings output;....// 全局光照TRANSFER_GI_DATA(input, output);return output;
}

在片元着色器中获取UV坐标

// 全局光照
#if defined(LIGHTMAP_ON)float2 LightMapUV = GI_FRAGMENT_DATA(input);
#endif

然而,这获取的UV并不是该物体在LightMap上的UV,而是LightMap局部空间上的UV。
每个物体均匀且不重叠的按照缩放和偏移放置在这张LightMap中,所以每一个物体都有一个对应的UV缩放和偏移数据。
我们通过在Shader的Input文件中添加unity_LightmapST得到该数据,该数据由Unity直接提供。

CBUFFER_START(UnityPerDraw)...float4 unity_LightmapST;
CBUFFER_END

教程中引入了动态光照贴图UV
float4 unity_DynamicLightmaoST;
防止因为兼容性导致的SRP批处理中断


这里我们不引入 unity_DynamicLightmaoST

在这里插入图片描述

4. 采样光照贴图

光照贴图的采样函数由render-pipelines.core提供,因为Unity有可能对:LightMap进行了压缩,所以使用内置函数可以帮我们解决这个问题。

其中,是否压缩LightMap在Light窗口下的Lightmap Compression来设置
在这里插入图片描述
设置压缩会在Shader中输入关键字 UNITY_LIGHTMAP_FULL_HDR

#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl"

里面有关于

  • 球谐采样
  • 光照探针采样
  • 遮蔽探针采样
  • 解码/编码LightMap
  • 解码/编码HDR环境贴图
  • 采样光照贴图的函数

的函数

其中,使用SampleSingleLightmap,对单一LightMap进行采样

real3 SampleSingleLightmap(TEXTURE2D_LIGHTMAP_PARAM(lightmapTex, lightmapSampler), LIGHTMAP_EXTRA_ARGS, float4 transform, bool encodedLightmap, real4 decodeInstructions)
{// transform is scale and biasuv = uv * transform.xy + transform.zw;real3 illuminance = real3(0.0, 0.0, 0.0);// Remark: baked lightmap is RGBM for now, dynamic lightmap is RGB9E5if (encodedLightmap){real4 encodedIlluminance = SAMPLE_TEXTURE2D_LIGHTMAP(lightmapTex, lightmapSampler, LIGHTMAP_EXTRA_ARGS_USE).rgba;illuminance = DecodeLightmap(encodedIlluminance, decodeInstructions);}else{illuminance = SAMPLE_TEXTURE2D_LIGHTMAP(lightmapTex, lightmapSampler, LIGHTMAP_EXTRA_ARGS_USE).rgb;}return illuminance;
}

我们使用该函数对LightMap进行采样,并根据是否开启LIGHTMAP_ON决定是否调用函数。

float3 SampleLightMap(float2 lightMapUV)
{
#if defined(LIGHTMAP_ON)return SampleSingleLightmap(TEXTURE2D_ARGS(unity_Lightmap, samplerunity_Lightmap), lightMapUV, unity_LightmapST, #if defined(UNITY_LIGHTMAP_FULL_HDR)false,#elsetrue,#endiffloat4(LIGHTMAP_HDR_MULTIPLIER, LIGHTMAP_HDR_EXPONENT, 0.0, 0.0));
#elsereturn 0.0;
#endif
}

返回数据

struct GI{float3 diffuse;
};GI GetGI(float2 lightMapUV){GI gi;gi.diffuse = SampleLightMap(lightMapUV);return gi;
}

在FragmentShader中调用函数,获取LightMap采样的数据。

// 全局光照float2 LightMapUV = GI_FRAGMENT_DATA(input);GI gi = GetGI(LightMapUV);

计算光照

    float3 color = GetLighting(surface, brdf, gi);

将全局光照作为基础色

float3 GetLighting(Surface surfaceWS, BRDF brdf, GI gi)
{// 得到表面级联阴影数据CascadeShadowData cascadeShadowData = GetCascadeShadowData(surfaceWS);// 将全局光照作为基础色float3 color = gi.diffuse;// 对可见光照结果进行累加for(int i = 0; i < GetDirectionalLightCount();i++){Light light = GetDirectionalLight(i, surfaceWS, cascadeShadowData);color += GetLighting(surfaceWS, brdf, light);}return color;
}

烘培光照
在这里插入图片描述
烘培光照+直接光照
在这里插入图片描述
注意:这里烘培光照只计算间接光照,不计算直接光照

但为什么是白色呢,不应该有绿色映射吗??????

将代码中计算GI的光照修改为

float3 color = gi.diffuse * brdf.diffuse;

变为:
间接光照(烘培)
在这里插入图片描述
烘培光照(烘培)+直接光照
在这里插入图片描述
效果好了,但是仍然没有得到正确的间接光照!

所以光照贴图保存的到底是什么
似乎只是一个强度,但没有颜色!!!
在这里插入图片描述
我们将直接光照颜色设为红色,再次查看间接光照数据。
在这里插入图片描述
可以看到,间接光照变成了红色,也就是说,光照烘培得到的数据并不是实际光照经过物体表面反射得到的间接光照,而是光照在弹射过程中按照一定比例衰减的结果。

因此,GI最终结果与BRDF相乘得到的才是间接光照的结果(没有反射物体颜色的映射)

如果要获取间接光照,见 4.Meta Pass

二、自定义光照探针

使用光照探针前
在这里插入图片描述
使用光照探针后
在这里插入图片描述

三、 Light Probe Proxy Volumes(LPPV)

四、Meta Pass

因为间接漫射光从表面反射,它应该受到这些表面漫反射的影响。这种情况目前还没有发生。Unity将我们的表面视为均匀的白色。Unity使用一个特殊的Meta通道来确定烘焙时的反射光。因为我们还没有定义这样的通道,Unity使用默认的通道,它最终是白色的。

增加Meta文件前
在这里插入图片描述
增加Meta文件后
在这里插入图片描述
间接光照效果
在这里插入图片描述
加上动态物体光照探针效果
在这里插入图片描述

五、 自发光烘培

在这里插入图片描述
在这里插入图片描述

相关文章:

Unity SRP 管线【第五讲:自定义烘培光照】

文章目录 一、自定义烘培光照1. 烘培光照贴图2. 获取光照贴图3. 获取物体在光照贴图上的UV坐标4. 采样光照贴图 二、自定义光照探针三、 Light Probe Proxy Volumes&#xff08;LPPV&#xff09;四、Meta Pass五、 自发光烘培 一、自定义烘培光照 细节内容详见catlikecoding.c…...

CentOS快速安装Mysql5.7(Alibaba Cloud Linux兼容)

1、安装 在线下载 http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm 下载rpm安装包 [roottheo bin]# cd /usr/local [roottheo local]# wget http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm安装rpm [roottheo local]# rpm -iv…...

【css】快速实现鼠标悬浮变色效果

<div class"nav-item"><div class"ic-img"></div><div>切换</div> </div>.nav-item {width: 100rem;height: 45rem;line-height: 45rem;display: flex;text-align: center;justify-content: center;align-items: cent…...

21. Mysql 事件或定时任务,解放双手,轻松实现自动化

文章目录 概念常见操作事件调度器操作查看事件创建事件删除事件启动与关闭事件 精选示例构造实时数据定时统计数据 总结参考资料 概念 Mysql 事件是一种在特定时间点自动执行的数据库操作&#xff0c;也可以称呼为定时任务&#xff0c;它可以自动执行更新数据、插入数据、删除…...

Apache Doris 2.0.2 安装步骤 Centos8

Linux 操作系统版本需求 Linux 系统版本当前系统版本CentOS7.1 及以上CentOS8Ubuntu16.04 及以上- 软件需求 软件版本当前版本Java1.81.8.0_391GCC4.8.2 及以上gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-4) 1、查看操作系统版本 方法 1&#xff1a;使用命令行 打开终端或…...

Java学习苦旅(二十五)——哈希表

本篇博客将详细讲解哈希表。 文章目录 哈希表概念冲突概念避免冲突哈希函数设计常见哈希函数 负载因子调节解决冲突闭散列开散列&#xff08;哈希桶&#xff09; 和java类集的关系 结尾 哈希表 概念 顺序结构以及平衡树中&#xff0c;元素关键码与其存储位置之间没有对应的关…...

性能分析与调优: Linux 实现 CPU剖析与火焰图

目录 一、实验 1.环境 2.CPU 剖析 3.CPU火焰图 一、实验 1.环境 &#xff08;1&#xff09;主机 表1-1 主机 主机架构组件IP备注prometheus 监测 系统 prometheus、node_exporter 192.168.204.18grafana监测GUIgrafana192.168.204.19agent 监测 主机 node_exporter192…...

leetcode动态规划问题总结 Python

目录 一、基础理论 二、例题 1. 青蛙跳台阶 2. 解密数字 3. 最长不含重复字符的子字符串 4. 连续子数组的最大和 5. 最长递增子序列 6. 最长回文字符串 7. 机器人路径条数 8. 礼物的最大价值 一、基础理论 动态规划其实是一种空间换时间的基于历史数据的递推算法&…...

strtok函数的介绍

_str指被分解的字符串 delim指分隔符字符串 返回类型是指针 strtok()用来将字符串分割成一个个片段。参数s指向欲分割的字符串&#xff0c;参数delim则为分割字符串中包含的所有字符。当strtok()在参数s的字符串中发现参数delim中包含的分割字符时,则会将该字符改为\0 字符…...

CF1909_C. Heavy Intervals题解

CF1909_C. Heavy Intervals题解 题目传送门&#xff08;Problem - C - CodeforcesCodeforces. Programming competitions and contests, programming communityhttps://codeforces.com/contest/1909/problem/C&#xff09;。 题目翻译如下&#xff1a;&#xff08;图片来源&a…...

【Python机器学习】理论知识:决策树

决策树是广泛用于分类和回归任务的模型&#xff0c;本质上是从一层层if/else问题中进行学习&#xff0c;并得出结论。这些问题类似于“是不是”中可能问到的问题。 决策树的每个结点代表一个问题或一个包含答案的终结点&#xff08;叶结点&#xff09;。树的边奖问题的答案与将…...

天软特色因子看板 (2024.01 第2期)

该因子看板跟踪天软特色因子A04001(当日趋势强度)&#xff0c;该因子为反映股价走势趋势强弱&#xff0c;用以反映股价走势趋势强弱&#xff0c;abs(值)越接近1&#xff0c;趋势 性越强&#xff0c;符号代表涨跌方向 今日为该因子跟踪第2期&#xff0c;跟踪其在SH000905 (中证5…...

java智慧医院互联网智慧3D导诊系统源码,经由智慧导诊系统多维度计算,准确推荐科室

什么是智慧导诊系统? 简单地说&#xff0c;智慧导诊系统是一种利用人工智能技术&#xff0c;为医生提供帮助的系统。它可以通过分析患者的症状和病史为医生提供疾病诊断和治疗方案的建议。 系统介绍&#xff1a; 医院智慧导诊系统是在医院中使用的引导患者自助就诊挂号&…...

WiFi7: MLD寻址

原文:MLD使用MLD MAC address唯一的标识本MLD。 MLD下的STA(s)使用与之不同的MAC address。 NOTE MLD MAC address可以和其下的某个STA的MAC address相同或者不同于任一MAC Address。 原文:对于individually addressed 帧。以下规则适用: Address 2(TA)设置为STA的MAC Add…...

laravel-admin之 浏览器自动填充密码(如果需要渲染数据库密码的话,首先确认数据库密码是否可以逆向解密)

参考 https://blog.51cto.com/u_10401840/5180106 为什么浏览器端保存的密码一直自动写入到$form->password 解决办法 2、在页面进入的时候&#xff0c;默认表单的type值为text&#xff1b;推荐指数&#xff1a;2颗星 5、设置表单的readonly属性;推荐指数&#xff1a;4颗…...

jquery图形验证码

效果展示 js图形随机验证码&#xff08;表单验证&#xff09; html代码片段 <form class"formwrap"><div class"item"><input type"text" id"code_input" value"" placeholder"请输入验证码"/>…...

dp专题10 目标和

本题链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 思路&#xff1a; 根据这道题&#xff0c;可以通过暴力的方法进行取 号或者 - 号 两个操作&#xff0c;通过当刚好得到 target 的时候 答案 1&#xff0c;但是通过长度是 20 &#xff0c;操…...

详解 docker 镜像制作的两种方式

概要 制作Docker镜像一般有2种方法&#xff1a; 通过Dockerfile&#xff0c;完成镜像的创建使用仓库中已有的镜像&#xff0c;安装自己使用的软件环境后完成新镜像创建 docker 常用命令 docker build: 用于构建 Docker 镜像。该命令可以从 Dockerfile 构建镜像&#xff0c;…...

selenium元素单击不稳定解决方法

selenium自动化测试过程中&#xff0c;经常会发现某一元素单击&#xff0c;很不稳定&#xff0c;有时候执行了点击没有反映。 以下总结两种解决方法&#xff1a;都是通过js注入的方式去点击。 1.F12查一看&#xff0c;要点击的按钮&#xff0c;或连接&#xff0c;有没有οncl…...

vue3中vite使用sass

引用&#xff1a;https://blog.csdn.net/weiliang_66/article/details/132469597 npm install sass -d配置vite.config.js: css: {preprocessorOptions: {scss: {additionalData:import "/assets/styles/main.scss";}}}创建对应的 main.sass...

centos 8.0 安装sysbench 1.0.17

序号步骤说明执行命令执行结果备注1 下载并解压sysbench-1.0.17.zip sysbench-1.0.17.zip2安装依赖文件 yum install automake libtool -y yum install /usr/include/libpq-fe.h 3安装sysbench cd sysbench-1.0.17 ./autogen.sh ./configure \ --prefix/sysbench \ --with-pgsq…...

LabVIEW开发分布式光纤油气管道泄漏检测及预警系统

LabVIEW开发分布式光纤油气管道泄漏检测及预警系统 随着油气工业的发展&#xff0c;管道泄漏成为一个严峻的安全问题。本文介绍了一种基于LabVIEW的分布式光纤油气管道泄漏检测及预警系统的设计思路和组成结构。系统包括硬件和软件两部分&#xff0c;其中硬件部分详细阐述了分…...

Go后端开发 -- Go Modules

Go后端开发 – Go Modules 文章目录 Go后端开发 -- Go Modules一、什么是Go Modules?二、GOPATH的工作模式1.GOPATH模式2.GOPATH模式的弊端 三、Go Modules模式创建项目1.go mod命令2.go mod环境变量3.使用Go Modules初始化项目4.修改模块的版本依赖关系 四、Go Modules下impo…...

基于det_keypoint_unite的ROS功能包(jetson部署)

文章目录 硬件软件FastDeploy编译CMakeLists.txt头文件源代码硬件 Jetson AGX Orin 64GB 软件 gcc/g++ >= 5.4(推荐8.2)cmake >= 3.10.0jetpack >= 4.6.1opencv=4.2.0FastDeploy编译 git clone https://github.com/PaddlePaddle/FastDeploy.git cd FastDeploy mkdi…...

TS 36.211 V12.0.0-下行(8)-调制和上变频

本文的内容主要涉及TS 36.211&#xff0c;版本是C00&#xff0c;也就是V12.0.0。...

基于SSM酒店后台管理系统【源码】【最详细运行文档】

基于SSM酒店后台管理系统【源码】【最详细运行文档】 功能简介技术描述运行准备♝项目运行访问项目 演示图✅源码获取 &#x1f4a1; 「分享」 大家好&#xff0c;最近几年在酒店后台管理系统非常流行&#xff0c;无论是上课的项目或者是一些毕设都会以酒店后台管理系统举例说…...

利用Python实现每日新闻早报推送

本文将介绍如何使用Python编写简单的逻辑&#xff0c;通过调用API接口实现每日新闻推送功能。 步骤&#xff1a; 导入所需的库&#xff1a; 在代码的开头&#xff0c;我们需要导入所需的库。通常&#xff0c;我们会使用requests库来发送HTTP请求&#xff0c;以获取新闻数据。 …...

图像分割-Grabcut法

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 本文的C#版本请访问&#xff1a;图像分割-Grabcut法(C#)-CSDN博客 GrabCut是一种基于图像分割的技术&#xff0c;它可以用于将图像…...

性能测试浅谈

早期的性能测试更关注后端服务的处理能力。 一个用户去访问一个页面的请求过程&#xff0c;如上图。 数据传输时间 当你从浏览器输入网址&#xff0c;敲下回车&#xff0c;开始... 真实的用户场景请不要忽视数据传输时间&#xff0c;想想你给远方的朋友写信&#xff0c;信件需…...

媒体运营常用的ChatGPT通用提示词模板

媒体平台选择&#xff1a;如何选择合适的媒体平台&#xff0c;确保内容的有效传播&#xff1f; 内容策划与创作&#xff1a;如何策划和创作高质量的内容&#xff0c;吸引和留住目标受众&#xff1f; 内容发布与推广&#xff1a;如何有效地发布和推广内容&#xff0c;提高内容…...

北京做网站公司有哪些/湖南好搜公司seo

最近项目当中有个场景问题&#xff0c;需要在数据更新完成之后&#xff0c;发送mq消息通知周边系统进行操作。但是周边系统需要用到当前事务更新完成的数据。经常出现mq消息处理过程中拿不到更新之后的数据。经过排查日志&#xff0c;查看sql执行情况&#xff0c;代码逻辑。还跟…...

外贸企业公司网站建设/可以做产品推广的软件有哪些

新的一年又开始了 2010年 祝大家新年快乐&#xff01; 加油&#xff0c;加油&#xff0c;加油--- 2009年12月31日23:59:59 转载于:https://www.cnblogs.com/meiqunfeng/archive/2009/12/31/1637235.html...

JSP动态网站开发实践教程/怎么推广网站

23 日晚&#xff0c;华为法国官方推特发文&#xff1a;华为即将发布全球首款石墨烯电池高端智能手机&#xff0c;石墨烯电池将带来更持久的续航和更快的充电速度。而且&#xff0c;华为法国推特账号&#xff0c;还转发了一篇关于华为 P40 的报道&#xff0c;报道中写到&#xf…...

wordpress freeradius/网店代运营骗局

多租户SaaS平台的数据库方案 1.1 多租户是什么 多租户技术&#xff08;Multi-TenancyTechnology&#xff09;又称多重租赁技术&#xff1a;是一种软件架构技术&#xff0c;是实现如何在多用户环境下 &#xff08;此处的多用户一般是面向企业用户&#xff09;共用相同的系统或…...

专业简历制作公司/seo是什么姓

昨天把一个数据表的字段从普通索引&#xff0c;修改成为了唯一索引。准备早早下班的时候&#xff0c;突然发现数据库的内存命中率从98%下降到了48%&#xff0c;导致大量的任务处于阻塞状态&#xff0c;整个系统也阻塞了。其实这个就是普通索引和唯一索引使用不当引起的原因。下…...

运用.net做网站/小程序开发教程

1 判断数据库是否存在if exists (select * from sys.databases where name 数据库名) drop database [数据库名] 2 判断表是否存在if exists (select * from sysobjects where id object_id(N[表名]) and OBJECTPROPERTY(id, NIsUserTable) 1) drop table [表名] …...