US2S3L12——CG内置函数
US2S3L12——CG内置函数
CG内置函数
Unity Shader中的CG语言提供了各种用于图形编程的函数
这些函数是CG为我们封装好的逻辑,我们可以使用它们来编写Unity Shader
可以通过以下链接来查看更多的相关函数:内部函数 - Win32 apps | Microsoft Learn
这是HLSL对应的内置函数,CG和它类似 (注意:不是所有函数都在Unity中被支持)
数学函数
三角函数相关
1234567891011sincos(float x, out s, out c) //该函数同时计算x的sin值和cos值通过s和c进行返回(比分别运算快很多)sin(x) //正弦函数cos(x) //余弦函数tan(x) //正切函数sinh(x) //双曲正弦函数cosh(x) //双曲余弦函数t ...
US2S3L11——ShaderLab属性类型和CG变量类型的匹配关系
US2S3L11——ShaderLab属性类型和CG变量类型的匹配关系
回顾:ShaderLab属性相关
关于ShaderLab属性,详见US2S2L4——Shader的属性
123456789101112131415Properties { } //属性在该语句块内声明_属性名("在Inspector窗口上显示的属性名", 类型) = 默认值 //属性的声明方法,要注意属性名默认前缀为'_'//数值类型,以一个数值作为默认值,数值不需要加fInt //整形,虽然提供了整数,但是编译时最终都会转换为浮点型Float //浮点型,在ShaderLab里,浮点数字面量不需要加fRange(,) //范围浮点型,需要在括号内()填写最小值和最大值//颜色与向量类型,以(num1,num2,num3,num4)作为默认值,其中的数值不需要加fColor //颜色,颜色值中的RGBA的取值范围是 0~1 (映射0~255)Vec ...
US2S3L10——顶点-片元着色器传递更多参数
US2S3L10——顶点-片元着色器传递更多参数
顶点/片元着色器传递更多参数
如果顶点/片元着色器想要传递更多参数,我们需要通过结构体进行封装,用语义修饰结构体成员变量来达到目的
注意:只有顶点/片元着色器的回调函数相关参数和返回值才需要通过语义修饰
一般的自定义函数是不需要语义的,因为我们自己调用自己的自定义函数是可以明确知道每个参数的作用的
顶点着色器获取更多数据信息
当我们在顶点着色器当中想要获取更多模型相关信息时,可以使用结构体对数据进行封装
通过对结构体中成员变量加语义的方式来定义想要获取的信息
使用结构体作为参数和返回值类型后,函数的参数和返回值就不需要再使用语义进行修饰了
我们也可以不用自己声明结构体,而使用Unity定义好的结构体,详见:结构体(UnityCG.cginc中)
假设顶点着色器需要接收来自应用阶段的更多语义的参数,如:模型空间下的顶点坐标,顶点法线,uv坐标
这时我们需要声明一个结构体,其中的成员使用对应的语义修饰,然后将其作为顶点着色器的参数
12345678910111213141516171819#pragma vertex myVert//从应 ...
US2S3L9——语义
US2S3L9——语义
语义
CG语言中提供了 语义 这种特殊关键字用于修饰函数中的传入参数和返回值
它的主要作用是让Shader知道从哪里读取数据,并把数据输出到哪里
让我们在Shader开发当中可以获取到想要的数据,并且可以把数据传递到正确的目标
以最简单的顶点着色器为例:
POSITION:应用阶段准备好的顶点数据会传入到该函数内,因此该参数需要这个语义来指定需要模型的顶点消息
SV_POSITION:模型的顶点需要转换到裁剪空间,因此该函数的返回值需要这个语义来指定函数返回值代表裁剪空间下的坐标
1234567#pragma vertex myVert//顶点着色器 回调函数float4 myVert(float4 v : POSITION) : SV_POSITION{ return UnityObjectToClipPos(v); //假设这里对顶点坐标进行变换,将变换出的顶点坐标返回出去}
注意:Unity中只支持CG当中的部分语义
语义的主要作用是让 Shader 知道从哪里读取数据,并把数据输出到哪里
我们在编写顶点片元着色 ...
US2S3L8——顶点-片元着色器基本结构
US2S3L8——顶点-片元着色器基本结构
顶点着色器的基本结构
首先需要使用 #pragma vertex 来指定实现顶点着色器的函数
最基础的顶点着色器函数要求:
参数类型为 float4,它代表传入的顶点的坐标,该参数需要由 POSITION 语义修饰,它代表**把模型的顶点坐标填充到这个参数当中**
返回值类型为 float4,它代表经过变换的顶点坐标,返回值需要由 SV_POSITION 语义修饰,它代表**输出的内容是裁剪空间中的顶点坐标**
函数内部需要对传入的模型空间的顶点坐标转换到裁剪空间后再返回出去
可以使用 mul(UNITY_MATRIX_MVP, *),其中mul()是CG提供的内置的矩阵和向量的乘法运算函数,
UNITY_MATRIX_MVP 代表一个变换矩阵,是Unity内置的模型M,观察V,投影P矩阵的集合
上面的写法是旧写法,在Unity2022内,它将被Unity自动替换为UnityObjectToClipPos(v),它是Unity封装的函数,效果是一样的
关于语义是什么,详见:US2S3L9——语义
12345 ...
US2S3L7——函数
US2S3L7——函数
本章代码关键字
12in //表示输入参数,用于外部传给内部,内部只会用,不会改,可以有多个out //表示输出参数,用于内部传给外部,内部必须初始化或修改,可以有多个
函数
CG语法中的函数声明和使用几乎和C#中一模一样
区别主要是CG中的 in 和 out 关键字
in 表示输入参数,用于外部传给内部,内部只会用,不会改,可以有多个
out 表示输出参数,用于内部传给外部,内部必须初始化或修改,可以有多个
对于有返回值的函数,要不采用返回值形式,要不采用 out
无返回值的函数
基本结构:
1234void name(in 参数类型 参数名, out 参数类型 参数名){ 函数体}
void:以 void 开头,表示没有返回值
name:函数的名称
in:表示是输入参数,表示由函数外部传递给函数内部,内部不会修改该参数,只会使用该参数进行计算,允许有多个
out:表示是输出参数,表示由函数内部传递给函数的调用者,在函数内部必须对该参数值进行初始化或修改,允许有多个
注 ...
US2S3L6——流程控制语句
US2S3L6——流程控制语句
流程控制语句
CG语法中的流程控制语句和C#中的使用一模一样
需要注意的是,在使用它们时要更多的考虑性能消耗
尽量少的使用循环语句,如果一定要用要减少次数和复杂度
要利用GPU并行性这一特点来替代循环
尽量避免复杂的条件分支
条件分支语句
尽量避免复杂的条件分支
if 语句
switch 语句
条件分支语句的使用和C#中一模一样
循环语句
尽量少的使用循环语句,如果一定要用要减少次数和复杂度
要利用GPU并行性这一特点来替代循环
for 循环
while 循环
do…while 循环
循环语句的使用和C#中一模一样
US2S3L5——运算符相关
US2S3L5——运算符相关
运算符
CG语法中比较、条件、逻辑、数学等运算符的使用和C#中一致,需要注意的是:
逻辑运算符在CG中不存在C#中的"短路"操作
数学运算符在CG中取余符号只能向整数取余
比较运算符
CG语言中比较运算符包括
大于 >
小于 <
大于等于 >=
小于等于 <=
等于 ==
不等于 !=
CG中的比较运算符的使用和C#中一样,详见:CS1L11——条件运算符,运算结果为 bool 值
1234fixed f1 = 3;fixed f2 = 4;bool result = f1 > f2;
条件运算符
CG语言中条件运算符(三目(三元)运算符)
1condition ? value_if_true : value_if_false
condition 是一个条件表达式
如果 condition 为真将返回 value_if_true
否则返回 value_if_false
CG中的条件运算符的使用和C#的三目运算符中一样
1234fixed f1 = 3;fixed f2 = ...
US2S3L4——Swizzle操作符
US2S3L4——Swizzle操作符
Swizzle操作符
上节课我们学习了向量,但是我们并没有讲解如何获取向量中某元素的相关知识点
而这节课将要学习的Swizzle操作符就可以用于获取向量中元素
Swizzle操作符通常以点号( . )的形式使用,后面跟着所需的分量顺序
对于四维向量来说,我们可以通过:向量.xyzw 或 向量.rgba
两种分量的写法来表示向量中的四个值
其中 xyzw 和 rgba 分别代表四维向量中的四个元素
在此的意义就是向量一般可以用来表示坐标和颜色
向量获取元素可以利用Swizzle操作符获取
矩阵获取元素和二维数组获取方式一样
Swizzle操作符可以让我们对向量进行方便的操作
向量和矩阵在声明和获取时可以配合使用
高维向量或矩阵可以用低维容器装载,可以利用这个特点将4维变3维,4x4变3x3
Swizzle操作符使用方法
利用它来提取分量,使用 xyzw 或 rgba
123456789fixed4 f4 = fixed4(1, 2, 3, 4);fixed f;//提取第一个分量f = f4.x;f = f4.r;//提取第 ...
US2S3L3——特殊数据类型
US2S3L3——特殊数据类型
本章代码关键字
12数值类型维数 向量名 = 数值类型维数(num, ...) //向量声明,最大维度不超过4维,可以使用bool声明bool向量数值类型行数x列数 = { num, ... } //矩阵声明,矩阵最大行列不大于4,不小于1
特殊数据类型
注意:CG中向量,矩阵和数组是完全不同的,向量和矩阵是内置的数据类型,而数组则是一种数据结构,不是内置数据类型
CG可以声明任意数值类型的矩阵和向量
向量最大维度不超过4维
矩阵最大行列不大于4,不小于1,在赋值时一定注意行列的关系
bool 向量可以用来存储向量之间比较的结果
向量
向量类型属于CG语言的内置数据类型
内置的向量类型是基于基础数据类型声明的
向量的最大维度不超过4维,数据类型可以是任意数值类型(也就是基础数据类型的数值类型)
基本构成:
数据类型2 = 数据类型2(n1,n2)
数据类型3 = 数据类型3(n1,n2,n3)
数据类型4 = 数据类型4(n1,n2,n3,n4)
123456789/ ...