UnityShader学习笔记——渲染路径

——内容源自唐老狮的shader课程

目录

1.是什么

2.LightMode标签

3.前向渲染路径(Forward)

3.1.处理光照的方式

3.2.处理各种光源的方式

3.3.在哪里进行光照计算

4.顶点照明渲染路径(Vertex)

5.延迟渲染路径(Deferred)

5.1.处理光照的方式

5.2.在哪里进行光照计算

5.3.内置光照变量

6.对比

6.1.光源的渲染

6.2.Pass

6.3.优缺点

7.如有疏漏,还请指出


1.是什么

        其决定了光照如何应用到Unity Shader中,不同渲染路径获取光源数据的流程不同。因此若想要获取正确的光照,就需要对每个Pass设置其对应的渲染路径。


2.LightMode标签

        LightMode渲染标签是用来指明该Pass匹配的渲染路径是哪种的,它通常需要和Camera中的Rendering Path匹配,用于指定Pass在渲染过程中的哪个阶段

        LightMode的值有如下几种:

        Always:不管使用哪种渲染路径,该Pass始终渲染,但不会计算任何光照

        ForwardBase:前向渲染路径的基础照明阶段执行的Pass,它会计算环境光,重要的平行光,逐顶点/SH光源和Lightamps

        ForwardAdd:前向渲染路径的额外照明阶段执行的Pass,它会计算额外的逐像素光源,每个Pass对应一个光源

        Deferred:延迟渲染路径中执行的Pass,用于几何阶段之后执行光照计算,该Pass会渲染到G缓存(G-buffer)中

        ShadowCaster:用于生成阴影图的Pass,通常用于阴影投射,把物体的深度信息渲染到阴影纹理或一张深度纹理中

        MotionVectors:用于生成运动矢量的Pass,通常用于动态模糊

        Meta:用于在渲染对象元数据时执行的Pass


3.前向渲染路径(Forward)

3.1.处理光照的方式

        主要有三种:

        逐像素处理:需要高等质量的光

        逐顶点处理:需要中等质量的光

        球谐函数(SH)处理:需要低等质量的光。它会将光照场景投影到球谐函数的空间中,通过一系列球谐函数来表示光照。用内存换性能,细节表现效果差

3.2.处理各种光源的方式

        在前向渲染中,一部分最亮的灯光以逐像素处理,然后4个点光源以逐顶点方式处理,其余灯光以SH处理。而一个光源究竟是什么处理取决于以下几点:

        (1)渲染模式设置为Not Important的光源始终以逐顶点或者SH的方式渲染

        (2)渲染模式设置为Important的光源始终以逐像素渲染

        (3)最亮的平行光总是逐像素渲染(当太阳使)

        (4)如果逐像素光照的灯光数量小于项目质量设置中的Pixel Light Count(像素灯光计数)的数量,那么其余比较亮的灯光将会被逐像素渲染 (超过4个可能会被丢弃)

        (5)如果灯光渲染模式为Auto,Unity会根据灯光亮度以及物体的距离自动判断其重要性

        unity一般还会将不同灯光组之间重叠,即同一个光源以多种方式处理。以解决不同渲染模式的光源衔接时会出现瑕疵的问题

3.3.在哪里进行光照计算

        Pass通道中,有两种Pass可以来进行前向光照渲染的光照处理

        Base Pass(基础光照通道,对应LightMode为ForwardBase)

        它是渲染物体的主要通道,用于处理主要的光照效果,主要用于计算逐像素的平行光和所有逐顶点以及SH光源。可以有多个

        默认支持阴影

        可用来实现漫反射,高光反射,自发光,阴影,光照纹理等

        Additional Pass(附加渲染通道,对应LightMode为ForwardAdd,混合一般为one one)

        是渲染物体额外的光照通道,用于处理一些附加的关照效果,主要用于计算所有除了平行光以外影响该物体的逐像素光源,每个光源都会执行一次该Pass

        它默认不支持阴影,需要添加 #pragma multi_compile_fwdadd_fullshadows 来开启阴影

        可用来实现描边,轮廓,辉光等

        

        对于一个物体,一个Base Pass只会执行一次,但Additional Pass会根据影响该物体的其他逐像素光源而被多次调用。且每个逐像素光源都会调用一次Addtional Pass

        虽然但是,具体处理光照的方式还是我们自己来搞的


4.顶点照明渲染路径(Vertex)

        在Pass里将LightMode设置为Vertex即可。通常只需要一个Pass,它会将所有光照一次性按逐顶点的方式计算。

        其硬件要求最低,性能最高,效果最差,不支持逐像素


5.延迟渲染路径(Deferred)

5.1.处理光照的方式

        光照的数量无限制,并且都可以使用逐像素来渲染,支持法线纹理,阴影等效果的处理,但不能处理半透明物体,也不支持真正的抗锯齿,这些会自动使用前向渲染路径

        延迟渲染的效率不取决于场景复杂度,而是与我们使用的屏幕空间的大小有关。原因是延迟渲染路径除了使用颜色缓冲和深度缓冲外,还会使用一个叫G缓存的额外缓存区来存储我们关心的表面(通常是离摄像机最近的表面)的其他信息,如表面的法线,位置,材质属性等。这些缓存区可以理解为一张张的2D图片,我们实际上是在对这些图片进行处理

5.2.在哪里进行光照计算

        同样是Pass通道,主要包含两个Pass

        第一个Pass:主要判断哪些片元可见,并将可见片元的信息存储到G缓存区中,如表面法线,视角向量,漫反射系数等。该Pass通常无需我们自己实现,且对于每个物体,该Pass只会执行一次

        第二个Pass:利用G缓存区中各个片元的相关信息进行真正的相关计算,最终将颜色写入到颜色缓冲区中。使用这个需要将LightMode设置为Deferred。而且这个Pass默认情况下只能Unity内置的标准光照模型进行计算

5.3.内置光照变量

        需要包含UnityGBuffer.cginc

        sampler2D _CameraGBufferTexture0(1, 2, 3...)

        这些变量是自定义变量,第一个Pass的数据会存在它们中。0为漫反射颜色(RGB),遮挡(A);1为镜面反射颜色(RGB),粗糙度(A);2为世界空间法线(RGB),未使用(A);3为发射 + 光照 + 光照贴图 + 反射探针缓冲区;4为光照遮挡值(RGBA)


6.对比

6.1.光源的渲染

        前向:先划分等级,再渲染

        顶点:都按逐顶点,最多八个

        延迟:都可逐像素渲染,光源数量无限制,不能处理半透明物体,不支持真正的抗锯齿

6.2.Pass

        前向:Base:处理一个平行光,所有中低质量光源

                   Additional:除平行光之外的所有高质量

        顶点:一个Pass按逐顶点处理一次性处理所有光源

        延迟:第一个Pass:判断哪些片元可见,并将可见光源信息存储到G缓存

                   第二个Pass:利用G缓存信息进行计算,最终将颜色写入

6.3.优缺点

        前向:优:适用于相对简单的场景和较少数量的光源,基本可以实现任何渲染效果

                   缺:复杂场景和大量光源情况下开销大

        顶点:优:性能开销小

                   缺:效果垃圾

        延迟:优:适用于复杂场景和大量光源,能有效减少光照计算的开销

                   缺:对于透明物体和一些特殊效果不饿能直接支持,需要复杂的处理


7.如有疏漏,还请指出

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

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

相关文章

单片机通讯中的时序图:初学者的入门指南

一、什么是时序图? 在单片机的世界里,时序图是一种非常重要的工具,它用于描述信号在时间上的变化规律。简单来说,时序图就像是信号的“时间线”,它展示了各个信号线在不同时间点上的电平状态。通过时序图,我…

docker常用命令及案例

以下是 Docker 的所有常用命令及其案例说明&#xff0c;按功能分类整理&#xff1a; 1. 镜像管理 1.1 拉取镜像 命令: docker pull <镜像名>:<标签>案例: 拉取官方的 nginx 镜像docker pull nginx:latest1.2 列出本地镜像 命令: docker images案例: 查看本地所有…

集合类不安全问题

ArrayList不是线程安全类&#xff0c;在多线程同时写的情况下&#xff0c;会抛出java.util.ConcurrentModificationException异常 解决办法&#xff1a; 1.使用Vector&#xff08;ArrayList所有方法加synchronized&#xff0c;太重&#xff09; 2.使用Collections.synchronized…

【自开发工具介绍】SQLSERVER的ImpDp和ExpDp工具04

SQLSERVER的ImpDp和ExpDp工具演示 1、指定某些表作为导出对象外 (-exclude_table) 验证用&#xff1a;导出的表&#xff0c;导入到新的数据库 2、指定某些表作为导出对象外 (-exclude_table) 支持模糊检索&#xff0c;可以使用星号 以s开头的表作为导出对象外&#xff0c;…

【大模型】基于LlamaIndex实现大模型RAG

文章目录 一、RAG基础二、使用大语言模型LLMs2.1 使用OpenAI大模型2.2 本地大模型 三、构建RAG pipeline3.1 加载数据3.1.1 SimpleDirectoryReader3.1.2 DatabaseReader3.1.3 直接创建文档Document 3.2 转换数据3.3 索引/嵌入 Indexing & Embedding3.4 存储3.5 查询3.6 评估…

Mac 终端命令大全

—目录操作— ꔷ mkdir 创建一个目录 mkdir dirname ꔷ rmdir 删除一个目录 rmdir dirname ꔷ mvdir 移动或重命名一个目录 mvdir dir1 dir2 ꔷ cd 改变当前目录 cd dirname ꔷ pwd 显示当前目录的路径名 pwd ꔷ ls 显示当前目录的内容 ls -la ꔷ dircmp 比较两个目录的内容 di…

你猜猜 攻防世界

你猜猜 打开附件&#xff1a; 504B03040A0001080000626D0A49F4B5091F1E0000001200000008000000666C61672E7478746C9F170D35D0A45826A03E161FB96870EDDFC7C89A11862F9199B4CD78E7504B01023F000A0001080000626D0A49F4B5091F1E0000001200000008002400000000000000200000000000000…

优惠券平台(一):基于责任链模式创建优惠券模板

前景概要 系统的主要实现是优惠券的相关业务&#xff0c;所以对于用户管理的实现我们简单用拦截器在触发接口前创建一个单一用户。 // 用户属于非核心功能&#xff0c;这里先通过模拟的形式代替。后续如果需要后管展示&#xff0c;会重构该代码 UserInfoDTO userInfoDTO new…

VsCode创建VUE项目

1. 首先安装Node.js和npm 通过网盘分享的文件&#xff1a;vsCode和Node&#xff08;本人电脑Win11安装&#xff09; 链接: https://pan.baidu.com/s/151gBWTFZh9qIDS9XWMJVUA 提取码: 1234 它们是运行和构建Vue.js应用程序所必需的。 1.1 Node安装&#xff0c;点击下一步即可 …

大模型产品Deepseek(五)、本地安装部署(Docker方式)

DeepSeek 本地部署指南 DeepSeek是一款高效的智能搜索与推荐引擎,除了通过云端API提供服务外,它还支持本地部署,让开发者可以完全控制数据和计算资源。通过本地部署,您可以将DeepSeek集成到内部系统中,在私有环境下运行模型,减少对外部API的依赖,同时提升数据隐私性与响…

JVM 中的四类引用:强、软、弱、虚

导言 在 Java 开发中&#xff0c;垃圾收集&#xff08;GC&#xff09;机制通过自动管理内存提升了开发效率。但你是否知道 JVM 通过四种引用类型&#xff08;强、软、弱、虚&#xff09;精细控制对象生命周期&#xff1f; 强引用&#xff08;Strong Reference&#xff09; 特…

数据结构--八大排序算法

1. 直接插入排序 当插入第 i(i>1) 个元素时&#xff0c;前面的 array[0],array[1],…,array[i-1] 已经排好序&#xff0c;此用 array[i] 的排序码与 array[i-1],array[i-2],… 的排序码顺序进行比较&#xff0c;找到插入位置即将 array[i] 插入&#xff0c;原来位置上的元素…

【C/C++算法】从浅到深学习---双指针算法(图文兼备 + 源码详解)

绪论&#xff1a;冲击蓝桥杯一起加油&#xff01;&#xff01; 每日激励&#xff1a;“不设限和自我肯定的心态&#xff1a;I can do all things。 — Stephen Curry” 绪论​&#xff1a; 本章是新开篇章也是算法的第一篇章----双指针算法&#xff0c;双指针算法是算法中非常…

Python内置函数map(), list(), len(), iter(), hex(), hash()的详细解析,包括功能、语法、示例及注意事项

1. map(function, iterable, ...) 功能&#xff1a;对可迭代对象中的每个元素应用指定函数&#xff0c;返回一个迭代器。 参数&#xff1a; function&#xff1a;要执行的函数&#xff08;可以是lambda表达式&#xff09;。 iterable&#xff1a;一个或多个可迭代对象&#x…

Win本地安装Ollama+本地运行大模型+Cherrystudio使用

0. 前言 本文主要介绍 win 本地安装 Ollama &#xff0c;本地部署 Ollama 的 deepseek-r1:7b 大模型&#xff0c;使用具有界面画操作的工具 Cherrystudio进行操作。文章内容仅供参考。 1. Ollama简介 ‌ ‌Ollama 是一个开源的框架&#xff0c;旨在本地运行大型语言模型…

用户点击商品埋点的实现方案

在高并发、可扩展性和高可用性的前提下&#xff0c;实现用户点击商品的埋点&#xff0c;方案应包括 数据采集、数据传输、数据存储和数据分析 四个主要环节。下面是一个完整的埋点实现方案&#xff1a; 1. 方案架构 整体流程&#xff1a; 前端埋点&#xff1a;用户点击商品时…

【C++】AVLTree(AVL树)简单模拟

文章目录 1.AVL树的结点2.AVL树的插入3.AVL树的旋转3.1 新节点插入较高左子树的左侧---左左&#xff1a;右单旋3.2 新节点插入较高右子树的右侧---右右&#xff1a;左单旋3.3 新节点插入较高左子树的右侧---左右&#xff1a;先左单旋再右单旋3.4 新节点插入较高右子树的左侧---…

零基础Vue入门6——Vue router

本节重点&#xff1a; 路由定义路由跳转 前面几节学习的都是单页面的功能&#xff08;都在专栏里面https://blog.csdn.net/zhanggongzichu/category_12883540.html&#xff09;&#xff0c;涉及到项目研发都是有很多页面的&#xff0c;这里就需要用到路由&#xff08;vue route…

【数据结构】(6) LinkedList 链表

一、什么是链表 1、链表与顺序表对比 不同点LinkedListArrayList物理存储上不连续连续随机访问效率O(N)O(1&#xff09;插入、删除效率O(1)O(N) 3、链表的分类 链表根据结构分类&#xff0c;可分为单向/双向、无头结点/有头节点、非循环/循环链表&#xff0c;这三组每组各取…

使用Pygame制作“俄罗斯方块”游戏

1. 前言 俄罗斯方块&#xff08;Tetris&#xff09; 是一款由方块下落、行消除等核心规则构成的经典益智游戏&#xff1a; 每次从屏幕顶部出现一个随机的方块&#xff08;由若干小方格组成&#xff09;&#xff0c;玩家可以左右移动或旋转该方块&#xff0c;让它合适地堆叠在…