Unity中Shader的GI的间接光实现

2023-11-06 01:44
文章标签 实现 unity shader 间接 gi

本文主要是介绍Unity中Shader的GI的间接光实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 一、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));#endifo_gi.light = data.light;o_gi.light.color *= data.atten;#if UNITY_SHOULD_SAMPLE_SHo_gi.indirect.diffuse = ShadeSHPerPixel(normalWorld, data.ambient, data.worldPos);#endif#if defined(LIGHTMAP_ON)// Baked lightmapshalf4 bakedColorTex = UNITY_SAMPLE_TEX2D(unity_Lightmap, data.lightmapUV.xy);half3 bakedColor = DecodeLightmap(bakedColorTex);#ifdef DIRLIGHTMAP_COMBINEDfixed4 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 lightmapo_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 lightmapsfixed4 realtimeColorTex = UNITY_SAMPLE_TEX2D(unity_DynamicLightmap, data.lightmapUV.zw);half3 realtimeColor = DecodeRealtimeLightmap (realtimeColorTex);#ifdef DIRLIGHTMAP_COMBINEDhalf4 realtimeDirTex = UNITY_SAMPLE_TEX2D_SAMPLER(unity_DynamicDirectionality, unity_DynamicLightmap, data.lightmapUV.zw);o_gi.indirect.diffuse += DecodeDirectionalLightmap (realtimeColor, realtimeDirTex, normalWorld);#elseo_gi.indirect.diffuse += realtimeColor;#endif#endifo_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后的效果)

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

这篇关于Unity中Shader的GI的间接光实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/353775

相关文章

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

如何通过Python实现一个消息队列

《如何通过Python实现一个消息队列》这篇文章主要为大家详细介绍了如何通过Python实现一个简单的消息队列,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录如何通过 python 实现消息队列如何把 http 请求放在队列中执行1. 使用 queue.Queue 和 reque

Python如何实现PDF隐私信息检测

《Python如何实现PDF隐私信息检测》随着越来越多的个人信息以电子形式存储和传输,确保这些信息的安全至关重要,本文将介绍如何使用Python检测PDF文件中的隐私信息,需要的可以参考下... 目录项目背景技术栈代码解析功能说明运行结php果在当今,数据隐私保护变得尤为重要。随着越来越多的个人信息以电子形

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景

使用Python快速实现链接转word文档

《使用Python快速实现链接转word文档》这篇文章主要为大家详细介绍了如何使用Python快速实现链接转word文档功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 演示代码展示from newspaper import Articlefrom docx import

前端原生js实现拖拽排课效果实例

《前端原生js实现拖拽排课效果实例》:本文主要介绍如何实现一个简单的课程表拖拽功能,通过HTML、CSS和JavaScript的配合,我们实现了课程项的拖拽、放置和显示功能,文中通过实例代码介绍的... 目录1. 效果展示2. 效果分析2.1 关键点2.2 实现方法3. 代码实现3.1 html部分3.2