Unity中Shader的GI的直接光实现

文章目录

  • 前言
  • 一、在上一篇文章中,得到GI相关数据后,需要对其进行Lambert光照模型计算
  • 二、在准备好上面步骤后,我们需要准备缺少的数据
    • 1、准备上图中的 s.Normal
    • 2、准备上图中的 s.Albedo


前言

Unity中Shader的GI的直接光实现,基于上一篇准备好的数据的基础上,继续实现GI的直接光效果

  • Unity中Shader的烘培分支的判断

一、在上一篇文章中,得到GI相关数据后,需要对其进行Lambert光照模型计算

这是上一篇文章中得到 GI 数据的方法
LightingLambert_GI1(o,giInput,gi);

得到了之后,我们直接使用Unity自带的计算 Lambert 模型的函数计算即可,当然也可自己按照之前的文章实现 Lambert 光照模型

  • Unity中Shader的Lambert光照的实现

这是在 Lighting.cginc 中Unity实现Lambert光照的方法

在这里插入图片描述

我们把它移植到我们自己的 cginc 中,方便管理修改(记着修改一下函数名,防止函数名冲突)

在这里插入图片描述


二、在准备好上面步骤后,我们需要准备缺少的数据

1、准备上图中的 s.Normal

这在之前的文章中,已经定义过很多次了,具体步骤如下

1.在appdata中,接受 half3 normal : NORMAL;

half3 normal : NORMAL;

2.在 v2f 中定义一个 half3 worldNormal :TEXCOORD;用于存放顶点法线数据

half3 worldNormal : TEXCOORD2;

3.在顶点着色器中,把 appdata 传入的数据转化到世界坐标下,存入 v2f 的worldNormal中

o.worldNormal = UnityObjectToWorldNormal(v.normal);

4.在片元着色器中,把 worldNormal 赋值给 SurfaceOutput 变量的 Normal

//1、准备 SurfaceOutput 的数据
SurfaceOutput o;
//目前先初始化为0,使用Unity自带的方法,把结构体中的内容初始化为0
UNITY_INITIALIZE_OUTPUT(SurfaceOutput,o)
o.Normal = i.worldNormal;

然后,我们在UnityLambertLight1中,返回一下diff,看看结果
在片元着色器,返回计算结果

fixed4 c = LightingLambert1(o,gi);
return c;

这是烘培前的效果:
请添加图片描述
这是烘培后的效果:(我们可以看见已经有基本的光照效果了)
请添加图片描述

2、准备上图中的 s.Albedo

这个 Albedo 一般是用模型的贴图主纹理采样得到的,在这里我们没有使用,则一般给他赋值为1(不能为0,不然会导致输出的结果为黑色)

以下是修改后的完整代码:

//在这里里面使用 自定义的 cginc 来实现全局GI
//GI数据的准备
//烘培分支的判断
//GI的直接光实现
//GI的间接光实现
Shader "MyShader/P1_8_6"
{
    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
                half3 normal : NORMAL;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float4 worldPos : TEXCOORD0;
                //定义第二套UV
                #if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
                float4 lightmapUV : TEXCOORD1;
                #endif
                half3 worldNormal : TEXCOORD2;
            };
            
            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

                o.worldNormal = UnityObjectToWorldNormal(v.normal);
                
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                //1、准备 SurfaceOutput 的数据
                SurfaceOutput o;
                //目前先初始化为0,使用Unity自带的方法,把结构体中的内容初始化为0
                UNITY_INITIALIZE_OUTPUT(SurfaceOutput,o)
                o.Albedo = 1;
                o.Normal = i.worldNormal;
                
                //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);
                //我们在得到GI的数据后,对其进行Lambert光照模型计算,即可得到结果
                fixed4 c =  LightingLambert1(o,gi);

                return c;
                //return fixed4(gi.indirect.diffuse,1);
                //return 1;
            }
            ENDCG
        }
    }
}

这是修改后的效果:
请添加图片描述

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

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

相关文章

基于springboot实现在线考试平台项目【项目源码+论文说明】

基于springboot实现在线考试平台管理系统演示 摘要 网络的广泛应用给生活带来了十分的便利。所以把在线考试管理与现在网络相结合,利用java技术建设在线考试系统,实现在线考试的信息化。则对于进一步提高在线考试管理发展,丰富在线考试管理经…

【计算机网络】同源策略及跨域问题

1. 同源策略 同源策略是一套浏览器安全机制,当一个源的文档和脚本,与另一个源的资源进行通信时,同源策略就会对这个通信做出不同程度的限制。 同源策略对 同源资源 放行,对 异源资源 限制。因此限制造成的开发问题,称…

OkHttp库爬取百度云视频详细步骤

以下是使用OkHttp库的Kotlin爬虫程序,该爬虫用于爬取百度云的视频。 首先,我们需要导入OkHttp库和Kotlin库。import okhttp3.OkHttpClient和import kotlin.jvm.JVM。 import okhttp3.OkHttpClient import kotlin.jvm.JVM然后,我们需要创建一…

单片机温湿度-光照-DHT11-烟雾气体检测控制系统-proteus仿真-源程序

一、系统方案 本设计采用52单片机作为主控器,液晶1602显示,DHT11温湿度,光照、烟雾气体检测,按键设置报警阀值,蜂鸣器报警。 二、硬件设计 原理图如下: 三、单片机软件设计 1、首先是系统初始化 // // …

docker部署Jenkins(Jenkins+Gitlab+Maven实现CI/CD)

GitLab介绍 GitLab是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的Web服务,可通过Web界面进行访问公开的或者私人项目。它拥有与Github类似的功能,能够浏览源代码,管理缺陷和注释。…

按键开发环境搭建

雷电模拟器 创建虚拟机 2.设置root权限 打开按键精灵连接虚拟机 开启悬浮 mumu模拟器操作 查找端口方法 adb connect 127.0.0.1:16416 设置-应用-所有应用-按键精灵-开启悬浮 步骤二:开启root 处理未root:中途如果有如下未root的情况&#x…

Perl安装教程

1. perl简介 Perl 是 Practical Extraction and Report Language 的缩写,可翻译为 “实用报表提取语言”。Perl 是高级、通用、直译式、动态的程序语言。Perl 最初的设计者为拉里沃尔(Larry Wall),于1987年12月18日发表。Perl 借…

【Unity基础】7.动画状态参数

【Unity基础】7.动画状态参数 大家好,我是Lampard~~ 欢迎来到Unity基础系列博客,所学知识来自B站阿发老师~感谢 (一)创建动画状态 (1) 创建动画状态 不好意思各位~最近工作比较忙,稍微耽误了这两周的博客。话…

LangChain+LLM实战---向量数据库介绍

原文:Vector Databases Embeddings是由人工智能模型(如大型语言模型)生成的,具有大量的属性或特征,使其表示难以管理。在人工智能和机器学习的背景下,这些特征代表了数据的不同维度,这些维度对于理解模式、关系和底层…

深入理解计算机系统CS213 - Lecture 02

Bits, Bytes, and Integer 1.位运算与条件运算 &&#xff0c;|&#xff0c;^&#xff0c;~ 是做位运算。诸位01运算。 &&&#xff0c;||&#xff0c;&#xff01;是判断条件真假&#xff0c;而后返回0或1。 2. 位移 x << y&#xff1a;左移y位&#xff…

3+单细胞+代谢+WGCNA+机器学习

今天给同学们分享一篇生信文章“Identification of new co-diagnostic genes for sepsis and metabolic syndrome using single-cell data analysis and machine learning algorithms”&#xff0c;这篇文章发表Front Genet.期刊上&#xff0c;影响因子为3.7。 结果解读&#x…

飞书开发学习笔记(三)-利用python开发调试云文档和电子表格

飞书开发学习笔记(三)-利用python开发调试云文档和电子表格 一.建立Python飞书开发环境 首先还是进入开放平台下的API调试台 飞书开放平台&#xff1a;https://open.feishu.cn/app?langzh-CN 以获取"我的空间"下的文件清单为例&#xff0c;通过获取飞书API调试台提…

51单片机锅炉监控系统仿真设计( proteus仿真+程序+原理图+报告+讲解视频)

51单片机锅炉监控系统仿真设计( proteus仿真程序原理图报告讲解视频&#xff09; 1.主要功能&#xff1a;讲解视频2.仿真3. 程序代码4. 原理图5. 设计报告6. 设计资料内容清单&&下载链接资料下载链接&#xff08;可点击&#xff09;&#xff1a; 51单片机锅炉监控系统仿…

企业电脑屏幕监控有哪些?如何实现电脑屏幕监控

企业电脑屏幕监控有哪些&#xff1f;如何实现电脑屏幕监控 下载使用安企神电脑屏幕监控软件 企业电脑屏幕监控是一种监测和记录员工在工作时间内在他们的计算机上执行的活动的技术。这种监控可以有多种目的&#xff0c;包括确保员工的生产力、确保数据安全性&#xff0c;或满…

Git 删除本地和远程分支

目录 删除本地和远程分支分支删除验证验证本地分支验证远程分支 开源项目微服务商城项目前后端分离项目 删除本地和远程分支 删除 youlai-mall 的 dev 本地和远程分支 # 删除本地 dev 分支&#xff08;注&#xff1a;一定要切换到dev之外的分支才能删除&#xff0c;否则报错&…

46基于matlab的模拟退火算法(SA)优化车辆路径问题(VRP)

基于matlab的模拟退火算法&#xff08;SA&#xff09;优化车辆路径问题&#xff08;VRP&#xff09;&#xff0c;在位置已知的条件下&#xff0c;确定车辆到各个指定位置的行程路线图&#xff0c;使得路径最短&#xff0c;运输成本最低。一个位置由一台车服务&#xff0c;且始于…

STM32中微秒延时的实现方式

STM32中微秒延时的实现方式 0.前言一、裸机实现方式二、FreeRTOS实现方式三、定时器实现&#xff08;通用&#xff09;4、总结 0.前言 最近在STM32驱动移植过程中需要用到微秒延时来实现一些外设的时序&#xff0c;由于网上找到的驱动方法良莠不齐&#xff0c;笔者在实现时序过…

集线器、交换机、网桥、路由器、网关

目录 集线器(HUB)交换机(SWITCH)网桥(BRIDGE)路由器(ROUTER)网关(GATEWAY)交换机和路由器的区别参考 集线器(HUB) 功能 集线器对数据的传输起到同步、放大和整形的作用 属于物理层设备 工作机制 使用集线器互连而成的以太网被称为共享式以太网。当某个主机要给另一个主机发送单…

webpack 高级

高级配置就是要进行 webpack 优化&#xff0c;让代码在编译、运行时性能更好 主要从以下角度去优化&#xff1a; 1、提升开发体验 2、提升打包构建速度 3、减少代码体积 4、优化代码运行性能 一、提升体验 1、SourceMap 为什么 打包出来的所有css和js合并成了一个文件&#…

手把手教程 | YOLOv8-seg训练自己的分割数据集

&#x1f680;&#x1f680;&#x1f680;手把手教程&#xff1a;教会你如何使用自己的数据集开展分割任务 &#x1f680;&#x1f680;&#x1f680;YOLOv8-seg创新专栏&#xff1a;http://t.csdnimg.cn/KLSdv 学姐带你学习YOLOv8&#xff0c;从入门到创新&#xff0c;轻轻松…