Shader入门-------基础光照
发布日期:2021-07-22 10:54:05 浏览次数:9 分类:技术文章

本文共 3526 字,大约阅读时间需要 11 分钟。

Shader入门-------基础光照

前记:真正入门了,多图(代码也用图展示了)-------------博主:mx
Unity Shader的基本结构
在这里插入图片描述

其中在这里插入图片描述声明了顶点着色器的函数,片元着色器的函数

一个最简单的顶点/片元着色器

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

ShaderLab属性类型和CG变量类型之间的匹配关系

在这里插入图片描述

CGIncludes中主要包含的文件以及它们的主要用处

在这里插入图片描述

UnityCG.cginc中一些常用的结构体

在这里插入图片描述

UnityCG.cginc中一些常用的帮助函数

在这里插入图片描述

从应用阶段传递模型数据给顶点着色器时Unity支持的常用语义

在这里插入图片描述

从顶点着色器传递数据给片元着色器时Unity使用的常用语义

在这里插入图片描述
博主:mx

片元着色器输出时Unity支持的常用语义

在这里插入图片描述

Unity中对Unity Shader的调试方法(可自行百度使用方法)

1.使用假彩色图像
2.使用Visual Studio中的Graphics Debugger
3.使用帧调试器

不同渲染平台的差异

渲染纹理的坐标差异
在这里插入图片描述

(注意:当我们使用到渲染到纹理技术,把屏幕图像渲染到一张渲染纹理中时,特别是开启抗锯齿(Edit > Project Settings -> Quality -> Anti Aliasing中开启)并同时处理多张渲染图像时,就会出现纹理翻转的情况)

Shder的语义差异

其他平台差异

Shder代码规范建议

CG/HLSL中3种精度的数值类型
在这里插入图片描述

(建议:尽可能使用精度较低的类型,因为这可以优化Shader的性能,这一点在移动平台上尤其重要。从它们大体的值域范围来看,我们可以使用fixed类型来存储颜色和单位矢量,如果要存储更大范围的数据可以选择half类型,最差情况下再选择使用float)

使用和变量类型相匹配的参数数目来对变量进行初始化

避免不必要的计算

Shader中进行了过多的运算,使得需要的临时寄存器数目或指令数目超过了当前可支持的数目。通常,我们可以通过制定更高级的Shader Target 来消除这些错误。下表给出了Unity 目前支持的Shader Target。

在这里插入图片描述

慎用分支和循环语句

建议:分支判断语句中使用的条件变量最好是常数,即在Shader运行过程中不会发生变化;每个分支中包含的操作指令数尽可能少;分支的嵌套层数尽可能少。

不要除以0

光照的基础知识

辐照度:量化光的一个指标。对于平行光来说,它的辐照度可以通过计算在垂直于l的单位面积上单位时间内穿过的能量来得到
散射:散射只改变光线的方向,但是不改变光线的密度和颜色。分为折射(透射)和反射
反射:高光反射部分表示物体表面是如何反射光线的,而漫反射部分表示有多少光线会被折射、吸收、散射出表面
出射度:根据入射光线的数量和方向,可以计算出出射光线的数量和而方向,我们常用出射度来描述它。辐照度和出射度之间满足线性关系,他们之间的比值就是材质的漫反射和高光反射属性
着色:根据材质属性(如漫反射属性等)、光源信息(如光源方向、辐照度等),使用一个等式去计算沿某个观察方向的出射度的过程。我们也把这个等式称为光照模型

标准光照模型

标准光照模型只关心直接光照(direct lIght),也就是那些直接从光源发出照射到物体表面后,经过物体表面的一次反射直接进入摄像机的光线。

·自发光(emissive):使用在这里插入图片描述表示,用于描述给定一个方向时,一个表面本身会向改方向发射多少辐射量。需要注意的是,如果没有使用全局光照技术,这些自发光的表面并不会真的照亮周围的物体,只是使他本身看起来更亮而已。

光线也可以直接由光源发射进入摄像机,而不需要经过任何物体的反射。标准光照模型使用自发光来计算这个部分的贡献度。它的计算也很简单,就是直接使用了该材质的自发光颜色:在这里插入图片描述

·高光反射(specular):使用在这里插入图片描述表示,这部分用于描述当光线从光源照射到模型表面,该表面会在完全反射方向散射多少辐射量

计算高光反射需要知道的信息比较多,如表面法线、视角方向、光源方向、反射方向等。我们假设这些矢量都是单位矢量,下图给出了这些方向矢量:
在这里插入图片描述

在这四个矢量中,我们实际上只需要知道其中3个矢量即可,而第4个矢量——反射方向可以通过其他信息计算得到:在这里插入图片描述

我们就可以利用Phong模型来计算高光反射的部分:

在这里插入图片描述

其中Mgloss是材质的光泽度,也被称为反光度。它用于控制高光区域的“亮点”有多宽,Mgloss越大,亮点就越小。Mspscular是材质的高光反射颜色,它用于控制该材质对于高光反射的强度和颜色。Clight则是光源的颜色和强度。

Blinn模型避免计算反射方向r,引入了一个新的矢量h,h通过对v和I的取平均然后归一化得到。Blinn模型计算公式如下:

在这里插入图片描述

在硬件实现时,如果摄像机和光源距离模型足够远的话, Blinn模型会快于Phong模型,这是因为此时可以认为v和I都是定值,因此将是一个常量。但是,当v或者I不是定值时, Phong模型可能反而更快一些。需要注意的是,这两种光照模型都是经验模型。

·漫反射(diffuse):使用在这里插入图片描述表示,描述当光线从光源照射到模型表面时,该表面会向每个方向散射多少辐射量。

漫反射光照符合兰伯特定律(Lambert’s law):反射光线的强度与表面法线和光源方向之间夹角的余弦值成正比。漫反射部分的计算如下:在这里插入图片描述
博主:mx

其中,n是表面法线,I是指向光源的单位矢量, Mdiffuse是材质的漫反射颜色, Clight是光源颜色。需要注意的是,我们需要防止法线和光源方向点乘的结果为负值,为此,我们使用取最大值的函数来将其截取到0,这可以防止物体被从后面来的光源照亮。

·环境光(ambient):使用在这里插入图片描述表示,它用于描述其他所有的间接光照。

虽然标准光照模型的重点在于描述直接光照,但在真实的世界中,物体也可以被间接光照(indirect light)所照亮。间接光照指的是,光线通常会在多个物体之间反射,最后进入摄像机,也就是说在光线进入摄像机之前,经过了不止一次的物体反射。
在标准光照模型中,使用依照你被称为环境光的部分来近似模拟简介光照。计算公式:在这里插入图片描述

逐像素光照和逐顶点光照

逐像素光照:在片元着色器中计算。在逐像素光照中,我们会以每个像素为基础,得到它的法线(可以是对顶点法线插值得到的,也可以是从法线纹理中采样得到的),然后进行光照模型的计算。这种在面片之间对顶点法线进行插值的技术被称为Phong着色(Phong shading)也被称为Phong插值或法线插值着色技术。这不同于我们之前讲到的Phong光照模型。
逐顶点光照:在顶点着色器中计算。其中的着色方法位高洛德着色。在逐顶点光照中,我们在每个顶点上计算光照,然后会在渲染图元内部进行线性插值,最后输出成像素颜色。由于顶点数目往往远小于像素数目,因此逐顶点光照的计算量往往要小于逐像素光照。但是,由于逐顶点光照依赖于线性插值来得到像素光照,因此,当光照模型中有非线性的计算(例如计算高光反射时)时,逐顶点光照就会出问题。而且,由于逐顶点光照会在渲染图元内部对顶点颜色进行插值,这会导致渲染图元内部的颜色总是暗于顶点处的最高颜色值,这在某些情况下会产生明显的棱角现象。

在Unity Shader中分别用逐顶点光照、逐像素光照实现光照模型(额外:逐像素半兰伯特–Blinn模型、在顶点着色器中计算漫反射而在片元着色器中计算高光反射)

前记知识:
CG中可以使用seturate函数实现max功能
函数:saturate(x)参数:x:为用于操作的标量或矢量,可以是float, float2,float3等类型。描述:把x截取在[0,1]范围内,如果x是一个矢量,那么会对它的每一个分量进行这样的操作。

CG中可以使用reflect函数求出反射方向

函数:reflect(i,n)参数: i—入射方向: n—法线方向。可以是float,float2, float3等类型。描述:当给定入射方向i和法线方向n时,reflect函数可以返回反射方向。
在这里插入图片描述

UnityCG.cginc中一些常用的帮助函数

在这里插入图片描述

(注意:这些函数没有保证得到的方向矢量是单位矢量,使用之前记得归一化)

博主:mx

实例:

在这里插入图片描述

(胶囊体从左到右分别是逐顶点漫反射、逐像素半兰伯特漫反射、逐像素漫反射、逐顶点漫/高光反射、逐像素漫/高光反射、逐像素半兰伯特–Blinn反射、逐顶点漫反射–逐像素高光反射)

逐顶点漫反射代码:

在这里插入图片描述

逐像素半兰伯特漫反射:

在这里插入图片描述

逐像素漫反射:

在这里插入图片描述

逐顶点漫/高光反射:

在这里插入图片描述

博主:mx

逐像素漫/高光反射:
在这里插入图片描述

逐像素半兰伯特–Blinn反射:

逐顶点漫反射–逐像素高光反射:

在这里插入图片描述
博主:mx

转载地址:https://blog.csdn.net/m0_56399931/article/details/116063774 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Shader入门-------基础纹理
下一篇:Shader预备知识二-------所需的数学基础

发表评论

最新留言

做的很好,不错不错
[***.243.131.199]2024年04月25日 00时40分41秒