Unity中Shader的GI的间接光实现

news2024/11/28 13:37:25

文章目录

  • 前言
  • 一、GI中 间接光照的实现
    • 1、看Unity的源码可知,在计算GI的间接光照时,最主要的实现是在UnityGI_Base函数中
  • 二、分析 UnityGI_Base 中实现的功能
    • 1、ResetUnityGI的作用
    • 2、第一个#if中实现的功能:计算在Distance Shadowmask 中实时阴影与烘培阴影的混合过程
    • 3、第二个#if中实现的功能:计算使用球谐光照(当使用光照探针后的效果)
    • 4、第三个#if中实现的功能:计算静态 GI (当使用BackedGI后的效果)
    • 5、第四个#if中实现的功能:计算动态 GI (当使用RealtimeGI后的效果)


前言

Unity中Shader的GI的间接光实现。在上一篇文章中,我们实现了GI中的直接光。但是,Global Illumination 是由 直接光 加 间接光 后的结果,所以我们还需要准备 GI 中的间接光。

  • Unity中Shader的GI的直接光实现

一、GI中 间接光照的实现

1、看Unity的源码可知,在计算GI的间接光照时,最主要的实现是在UnityGI_Base函数中

在这里插入图片描述

UnityGI_Base如下:

inline UnityGI UnityGI_Base1(UnityGIInput data, half occlusion, half3 normalWorld)
{
    UnityGI o_gi;
    ResetUnityGI1(o_gi);

    // Base pass with Lightmap support is responsible for handling ShadowMask / blending here for performance reason
    #if defined(HANDLE_SHADOWS_BLENDING_IN_GI)
        half bakedAtten = UnitySampleBakedOcclusion(data.lightmapUV.xy, data.worldPos);
        float zDist = dot(_WorldSpaceCameraPos - data.worldPos, UNITY_MATRIX_V[2].xyz);
        float fadeDist = UnityComputeShadowFadeDistance(data.worldPos, zDist);
        data.atten = UnityMixRealtimeAndBakedShadows(data.atten, bakedAtten, UnityComputeShadowFade(fadeDist));
    #endif

    o_gi.light = data.light;
    o_gi.light.color *= data.atten;

    #if UNITY_SHOULD_SAMPLE_SH
        o_gi.indirect.diffuse = ShadeSHPerPixel(normalWorld, data.ambient, data.worldPos);
    #endif

    #if defined(LIGHTMAP_ON)
        // Baked lightmaps
        half4 bakedColorTex = UNITY_SAMPLE_TEX2D(unity_Lightmap, data.lightmapUV.xy);
        half3 bakedColor = DecodeLightmap(bakedColorTex);

        #ifdef DIRLIGHTMAP_COMBINED
            fixed4 bakedDirTex = UNITY_SAMPLE_TEX2D_SAMPLER (unity_LightmapInd, unity_Lightmap, data.lightmapUV.xy);
            o_gi.indirect.diffuse += DecodeDirectionalLightmap (bakedColor, bakedDirTex, normalWorld);

            #if defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK) && defined(SHADOWS_SCREEN)
                ResetUnityLight(o_gi.light);
                o_gi.indirect.diffuse = SubtractMainLightWithRealtimeAttenuationFromLightmap (o_gi.indirect.diffuse, data.atten, bakedColorTex, normalWorld);
            #endif

        #else // not directional lightmap
            o_gi.indirect.diffuse += bakedColor;

            #if defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK) && defined(SHADOWS_SCREEN)
                ResetUnityLight(o_gi.light);
                o_gi.indirect.diffuse = SubtractMainLightWithRealtimeAttenuationFromLightmap(o_gi.indirect.diffuse, data.atten, bakedColorTex, normalWorld);
            #endif

        #endif
    #endif

    #ifdef DYNAMICLIGHTMAP_ON
        // Dynamic lightmaps
        fixed4 realtimeColorTex = UNITY_SAMPLE_TEX2D(unity_DynamicLightmap, data.lightmapUV.zw);
        half3 realtimeColor = DecodeRealtimeLightmap (realtimeColorTex);

        #ifdef DIRLIGHTMAP_COMBINED
            half4 realtimeDirTex = UNITY_SAMPLE_TEX2D_SAMPLER(unity_DynamicDirectionality, unity_DynamicLightmap, data.lightmapUV.zw);
            o_gi.indirect.diffuse += DecodeDirectionalLightmap (realtimeColor, realtimeDirTex, normalWorld);
        #else
            o_gi.indirect.diffuse += realtimeColor;
        #endif
    #endif

    o_gi.indirect.diffuse *= occlusion;
    return o_gi;
}

所以我们在片元着色器中可以直接给 gi 赋值,不使用 LightingLambert_GI1函数

gi = UnityGI_Base1(giInput,1,o.Normal);

可以看出,效果是一样的:
请添加图片描述


二、分析 UnityGI_Base 中实现的功能

1、ResetUnityGI的作用

在这里插入图片描述

由图可见:这个 ResetUnityGI1 函数的作用是和之前初始化的函数 UNITY_INITIALIZE_OUTPUT 功能一样的。

然后,除掉 #if 的部分,主要实现了以下功能。
在这里插入图片描述

2、第一个#if中实现的功能:计算在Distance Shadowmask 中实时阴影与烘培阴影的混合过程

在这里插入图片描述

3、第二个#if中实现的功能:计算使用球谐光照(当使用光照探针后的效果)

在这里插入图片描述

4、第三个#if中实现的功能:计算静态 GI (当使用BackedGI后的效果)

在这里插入图片描述

光照图的采样(核心部分)

在这里插入图片描述
之后这个功能是在Unity中开启 定向光 模式时使用

在这里插入图片描述

在这里插入图片描述

5、第四个#if中实现的功能:计算动态 GI (当使用RealtimeGI后的效果)

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

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

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

相关文章

网络资料(忘传了)

1网络分层模型和应用协议 1.1分层模型 1.1.1分层的意义 当遇到一个复杂问题的时候,可以使用分层的思想把问题简单化 比如,你有半杯82年的可乐,想分享给你的朋友王富贵,但你们已经10年没有联系了。要完成这件事,你可…

JavaScript引用数据类型(对象类型)和原始(基本)数据类型特点比较

JavaScript引用数据类型(对象类型)和原始(基本)数据类型特点比较 为讲解JavaScript引用数据类型(对象类型)和原始(基本)数据类型特点比较,需要先回顾JavaScript数据类型…

UE5——源码阅读——3——引擎退出

这边主要是做了个标记,为了UE的性能分析 把全局运行设置为0,把日志也设置为空 判断预加载屏幕 关闭visual logger 关闭资源编译的管理器 引擎预退出 预退出的核心代理 关闭网络追踪 关闭所有电影场景的捕捉接口 关闭UE中用于MID的缓存 关闭引擎…

哆啦百宝箱APP

专门为年轻人设计的APP,主打的免费、无恶心广告、不获取任何个人信息。 哆啦百宝箱 ● 永久免费 ● 无恶心广告 ● 种类巨多 ● 全民参与 ● 爆款功能 ● 用心创造 哆啦百宝箱 提供了从日常、图片、查询、设备、趣味、娱乐等多方面的功能, 操作简单&a…

postMessage

A:端口3000 import React, { useEffect } from react;function App() {useEffect(() > {const childWindow document.getElementById(child).contentWindow;const sendMessageToChild () > {childWindow.postMessage("主页面消息", "http://localhost:…

Java 数据结构篇-实现单链表核心API

🔥博客主页: 小扳_-CSDN博客 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 单链表的说明 2.0 单链表的创建 2.1 单链表 - 头插节点 2.2 单链表 - 遍历 2.2.1 使用简单的 for/while 循环 2.2.2 实现 forEach 方法 2.2.3 实现迭代器的方法 2.…

使用腾讯云服务器建站流程(新手站长指南)

使用腾讯云服务器搭建网站全流程,包括轻量应用服务器和云服务器CVM建站教程,轻量可以使用应用镜像一键建站,云服务器CVM可以通过安装宝塔面板的方式来搭建网站,腾讯云服务器网txyfwq.com分享使用腾讯云服务器建站教程,…

【网络协议】聊聊CND如何进行提升系统读性能

我们知道对于京东这种仓储来说,其实并不是在北京有一个仓储中心,而是针对全国主要的地方,北京、上海、广州、杭州,郑州等地方都有自己的仓储中心,当用户下单后,就会根据最近的仓储进行发货,不仅…

第二章:input partitioning

文章目录 Input partitioninginput partitioning 的目的computational / domain faults等价类(equivalence classes)input conditions & valid / invalid inputspartitioning and equivalence classes等价类划分的原则 白盒 - Domain testing复合谓词…

curl(七)上传和下载

一 上传 ① -T | --upload 上传 ​1、向ftp服务器 传一个文件:curl -T localfile -u name:passwd ftp://upload_site:port/path/2、向http服务器上传文件curl -T localfile http://www.wzj.com/wzj.html注意: 这时候使用的协议是HTTP的PUT…

全球首款双模型AI手机METAVERTU2,为用户开发“第二大脑”

在2023年11月1日,英国奢侈手机品牌VERTU在香港举办了一场新品发布会,它推出了一款全新的AI手机称为METAVERTU2,这是全球首款双模型AI手机。此款手机将Web3技术与人工智能相结合,通过AI模型标记数据和AI Agent的方式,将…

在线安装Arthas以及常用命令介绍

Arthas介绍:arthas(阿尔萨斯)是阿里巴巴开源的一款 Java 诊断工具,它可以对运行中的 Java 程序进行实时监控和故障排查。Arthas 提供了丰富的功能,如线程分析、内存分析、类加载分析等,帮助开发者快速定位问题并提高开发效率。 主…

自动控制原理答案

题目 现有一个单位反馈系统的开环传递函数为 试对该系统进行以下分析。 1.基础分析 计算该系统的闭环传递函数。 2.稳定性分析 2.1 使用劳斯判据分析该系统的稳定性 2.2 使用MATLAB编程,计算该系统有关于稳定性分析的零、极点,分析其稳定性。 3.暂态性…

性能测试知多少---吞吐量

我们每天的生活中都在用水用电,我只会关心自己的水管是否有水,水压是否稳定,如果我们把水龙头拧到最大,还是一滴一滴的流水。那我们就要愤怒了,直接找房东问明情况。我们从来没想过去找自来水公司。我们每天都会上网&a…

【原创】java+swing+mysql宠物领养管理系统设计与实现

摘要: 生活中,有很多被人遗弃的宠物,这些宠物的处理成为了一个新的难题。生活中也有许多人喜欢养宠物,为了方便大家进行宠物领养,提高宠物领养管理的效率和便利性。本文针对这一问题,提出设计和实现一个基…

Matlab上机三(Apriori算法)

1、题目要求 (1) 读取给定的交易数据库test3.txt,将整个交易数据库表示为一个矩阵,每个元组表示成一个行向量,向量长度为4。其中,一个项目出现在这个元组中,则相应位置设为1,否则为…

比亚迪被曝 24 小时收到 12 万份简历?

众所周知,今年找工作的难度都相当大,不论是应届毕业生还是经验丰富的职场人士,都面临相同的困境。然而,没想到情况居然如此糟糕,着实让人震惊。 最近,比亚迪公司被曝收到了12万份简历,简历投递…

深度学习框架TensorFlow.NET环境搭建1(C#)

测试环境 visual studio 2017 window10 64位 测试步骤如下: 1 新建.net framework控制台项目,工程名称为TensorFlowNetDemo,.net framework的版本选4.7.2,如下图: 2 分别安装TensorFlow.NET包(先装)和SciSharp.…

分治法——找众数

分治法——找众数 要求: 寻找整数数组的众数,如果存在多个众数,则返回权值最小的那个 第一步: 要利用分治法找众数,首先就先要使数组有序。这里,我们用C语言库中的qsort进行快排: qsort(nums…