Unity中Shader的烘培分支的判断

文章目录

  • 前言
  • 一、上一篇文章中所需要的 lightmapUV 只有在烘焙时才会使用
    • 1、查看帮助文档后,Unity中判断烘培是否开启,使用的是LIGHTMAP_ON
    • 2、我们在 appdata 和 v2f 中,定义第二套UV


前言

Unity中Shader的烘培分支的判断,基于上一篇文章,继续实现 GI Shader

  • Unity中Shader的GI相关数据的准备

一、上一篇文章中所需要的 lightmapUV 只有在烘焙时才会使用

即只有在 BackGI 和 RealtimeGI 下才会使用到 lightmapUV ,所以我们需要用分支来区别

1、查看帮助文档后,Unity中判断烘培是否开启,使用的是LIGHTMAP_ON

在这里插入图片描述

  1. DYNAMICLIGHTMAP_ON :RealtimeGI是否开启
  2. LIGHTMAP_ON:当对象标记为LightMap Static并且场景烘焙后开启

所以,我们在Pass中,修改 LightMode 为 ForwardBase
定义 multi_compile_fwdbase 变体

Tags{“LightMode”=“ForwardBase”}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase

2、我们在 appdata 和 v2f 中,定义第二套UV

1.在appdata中,第二套UV对应的语义是 TEXCOORD1,这是不能乱改的

struct appdata
{
float4 vertex : POSITION;
//定义第二套 UV ,appdata 对应的固定语义为 TEXCOORD1
#if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
float4 lightmapUV : TEXCOORD1;
#endif
};

2.在 v2f 中,也定义第二套UV,不过这里没有语义限制

struct v2f
{
float4 vertex : SV_POSITION;
float4 worldPos : TEXCOORD0;
#if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
float4 lightmapUV : TEXCOORD1;
#endif
};

3.在顶点着色器中对其采样

float4 lightmapUV; // .xy = static lightmap UV, .zw = dynamic lightmap UV
lightmapUV的XY代表的是:BackGI
lightmapUV的ZW代表的是:RealTimeGI

//对第二套UV进行纹理采样,这个unity_LightmapST,类似于之前我们定义纹理的Tilling 和 Offset
#if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
o.lightmapUV.xy = v.lightmapUV * unity_LightmapST.xy + unity_LightmapST.zw;
#endif

4.在片元着色器,对其赋值

#if defined(DYNAMICLIGHTMAP_ON) || defined(LIGHTMAP_ON)
giInput.lightmapUV = i.lightmapUV;
#endif

以下是准备好所有数据后的代码:

//在这里里面使用 自定义的 cginc 来实现全局GI
//GI数据的准备
//烘培分支的判断
Shader "MyShader/P1_8_4"
{
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        Pass
        {
            Tags{"LightMode"="ForwardBase"}
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile DYNAMICLIGHTMAP_ON
            #pragma multi_compile LIGHTMAP_ON
            

            #include "UnityCG.cginc"
            #include "AutoLight.cginc"
            #include "Lighting.cginc"
            #include "CGIncludes/MyGlobalIllumination.cginc"
            
            struct appdata
            {
                float4 vertex : POSITION;
                //定义第二套 UV ,appdata 对应的固定语义为 TEXCOORD1
                #if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
                float4 lightmapUV : TEXCOORD1;
                #endif
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float4 worldPos : TEXCOORD0;
                //定义第二套UV
                #if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
                float4 lightmapUV : TEXCOORD1;
                #endif
            };
            
            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.worldPos = mul(unity_ObjectToWorld,v.vertex);

                //对第二套UV进行纹理采样
                #if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
                    o.lightmapUV.xy = v.lightmapUV * unity_LightmapST.xy + unity_LightmapST.zw;
                #endif
                
                
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                //1、准备 SurfaceOutput 的数据
                SurfaceOutput o;
                //目前先初始化为0,使用Unity自带的方法,把结构体中的内容初始化为0
                UNITY_INITIALIZE_OUTPUT(SurfaceOutput,o)

                //2、准备 UnityGIInput 的数据
                UnityGIInput giInput;
                //初始化
                UNITY_INITIALIZE_OUTPUT(UnityGIInput,giInput);
                //修改用到的数据
                giInput.light.color = _LightColor0;
                giInput.light.dir = _WorldSpaceLightPos0;
                giInput.worldPos = i.worldPos;
                giInput.worldViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);
                giInput.atten = 1;
                giInput.ambient = 0;
                
                #if defined(DYNAMICLIGHTMAP_ON) || defined(LIGHTMAP_ON)
                giInput.lightmapUV = i.lightmapUV;
                #endif
                
                //3、准备 UnityGI 的数据
                UnityGI gi;
                //直接光照数据(主平行光)
                gi.light.color = _LightColor0;
                gi.light.dir = _WorldSpaceLightPos0;
                //间接光照数据(目前先给0)
                gi.indirect.diffuse = 0;
                gi.indirect.specular = 0;
                
                LightingLambert_GI1(o,giInput,gi);
                return 1;
            }
            ENDCG
        }
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

服务器数据恢复—EMC存储pool上数据卷被误删的数据恢复案例

服务器数据恢复环境: EMC Unity某型号存储,连接了2台硬盘柜。2台硬盘柜上创建2组互相独立的POOL,2组POOL共有21块520字节硬盘。21块硬盘组建了2组RAID6,1号RAID6有11块硬盘. 2号RAID6有10块硬盘。 服务器故障&检测&#xff1…

扩容一个新节点

1.删除nodes rm -rf nodes/ 2.挂载本地文件与创建节点 bash build_chain.sh -f ipconf -e /root/tools/fisco-bcos 3.部署节点 bash nodes/127.0.0.1/start_all.sh 4.把共享的gen_node_cert.sh文件下载到本地 cp /root/Desktop/共享文件夹/tools/gen_node_cert.sh ./…

代码生成器

Easycode Entity ##导入宏定义 $!{define.vm}##保存文件(宏定义) #save("/entity", ".java")##包路径(宏定义) #setPackageSuffix("entity")##自动导入包(全局变量) $!{au…

链表详讲(附代码)

1.什么是链表 链表是一种非常常见的数据结构,在程序设计中经常被使用。它由一系列节点组成,每个节点都有用来存放数据的数据区以及存放下一个节点地址指针的地址区。跟顺序表不同的是,链表的节点之间的空间并非是连续的,依靠地址区…

【python VS vba】(5) 在python中使用xlwt操作Excel(待完善ing)

目录 1 什么是xlwt 2 导入xlwt 3 相关语法 3.1 创建新的workbook 3.2 创建新的sheet 3.3 保存workbook 4 python里表格的形式 4.1 矩阵 4.2 EXCEL的数据形式 完全等于矩阵的数字结构 4.3 python里矩阵 5 具体代码 5.1 代码 5.2 结果 5.3 要注意的问题 5.3.1 不能…

STL-set和map

目录 一、pair和make_pair 1. pair 2. make_pair 二、set (一)set的模板参数列表 (二)set的构造 (三)set的插入 1. 测试1 2. 测试2 (四)low_bound和upper_bound&#xff…

(四)docker:为mysql和java jar运行环境创建同一网络,容器互联

看了很多资料,说做互联的一个原因是容器内ip不固定,关掉重启后如果有别的容器启动,之前的ip会被占用,所以做互联创建一个网络,让几个容器处于同一个网络,就可以互联还不受关闭再启动ip会改变的影响&#xf…

ArcGIS for Android 禁止地图旋转

ArcGIS for Android 禁止地图旋转 话不多说,直接上代码!!! public class LoadMap extends AppCompatActivity {// 地图private MapView mapView;private ArcGISMap map;Overrideprotected void onCreate(Bundle savedInstanceSta…

Ubuntu 系统内核 kernel panic

Ubuntu 系统内核 kernel panic 不能进入系统:报错end kernel panic -not syncing: attemped to kill init! exit code 0x00000100 系统启动的时候,按下‘e’键进入grub编辑界面,编辑grub菜单,选择“kernel /vmlinuz-XXXXro root…

听听ChatGPT对IT行业的发展和就业前景的看法

🌈个人主页: Aileen_0v0🔥系列专栏:PYTHON学习系列专栏💫"没有罗马,那就自己创造罗马~" 目录 (1)判断素数 写法1: 写法2: (2)计算1-100的偶数之和 写法1: 写法2: (3)计算1-100的奇数之和 (4)多层循环 IT行业哪个方向比较…

k8s 多网卡方案multus

kubernetes 多网卡方案之 Multus_CNI 部署以及基本使用 一、multus cni 出现的背景 在k8s的环境中启动一个容器,默认情况下只存在两个虚拟网络接口(loopback 和 eth0), loopback 的流量始终都会在本容器内或本机循环&#xff0c…

【中国知名企业高管团队】系列57:康佳KONKA

今天开始,华研荟为大家介绍中国电视行业的知名企业,接下来三天介绍位于深圳的电视三巨头,这三巨头以电视机研发、生产和销售起步,2000左右生产过非智能手机,但是在互联网时代被小米们抢走了电视和手机的很大一部分市场…

【音视频 | opus】opus编解码库(opus-1.4)详细介绍以及使用——附带解码示例代码

😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀 🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C、数据结构、音视频🍭 🤣本文内容🤣&a…

《动态顺序表》的实现

目录 前言: 认识线性表: 关于顺序表 实现动态顺序表: 顺序表的动态存储定义: 初始化顺序表: 顺序表的销毁: 尾插: 判断是否需要扩容: 总代码: 头插&#xff1a…

C++——类和对象(中)完结

赋值运算符重载 运算符重载 C 为了增强代码的可读性引入了运算符重载 , 运算符重载是具有特殊函数名的函数 ,也具有其 返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。 函数名字为:关键…

父子进程之间的等待(wait和waitpid的介绍+原理),status的介绍+恢复退出码(位运算+宏),非阻塞等待(宏),signal查看

目录 父子进程之间的等待 介绍 为什么要有等待 内存泄漏 如何等待 介绍 pid_t wait (int* status) 介绍 status指针 示例 ​编辑 pid_t waitpid (pid_t pid,int* status,int options) pid options WNOHANG -- 非阻塞等待 示例 status 查看status status问题 …

Mybatis与Mybatis-Plus(注解与Xml)(单表与多表)

准备工作 这里我们准备了两个与数据库表对应的实体类,stu为学生表,cls为班级表 类属性上的注解如 TableId等 为Mybatis-Plus的注解,使用mybatis会无视掉这些注解 在Stu 类的最后一个属性我们定义了Cls实体类的对象,对于单表查询&…

EASYX输出文字

在EASYX中绘制出字符串和字符 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <easyx.h> #include <iostream> #include <math.h> #include <stdlib.h> #include <conio.h> #include <time.h> #define PI 3.14、 //…

Windows 下编译 TensorFlow 2.9.1 CC库

参考 Intel 的 tensorflow 编译指导&#xff0c;不过项目还是可以用 TF原本的&#xff0c;不是一定要选择Intel 的TF版本。 安装 MSVC 2019 安装 Intel OneDNN OneMKL 似乎也可以不安装 ( & ) https://www.intel.cn/content/www/cn/zh/developer/articles/tool/one…

算法随想录算法训练营第四十七天| 647. 回文子串 516.最长回文子序列

647. 回文子串 题目&#xff1a;给你一个字符串 s &#xff0c;请你统计并返回这个字符串中 回文子串 的数目。回文字符串 是正着读和倒过来读一样的字符串。子字符串 是字符串中的由连续字符组成的一个序列。具有不同开始位置或结束位置的子串&#xff0c;即使是由相同的字…