UnityShader学习3 vertx and fragment Shader 和 CG语言入门
1.大部分知识都可以从以下代码知道
Shader "ShaderLearn/vf1" { SubShader{ pass{ CGPROGRAM // Upgrade NOTE: excluded shader from DX11; has structs without semantics (struct v2f members pos,uv) #pragma exclude_renderers d3d11 // Upgrade NOTE: excluded shader from OpenGL ES 2.0 because it uses non-square matrices #pragma exclude_renderers gles #pragma vertex vert #pragma fragment frag //类型别名 typedef float4 FL4; //宏定义 #define MACROFL float4(fl4.rgba); //结构体 struct v2f { float4 pos; float2 uv; } //#pragma target 2.0 //像“ : POSITION”、“: COLOR”这样的均是语意 void vert(in float2 objPos : POSITION, out float4 pos:POSITION, out float4 col : COLOR) { //这里的in的参数是由引擎输入的 pos = float4(objPos, 0, 1); //顶点程序也能对颜色做处理,输出给下面的片段程序 col col = pos; } void frag(inout float4 col : COLOR) { //这里的inout是指在顶点程序中 col是从顶点程序中输入的,同时也会从片段程序输出 //如果片段程序不做处理,那么最后会直接输出由顶点程序处理的颜色 fixed r = 1; fixed g = 0; fixed b = 0; fixed a = 1; col = fixed4(r, g, b, a); //float ==> float2 ==> float3 ==> float4 32位精度浮点 //half ==> half2 ==> half3 ==> half4 16位精度 ////fixed ==> fixed2 ==>fixed3 ==> fixed4 8位 颜色的输出用fixed已经足够了 //bool bl = true; //sampler bool bl = true; //col = bl? col:fixed4(0,1,0,1);// 如果bl为真,取col的值 如果为假,取fixe4... float2 fl2 = float2(1, 0); float3 fl3 = float3(1, 0, 1); float4 fl4 = float4 (1, 1, 0, 1); //swizzle float4 fl = float4 (fl2.xy, 0, 1); fl = float4 (fl2.yx, 0, 1); fl = float4(fl4); fl = float4(fl3.xyxx); //类型别名的使用 fl = FL4(fl4.rgba); //fl= float4 (fl4.raxy);错误 要么rgba 要么xyzw //宏使用 ,定义的时候有了“;”,所以这里就不要分号了 fl = MACROFL col = fl; //矩阵 float2x2 M2x2 = { 1,0,1,1 }; float2x4 M2x4 = { 1,0,1,1,0,1,0,1 }; //也可以用 {1,0,1,1},{0,1,0,1} 也可以用 {fL4,{0,1,0,1}} col = M2x4[0]; //数组 float arr[4] = { 1,0.5,0.5,1 }; col = float4(arr[0], arr[1], arr[2], arr[3]); //结构体使用 v2f o; o.pos = fl4; o.uv = fl2; } ENDCG } } /* SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; }; struct v2f { float4 vertex : SV_POSITION; fixed4 vertColor : COLOR0; }; v2f vert(appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.vertColor = fixed4(v.vertex.xy, 0.0, 1.0); return o; } fixed4 frag(v2f i) : SV_Target { return i.vertColor; } ENDCG } } */ }
2.CG语言的函数大致和c语言差不多,用之前要声明。以下代码为例:
//如果要调用A函数 void A(); void frag (inout float4 col : COLOR) { A(); } void A() { //函数实现 } //===========我是分割线=========== //或者再调用之前先实现函数 void A() { //函数实现 } void frag (inout float4 col : COLOR) { A(); }
3.由于CG语言不支持引用(或者说指针),所以在传参数的时候要么就设定函数有返回值,要么就把参数修饰符写成“out”。
4.CG语言同样也有数组,函数里带数组作为参数的时候要明确确定数组长度,比如参数为float类型的数组arr,那参数就写成“float arr[长度(用户自己定)]”。
5.我们也可以include相关文件来复用代码,比如:
“#include "文件路径/文件名.cginc"”,然后函数该怎么调还是怎么调,比如“文件名.cginc”里面有A()函数,我们直接“A();”这样调用。顺带一提,文件放在与unity官方的cginc同级目录,win和ios两个系统路径为:
a.Windows:“unity安装目录/Editor/Data/CGIncludes/”
b.IOS:“unity安装目录/Editor/Applications/Unity/Unity.app/Contents/CGIncludes/”
6.CG语言有很多内置数学函数,建议用内置的,虽然也能手写,但是nvidia是专门对函数做了优化的,比我们手写的高到不知道哪里去了,顺便贴上函数一览地址:https://blog.csdn.net/jingmengshenaaa/article/details/52809879
浙公网安备 33010602011771号