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

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;#endifhalf3 normal : NORMAL;};struct v2f{float4 vertex : SV_POSITION;float4 worldPos : TEXCOORD0;//定义第二套UV#if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)float4 lightmapUV : TEXCOORD1;#endifhalf3 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;#endifo.worldNormal = UnityObjectToWorldNormal(v.normal);return o;}fixed4 frag (v2f i) : SV_Target{//1、准备 SurfaceOutput 的数据SurfaceOutput o;//目前先初始化为0,使用Unity自带的方法,把结构体中的内容初始化为0UNITY_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}}
}

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

相关文章:

Unity中Shader的GI的直接光实现

文章目录 前言一、在上一篇文章中,得到GI相关数据后,需要对其进行Lambert光照模型计算二、在准备好上面步骤后,我们需要准备缺少的数据1、准备上图中的 s.Normal2、准备上图中的 s.Albedo 前言 Unity中Shader的GI的直接光实现,基…...

JAVA进程和线程

哈喽~大家好呀,这篇来看看JAVA进程和线程。 🥇个人主页:个人主页​​​​​ 🥈 系列专栏:【日常学习上的分享】 🥉与这篇相关的文章: Redis快速入…...

3.2-Docker Image概述

...

JS自定义深浅度克隆

function deepClone(obj, cache new WeakMap()) {if (typeof obj ! object) return obj //普通类型,直接返回if (obj null) return objif (cache.get(obj)) return cache.get(obj)//防止循环引用,程序进入死循环if (obj instanceof Date) return new D…...

MySQL之表的约束

目录 表的约束1.空属性2.默认值3.列描述4.zerofill5.主键6.自增长7.唯一键8.外键 表的约束 真正约束字段的是数据类型,数据类型规定了数据的用法、范围…假如我们没有按照其规定的约束,那么数据将插入不成功但是数据类型约束很单一,需要有一…...

Go基础——接口、并发

1、接口 Go 语言提供了另外一种数据类型即接口,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口。接口可以让不同的类型绑定到一组公共的方法上,从而实现多态和灵活的设计。Go 语言中的接口是隐式实现…...

zookeeper本地部署和集群搭建

zookeeper(动物园管理员)是一个广泛应用于分布式服务提供协调服务Apache的开源框架 Zookeeper从设计模式角度来理解:是一个基于观察者模式设计的分布式服务管理框架,它 负责存储和管理大家都关心的数据 ,然 后 接受观察…...

优橙内推甘肃专场——5G网络优化(中高级)工程师

内推公司1:上海井胜通讯技术有限公司 内推公司2:西安长河通讯有限责任公司 内推公司3:沈阳电信工程局 上海井胜通讯技术有限公司 公司成立于2002年,是一家专业移动通信技术服务公司。2008年之前是香港一家大型流动通讯运营公司…...

crontab 定时任务

1.查看 crond 是否开启 systemctl status crond 2.设置 crontab 定时任务 基本语法 #基本语法 crontab [选项] 查看定时任务 #查看定时任务 crontab -l 编辑定时任务 #编辑定时任务 crontab -e 案例实操 */1 * * * * echo "hello,world" >> /root/hel…...

【入门Flink】- 03Flink部署

集群角色 Flik提交作业和执行任务,需要几个关键组件: 客户端(Client):代码由客户端获取并做转换,之后提交给JobManger JobManager:就是Fink集群里的“管事人”,对作业进行中央调度管理;而它获…...

DockerFile常用保留字指令及知识点合集

目录 DockerFile加深理解&#xff1a; DockerFile常用保留字指令 保留字&#xff1a; RUN&#xff1a;容器构建时需要运行的命令 COPY&#xff1a;类似ADD&#xff0c;拷贝文件和目录到镜像中。 将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 …...

怎么批量删除文件名中的空格?

怎么批量删除文件名中的空格&#xff1f;当我们整理文件的时候发现文件名里面有一些空格&#xff0c;如果空格较多&#xff0c;可能会造成文件名特别的长&#xff0c;我们一般会随手对文件进行重命名&#xff0c;然后将文件名中的空格删除掉&#xff0c;这项操作非常的简单方便…...

回顾十大数据恢复软件,帮助用于恢复丢失的文件!

您是否因丢失计算机上的重要文件而感到恐慌&#xff1f;你不是一个人&#xff01;数据丢失是许多人面临的严重问题&#xff0c;但幸运的是&#xff0c;有许多解决方案可以恢复数据。 在本文中&#xff0c;我将回顾十大数据恢复软件&#xff0c;以帮助您恢复丢失的文件&#xf…...

【Linux】多路IO复用技术②——poll详解如何使用poll模型实现简易的一对多服务器(附图解与代码实现)

在阅读本篇博客之前&#xff0c;建议大家先去看一下我之前写的这篇博客&#xff0c;否则你很可能会一头雾水 【Linux】多路IO复用技术①——select详解&如何使用select模型在本地主机实现简易的一对多服务器&#xff08;附图解与代码实现&#xff09;http://t.csdnimg.cn/…...

CSS 滚动捕获 Scroll Snap

CSS 滚动捕获 Scroll Snap CSS 滚动捕获允许开发者通过声明一些位置(或叫作捕获位置)来创建精准控制的滚动体验. 通常来说轮播图就是这种体验的例子, 在轮播图中, 用户只能停在图 A 或者图 B, 而不能停在 A 和 B 的中间. 比如平时用淘宝或小红书, 当你上滑到下一个推荐内容时…...

【带头学C++】----- 三、指针章 ---- 3.9 数组作为函数的参数

当数组作为函数参数时&#xff0c;有几种常见的方式可以传递数组给函数&#xff1a; 数组作为指针传递&#xff1a; 数组名在函数调用时会自动转换为指向数组第一个元素的指针。通过指针可以访问数组元素&#xff0c;但无法获取数组的大小。在函数中修改指针指向的值会影响原始…...

完美处理 Android App 的 apk 输出路径与文件名

实现代码 buildTypes {// ...applicationVariants.all {variant ->variant.outputs.all {Calendar calendar Calendar.getInstance(Locale.CHINA);def buildDate String.format(Locale.CHINA, "%04d%02d%02d", calendar.get(Calendar.YEAR), calendar.get(Cale…...

【技术干货】开源库 Com.Gitusme.Net.Extensiones.Core 的使用

目录 1、项目介绍 2、为项目添加依赖 3、代码中导入命名空间 4、代码中使用 示例 1&#xff1a;string转换 示例 2&#xff1a;object转换 1、项目介绍 Com.Gitusme.Net.Extensiones.Core是一个.Net扩展库。当前最新版本1.0.4&#xff0c;提供了常见类型转换&#xff0c…...

大厂面试题-b树和b+树的理解

为了更清晰的解答这个问题&#xff0c;从三个方面来回答&#xff1a; a.了解二叉树、AVL树、B树的概念 b.B树和B树的应用场景 1.B树是一种多路平衡查找树&#xff0c;为了更形象的理解&#xff0c;我们来看这张图。 二叉树&#xff0c;每个节点支持两个分支的树结构&#xff…...

NeRF-SLAM部署运行(3060Ti)

记录在部署运行期间遇到的一些问题&#xff0c;分享给大家~ 一、环境 RTX 3060 Ti、8G显存、Ubuntu18.04 二、部署 1. 下载代码 git clone https://github.com/jrpowers/NeRF-SLAM.git --recurse-submodules git submodule update --init --recursive cd thirdparty/insta…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

什么是VR全景技术

VR全景技术&#xff0c;全称为虚拟现实全景技术&#xff0c;是通过计算机图像模拟生成三维空间中的虚拟世界&#xff0c;使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验&#xff0c;结合图文、3D、音视频等多媒体元素…...

SpringAI实战:ChatModel智能对话全解

一、引言&#xff1a;Spring AI 与 Chat Model 的核心价值 &#x1f680; 在 Java 生态中集成大模型能力&#xff0c;Spring AI 提供了高效的解决方案 &#x1f916;。其中 Chat Model 作为核心交互组件&#xff0c;通过标准化接口简化了与大语言模型&#xff08;LLM&#xff0…...

【HarmonyOS 5】鸿蒙中Stage模型与FA模型详解

一、前言 在HarmonyOS 5的应用开发模型中&#xff0c;featureAbility是旧版FA模型&#xff08;Feature Ability&#xff09;的用法&#xff0c;Stage模型已采用全新的应用架构&#xff0c;推荐使用组件化的上下文获取方式&#xff0c;而非依赖featureAbility。 FA大概是API7之…...

CppCon 2015 学习:Time Programming Fundamentals

Civil Time 公历时间 特点&#xff1a; 共 6 个字段&#xff1a; Year&#xff08;年&#xff09;Month&#xff08;月&#xff09;Day&#xff08;日&#xff09;Hour&#xff08;小时&#xff09;Minute&#xff08;分钟&#xff09;Second&#xff08;秒&#xff09; 表示…...

PH热榜 | 2025-06-08

1. Thiings 标语&#xff1a;一套超过1900个免费AI生成的3D图标集合 介绍&#xff1a;Thiings是一个不断扩展的免费AI生成3D图标库&#xff0c;目前已有超过1900个图标。你可以按照主题浏览&#xff0c;生成自己的图标&#xff0c;或者下载整个图标集。所有图标都可以在个人或…...

零基础在实践中学习网络安全-皮卡丘靶场(第十一期-目录遍历模块)

经过前面几期的内容我们学习了很多网络安全的知识&#xff0c;而这期内容就涉及到了前面的第六期-RCE模块&#xff0c;第七期-File inclusion模块&#xff0c;第八期-Unsafe Filedownload模块。 什么是"遍历"呢&#xff1a;对学过一些开发语言的朋友来说应该知道&…...