建好的网站能修改吗,有源码怎么做app,GPS实时定位网站怎么做,百度关键词排行榜在了解完Shader的基本结构之后#xff0c;我们再来看看编写着色器的语言。
Shader编写语言有CG#xff0c;HLSL两种#xff0c;我们主要学习CG的写法。
数据类型
CG的基础变量类型
uint a12;//无符号32位整形
int b12;//32位整形float f1.2f;//32位浮点型
half h1.2h;//…在了解完Shader的基本结构之后我们再来看看编写着色器的语言。
Shader编写语言有CGHLSL两种我们主要学习CG的写法。
数据类型
CG的基础变量类型
uint a12;//无符号32位整形
int b12;//32位整形float f1.2f;//32位浮点型
half h1.2h;//16位浮点型
fixed fix1.2;//12位浮点型bool btrue;
string str123;纹理对象句柄理解为一个纹理就行
sampler sam;sampler1D 用于一维纹理通常用于对一维纹理进行采用如从左到右的渐变色
sampler2D 用于二维纹理最常见的纹理类型之一用于处理二维图像纹理比如贴图
sampler3D 用于三维纹理通常用于体积纹理如体积渲染
samplerCUBE 用于立方体纹理通常用于处理环境映射登需要立方体贴图的情况
samplerRECT 用于处理矩形纹理通常用于一些非标准的纹理映射需求他们都是用来处理纹理Texture数据的数据类型
注意区别在意纹理的类型和维度
可以看到基本上和C#差不多除此之外多了纹理对象句柄的类型。
CG的复合变量类型
复合类型也和C#差不多数组结构体
基础复合数据类型
数组和C#差不多
int c[4]{1,2,3,4};
// a.length;int d[2][3]{{1,2,3},{4,5,6}};
//d.length 行
//d[0].length 列//结构体
//没有访问修饰
//申明结束加分号
//一般在函数外部申明
注意结构体的写法 CG的特殊变量类型
学了这么多知识点其中矩阵和向量占了很大一部分同样CG中也为我们提供了矩阵的变量以及向量相关的变量。
这些变量的类型都是基于基本数据类型的无非就是在基本数据类型的后面加一些数字之类的
//向量CG语言内置的数据类型
//内置的向量类型是基于基础数据类型申明的最大不超过4维可以是任意数值类型
//数据类型n数据类型(a1,...,an);fixed2 f2fixed2(1.3,1.5);
fixed3 f3fixed3(2,3,4);//矩阵行列不大于4不小于1
//数据类型 nxm{n1m1,n1m2...}
int2x3 mytest{1,2,3,3,4,6};
int4x4 test1{1,2,3,4,5,6,7,8,4,5,6,7,1,2,2,3};
其他类型的向量和矩阵我就不举例了类似一下大差不差。
了解了这些之后我们再来看看一些类型的特殊用法
Bool的特殊用法
之前我们提到特殊变量类型是基于基本类型的所以bool类型同样能够用在特殊类型中
//bool类型同样可以用于向量的申明
//它可以用于储存一些逻辑判断结果
//比如
//float3 fafloat3(0.5,0.0,1.0);
//float3 fbfloat3(0.6,-0.1,0.9;
//bool3 bcab;
//结果为 boool3(true,false,false)
学习了数据类型之后我们思考矩阵和向量使用如此的频繁那我我们怎么去获取这些变量中的分量值呢这就需要Swizzle操作符
Swizzle操作符
Swizzle使用点号.来表示使用就和我们去使用类的成员一样。
但是Swizzle操作符的作用远不止这一点我们来看看
//如向量.xyzw,向量.rgba来获取其中的值
//使用1。用来提取分量2.用来重新排列分量 3.创建新的分量1.用来提取分量
fixed4 f4fixed4(1,2,3,4);
fixed ff4.w;
ff4.r;2.用来重新排列分量
f4f4.wyzx;
f4f4.gbar;3.创建新的分量
//fixed3 f3f4.xyz;
//fixed2 f2f4.rg;
fixed4 f4_1fixed4(f2,1,2);//低维创建高维补充元素即可
我们发现矩阵中的数据其实就是基本数据类型那我们能不能用向量来表示呢
向量和矩阵的特殊用法
其实向量和矩阵是可以相互使用的就像这样
//向量和矩阵的更多用法
//1.利用向量声明矩阵
fixed4x4 f44{fixed4(1,2,3,4),fixed4(2,3,4,5),fixed4(4,5,6,7),fixed4(5,6,7,8)};
//2.获取矩阵中的元素
ff44[0][0];//一行一列
//3.利用向量获取矩阵的某一行
f4_1f44[0];
//4.高维转低维
fixed3x3 f33f44;//自动取值
fixed3 f5f;
注意的是如果使用低维转高维需要将欠缺的维度补齐 那么我们再来了解了解运算表达式吧
语法相关
基本运算和流程控制 比较运算符和C#一样的条件运算符三元运算符用法和C#一样逻辑运算符和C#一样,不过CG中不存在“短路”短路在比较的过程中如果一边满足则不会继续比较属性运算符和C#一样不过%取余只能整数取余流程控制(和C#一样)条件分支if,switch循环(for,while,do while)注意虽然用法和C#一样但是在使用的时候更多考虑性能的消耗1.尽量少的使用循环必要情况可以减少次数和复杂度2.可以利用GPU并行性来代替循环3.尽量避免复杂的条件分支
这一部分和C#没什么区别唯一需要注意的是逻辑运算符短路的问题。
函数相关
这一部分也和C#一样我就不多说了 函数相关函数的申明和用法几乎和C#中一模一样无返回值结构void name(in 参数类型 参数名out 参数类型 参数名){函数体}name:函数名CG中一般小写in表示输入参数外部传递过来的值内部不会做更改只会用来计算允许有多个out表示输出参数由内部向外传递函数内部必须进行初始化或者修改允许有多个in,out可以不写这样就可以避免in,out的特性不过为了可读性和可维护性建议写上void test_01(in fixed inf,out fixed outf){outfinf10;}
至此CG的基本内容就结束了接下来我们看看CG的编写
CG编写
在此之前我们先来看看CG的结构 顶点片元着色器 表面光照着色器 可以看到顶点片元着色器的结构和表面光照着色器的结构是不同的不过他们都是使用CG代码段的方式来编写所以我们在编写CG代码时同样要将代码放在CGPROGRAM和ENDCG之间。
在CG中最重要的就是顶点回调函数以及片元回调函数了这也是渲染代码存放的位置
顶点/片元函数 //顶点着色器回调函数//编译指令#pragma vertex myVert//处理顶点相关#pragma fragment myFra//处理颜色相关//POSITION,SV_POSITION,语义用来表面参数的含义//POSITION把模型的顶点坐标填充到输入的参数v中//SV_POSITION输出的内容是裁剪空间中的顶点坐标float4 myVert(float4 v:POSITION):SV_POSITION{//mul是CG提供的内部函数矩阵和向量的乘法//UNITY_MATRIX_MVP代表一个变换矩阵是UNITY的内置模型观察投影矩阵的集合//return mul(UNITY_MATRIX_MVP,v);return UnityObjectToClipPos(v*2);//和上一个等价新的写法}//片源着色器回调函数//SV_Target告诉着色器把输出的颜色存储到一个渲染目标中这里输出到默认的帧缓存中fixed4 myFra():SV_Target{return fixed4(1,0,0,1);}
可以看到最主要的部分就是申明编译指令 这个步骤决定了函数的名字以及调用。除此之外我们可以看到在函数的后面或者参数中还有一些代码这一部分叫语义它定义了参数的含义就像POSITION把模型的顶点坐标填充到输入的参数v中这部分后面再说。 那么如何在函数中使用我们定义的变量呢
非常简单只需要申明一个同名变量即可不过需要注意类型的对应
函数中使用自定义的变量 ShaderLab的属性和CG变量类型的对应ShaderLab CG类型Color,Vector float4,half4,fixed4Range,Float,Int float,half,fixed2D sampler2DCube samplerCube3D sampler3D2DArray sampler2DArray使用是在CG中声明对应类型的同名变量即可
语义
在上面我们基本了解了语义的基本用法。我们再来看看。
语义修饰输入和输出参数让shader知道从哪里读取数据并且把数据输出到哪里
语义是什么不重要重要的是我们需要了解的语义有哪些 应用阶段--顶点着色器 常用语义应用阶段--顶点着色器一般在顶点着色器回调函数的传入中使用POSITION:模型空间的顶点位置通常为float4类型NORMAL:顶点法线通常为float3类型TANGENT:顶点切线通常为float4类型TEXCOORDn:例如TEXCOOORD0,TEXCOORD1....该顶点的纹理坐标通常为float2或者float4类型n 表示第n1组纹理坐标TEXCOOORD0 第一组纹理坐标纹理坐标UV坐标表示这个顶点在对于纹理图像上的位置COLOR:顶点颜色通常为fixed4或者float4类型 顶点着色器--片元着色器 顶点着色器--片元着色器一般在顶点着色器的返回值中使用SV_POSITION:必须裁剪空间中的顶点坐标COLOR0:通常用来输出第一组的顶点颜色COLOR1通常用来输出第二组颜色TEXCOORD0--TEXCOORD7通常用于输出纹理坐标
片元着色器输出 片元着色器输出一般在片元着色器的返回值中使用SV_Target:输出的值会存档渲染目标中如果顶点着色器和片元着色器需要更多的参数可以通过定义结构体的方式对参数进行封装传递
东西非常多可以再使用中慢慢熟悉
我们想一下这么多东西那么再我们使用的时候必然会相当的麻烦所以CG也内置了很多的函数我们来看看
CG内置函数
数学相关 //1.三角函数相关sincos(floatx,out s,out c) 同时计算x的sin和cos值并返回sin(x) 正弦函数cos(x) 余弦函数tan(x) 正切函数sinh(x) 双曲正弦函数cosh(x) 双曲余弦函数tanh(x) 双曲正切函数asin(x) 反正弦函数输入参数[-1,1],返回[-pai/2,pai/2]区间的角度值acos(x) 反余弦函数输入参数[-1,1],返回[0,pai]区间的角度值atan(x) 反正切函数输入参数[-1,1],返回[-pai/2,pai/2]区间的角度值atan2(x) 计算y/x的反正切值和atan功能一样只是输入参数不同 atan(x)atan2(x,1) //2.向量矩阵相关cross(A,B) 叉乘传入必须为三维向量dot(A,B) 点乘三维向量mul(M,N) 计算两个矩阵相乘 mul(M,V) 计算矩阵和向量的相乘mul(v,m) 计算向量和矩阵的相乘transpose(M) M为矩阵计算M的转置矩阵determinant(m) 计算矩阵的行列式因子 //3.数值相关abs(x)ceil(x) 向上取整floor(x) 向下取整clamp(x,a,b)等等//4.其他lit(NdotL,NdotH,m) N表示法向量L表示入射光向量H表示半角向量m表示高光系数这个函数计算环境光散射光镜面光的 贡献返回4维向量x表示环境光贡献y表示散射光贡献z表示镜面光贡献w始终为1noise(x) 噪声函数返回值始终在0-1之间对于相同的输入始终返回相同值不是真正的随机噪声 几何相关 //几何相关length(v) 向量模长normalize(v) 归一化向量 distance(p1,p2) 两个点的距离reflect(I,N) 计算反射光的方向向量I为入射光N为顶点法向量。I是指向顶点的I和N必须归一化的三维向量refract(I,N,eta) 计算折射向量I为入射N为顶点法向量eta为折射系数。I是指向顶点的I和N必须归一化的三维向量
纹理相关 //纹理相关返回值均为fixed4类型的颜色值1.二维纹理tex2D(sampler2D tex,flota2 s) 二维纹理查询等等2.立方体纹理3.其他纹理
CG内置文件
CG内置文件unity中的常用内置1.UnityCG.cginc2.Lighting.cginc3.UnityShaderVariables.cginc4.HLSLSupport.cginc等等
这些内置文件为我们提供了很多的方法需要使用时通过#include 的方式引用即可。
来看看这些文件中常用的东西吧
//常用内容方法UnityCG.cginc1.float3 WorldSpaceViewDir(float4 v)输入模型空间的顶点位置返回世界空间中从该点到摄像机的观察方向2.float3 ObjSpaceViewDir(float4 v)输入模型空间的顶点位置返回模型空间中该点到摄像机的观察方向3.float3 WorldSpaceLightDir(float4 v)仅用于向前渲染输入一个模型空间的顶点位置返回世界空间中从该店到光源的光照方向没有归一化4.float3 ObjSpaceLightDir(float4 v)仅用于向前渲染输入一个模型空间的顶点位置返回模型空间中从该店到光源的光照方向没有归一化5.float3 UnityObjectToWorldNormal(float3 norm)把法线方向从模型空间转到世界空间中6.float3 UnityObjectToWorldDir(float3 dir)把方向矢量从模型空间转到世界空间中7.float3 UnityWorldToObjectDir(float3 dir)把方向矢量从世界空间转到模型空间中结构体UnityCG.cginc1.appdata_base(顶点着色器输入)顶点位置顶点法线第一组纹理坐标2.appdata_tan(顶点着色器输入)顶点位置顶点法线顶点切线,第一组纹理坐标3.appdata_img(顶点着色器输入)顶点位置,第一组纹理坐标4.appdata_full(顶点着色器输入)顶点位置顶点法线顶点切线,四组或者更多纹理坐标5.appdata_img(顶点着色器输输出)裁剪空间中的位置纹理坐标等等变换宏矩阵等等
东西有很多我只举例部分感兴趣的可以到HSLS的官网查看这部分CG与HSLS差不多。 内部函数 - Win32 apps | Microsoft Learn 具体的用法会在之后的编写中用到这里留个印象即可。 那么到这里CG的基础就完结啦后面部分我们会学习到基本的光照模型到时候我们在通过使用的方式来认识他们。