【UnityShader入门精要学习笔记】第六章(1)Unity中的基础光照

本文主要是介绍【UnityShader入门精要学习笔记】第六章(1)Unity中的基础光照,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述
本系列为作者学习UnityShader入门精要而作的笔记,内容将包括:

  • 书本中句子照抄 + 个人批注
  • 项目源码
  • 一堆新手会犯的错误
  • 潜在的太监断更,有始无终

总之适用于同样开始学习Shader的同学们进行有取舍的参考。


文章目录

  • 光照的原理
    • 光源
    • 吸收和散射
    • 着色
    • BRDF光照模型
  • 标准光照模型
    • 自发光
    • 环境光
    • 漫反射
    • 高光反射
    • 逐像素还是逐顶点
    • 总结


光照的原理

一个物体为什么看起来是红色的?从物理上解释是因为这个物体能够反射更多的红色波长而吸收了其他波长。

因此想要实现光照渲染,我们就需要模拟光照环境下的物理现象:

  • 首先,光线要从光源(Light Source)中被发射出来
  • 然后,光线和场景中的一些物体相交:一些光线被物体吸收了,而另一些光线被散射到其他方向
  • 最后,摄像机吸收了一些光,产生了一张图像

光源

光是从光源发射出来的。在光学里,我们量化光的标准是辐照度(irradiance),对于平行光而言,辐照度可以通过计算光线方向 l l l(光源照射方向)垂直于单位面积上单位时间穿过的能量来得到。

而在计算光照模型时,若要计算物体表面的辐照度。而物体表面往往和光线方向 l l l是不垂直的,那么我们就会计算光源方向 l l l和表面法线n之间夹角的余弦值来得到。

在这里插入图片描述
(通过上图不难知道为什么 c o s θ cos\theta cosθ可以计算辐照度,假设左图单位面积的长度为8d,那么辐照度就是8d/d = 8 = 单位辐照度。如右图所示,若光线与法线入射角为 θ \theta θ,则两条光线间入射点间距则为 d / c o s θ d/cos\theta d/cosθ,则辐照度 = 8 d / ( d / c o s θ ) = 8 c o s θ = 单位辐照度 ∗ c o s θ = 8d / (d/cos\theta)= 8cos\theta = 单位辐照度 * cos\theta =8d/(d/cosθ)=8cosθ=单位辐照度cosθ

因此 c o s θ cos\theta cosθ就可以使用光源向量 l l l和表面法线向量 n n n的点积来计算得到( l ⋅ n ∣ l ∣ ∣ n ∣ \frac{l \cdot n}{|l||n|} l∣∣nln),因此我们可以通过点积来计算辐照度。(点积也可以理解为光线l在法线n向量方向上的投影与法线n的乘积)

吸收和散射

光线由光源发射出来后,就会与一些物体相交,通常相交的结果只有两个:散射(scattering)和吸收(absorption)

散射只能改变光线的方向,但不改变光线的密度和颜色。吸收改变光线密度和颜色但不改变方向。

光线在物体表面产生散射通常有两种方向,如果散射到物体内部,被称为折射(refraction)。而另一种方向是散射到物体外部,被称为反射(reflection)
在这里插入图片描述

为了区分这两种不同的散射方向,我们在光照模型中使用了不同的部分来计算它们:高光反射/镜面反射(specular) 表示物体表面是如何反射光线的,而漫反射(diffuse) 则表示有多少光线会被折射、吸收和散射出表面。根据入射光线的数量和方向,我们也可以计算出出射光线的数量和方向,我们用出射度(exitance) 来描述它。

辐照度和出射度是满足线性关系的,而它们之间的比值就是材质的漫反射和高光反射属性

而且漫反射是没有方向性的,所以我们可以假设它在各个方向上是平均分布的。因此我们只会考虑某一特定方向上的高光反射。

着色

着色(Shading) 指的是,根据材质属性(如漫反射属性等),光源信息(如光源方向,辐照度等),使用一个等式去计算沿某个观察方向的出射度的过程。我们也把这个等式称为光照模型(Lighing Model) 。不同的光照模型由不同的目的,例如一些用于描述粗糙的物体表面,一些用于描述金属表面等等。


BRDF光照模型

BRDF是一种光照模型,通过给定入射光线的方向和辐照度后,BRDF可以给出在某个出射方向上的光照能量分布。


标准光照模型

标准光照模型是游戏引擎中早期使用的光照模型,原理比较简单,它只关心直接光照。从光源发射出来照射到物体表面的光,经过表面的一次反射直接进入摄像机的光线。

它的基本方法是,把进入到摄像机内部的光线分为4个部分。每个部分使用一种方法来计算它的贡献度:

  • 自发光(emissive) ,在本书中用 C e m i s s i v e C_{emissive} Cemissive来表示。这个部分用于描述当给定一个方向时,一个表面本身会向该方向发射多少辐射度。需要注意的是,如果没有使用全局光照(global illumination)技术,这些自发光的表面并不会真的照亮周围的物体。而是它本身看起来更亮了
  • 高光反射(specular) 部分,本书用 C s p e c u l a r C_{specular} Cspecular来表示,这个部分用于描述当光线从光源照射到模型表面时,该表面会在完全镜面反射方向散射多少辐射量。
  • 漫反射(diffuse) 部分,本书使用 C d i f f u s e C_{diffuse} Cdiffuse来表示,漫反射用于描述,当光线从光源照射到模型表面时,该表面会向每个方向散射多少辐射量。
  • 环境光(ambient) 部分,本书使用 C a m b i e n t C_{ambient} Cambient来表示,用于描述其他所有的间接光照。

自发光

自发光光线会从光源本身直接进入摄像机,无需任何物体表面的反射。自发光的值等于材质本身的自发光颜色值:

C e m i s s i v e = m e m i s s i v e C_{emissive} = m_{emissive} Cemissive=memissive

环境光

虽然标准光照模型通常用于描述直接光照,但是现实中的物体也可以被间接光照所照亮,间接光照指的是,光线通常会在多个物体之间反射,最后进入相机。

例如在红地毯上放置一个灰色的沙发,那么沙发的底部也会反射出由红地毯反射的一部分红光。

我们通过环境光来近似模拟间接光照,环境光就是一个全局变量,场景中的所有物体都使用这个变量:

C a m b i e n t = g a m b i e n t C_{ambient} = g_{ambient} Cambient=gambient

漫反射

漫反射光照的方向是完全随机的,因此我们可以认为在任意反射方向上光照的分布都是一样的,但是入射光线的角度很重要。

漫反射光照符合兰伯特定律 :反射光线的强度与表面法线和光源方向之间的夹角的余弦值成正比,因此,漫反射部分的计算如下:

在这里插入图片描述

高光反射

此处的高光反射也是经验模型,并不完全符合现实中的高光反射现象。它可用于计算那些沿着镜面方向被反射的光线,从而让物体看起来有光泽,例如金属材质

计算高光反射需要知道的信息比较多,如表面法线,视角方向,光源方向,反射方向等。

在这四个向量中,我们只需要知道其中的表面法线,视角方向和光源方向即可。反射方向可以通过其他信息计算:

在这里插入图片描述

其中, m g l o s s m_{gloss} mgloss是材质的光泽度,也被称为反光度。它用于控制高光区域的大小, m g l o s s m_{gloss} mgloss越大,高光区域呈现的亮点越小。 m s p s c u l a r m_{spscular} mspscular是材质的高光反射颜色,用于控制该材质对于高光反射的强度和颜色。

除了上述的Phong模型,还有一个类似的Blinn模型:
在这里插入图片描述
Blinn模型引入了一个归一化矢量h,并使用n和h的夹角进行计算。通常来说,若v和I向量是定值时Blinn模型更快。反之是Phong模型更快。


逐像素还是逐顶点

这些光照模型是在着色器中进行计算的。若在片元着色器中进行计算,就被称为逐像素光照,而在顶点着色器中计算,则被称为逐顶点光照

在逐像素光照中,我们以每个像素为基础,得到它的法线(可以是对顶点法线进行插值得到的,也可以从法线纹理中采样得到)。并进行光照模型的计算。这种在片元着色器中,在面片之间对顶点法线插值的技术被称为Phong着色 ,也被称为Phong插值或者法线插值着色技术。注意,此处的Phong着色不同于我们说的Phong光照模型。

与之相对的是逐顶点光照,被称为高洛德着色(Gouraud shading) 。在逐顶点光照中,我们在每个顶点上计算光照,然后会在渲染图元内部进行线性插值,最后输出成像素颜色。

由于顶点数远远少于像素点数,因此逐顶点光照的计算量少于逐像素光照。但是,由于逐顶点光照依赖于通过顶点的线性插值输出像素颜色,因此若光照模型中有非线性计算的时候(例如计算高光反射时),逐顶点光照就会出现问题。

总结

在上文中我们了解了,光照我们通常用辐照度来描述其强度,并可以用光源方向l和法线向量n的夹角余弦值 c o s θ cos\theta cosθ来描述光的辐照度。

在光线发射过程中会发生吸收和散射两种现象。为了模拟光照,我们通常用光照模型对光线进行计算着色。

在标准光照模型中,通常存在四类光线:
自发光——材质自身的发光值,
环境光——反射光照的间接光照,通常用全局变量来表示,
漫反射——与辐照度类似,反射光线的强度与表面法线和光源方向之间的夹角的余弦值成正比;
高光反射——一个非线性的经验模型,一般有Phong模型和Blinn模型两种。

在对着色器进行光照计算的时候,通常有逐像素和逐顶点两种模式。如果使用片元着色器进行光照渲染,则是逐像素光照,逐像素光照以每个像素为单位进行光照颜色计算,其中每个像素点的法线可以通过顶点进行插值计算获取,或者直接从法线纹理中获取。

若使用顶点着色器进行渲染则为逐顶点光照。逐顶点光照只计算片元顶点上的光照,并直接通过顶点间的线性插值来计算其中每个像素的颜色。

显然逐顶点计算的计算量远小于逐像素计算。但是逐顶点计算的缺陷在于依赖对顶点的线性插值。若光照模型中包含非线性的计算时(例如计算高光反射),逐顶点计算就会出问题。

标准光照模型我们也称为Blinn-Phong光照模型。但这种模型也存在很多局限性,首先很多重要的物理线性无法通过Blinn-Phong模型来表现出来,例如菲涅尔反射

其次,Blinn-Phong模型是各向同性的 ,即当我们旋转物体表面时,光照反射不会发生任何改变。但是有些表面材质是需要各向异性的,例如金属,毛发等。后文中,我们将学习基于物理的光照模型,这些模型将会更加复杂。

这篇关于【UnityShader入门精要学习笔记】第六章(1)Unity中的基础光照的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

数论入门整理(updating)

一、gcd lcm 基础中的基础,一般用来处理计算第一步什么的,分数化简之类。 LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a; } <pre name="code" class="cpp">LL lcm(LL a, LL b){LL c = gcd(a, b);return a / c * b;} 例题:

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

Java 创建图形用户界面(GUI)入门指南(Swing库 JFrame 类)概述

概述 基本概念 Java Swing 的架构 Java Swing 是一个为 Java 设计的 GUI 工具包,是 JAVA 基础类的一部分,基于 Java AWT 构建,提供了一系列轻量级、可定制的图形用户界面(GUI)组件。 与 AWT 相比,Swing 提供了许多比 AWT 更好的屏幕显示元素,更加灵活和可定制,具有更好的跨平台性能。 组件和容器 Java Swing 提供了许多