> Shader Vertex 的初步使用。
1 | Shader "Custom/vertexShader" { |
1 | struct appdata_full { |
这里还包含两个appdata_full的简化版,其实都一样 什么时候要用简化版?当然是越简化越省性能。
1
2
3
4
5
6
7
8
9
10
11
12 struct appdata_base {
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
};
struct appdata_tan {
float4 vertex : POSITION;
float4 tangent : TANGENT;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
};
2. SurfaceOutput 位于Lighting.cginc . 这可以说是最常见的一个结构体了但还是稍微写下吧。
1
2
3
4
5
6
7
8
9
10
11
12
13
14 struct SurfaceOutput {
//本身的颜色
fixed3 Albedo;
//法线贴图
fixed3 Normal;
//自发光
fixed3 Emission;
//反光
half Specular;
//光泽度
fixed Gloss;
//透明
fixed Alpha;
};
效果就是文章首页放的图了。下面的算法我就不解释了,毕竟这数学也不是靠别人能说清楚的。
1 | Shader "test/vertexAnimation" { |
在 #pragma 声明函数的时候,不要重名否则会报错。这是常识,引擎编译的时候会自动搜索所有编译期文件是否包含此函数。
in out inout 是cg语言提供的输入输出关键字,用来表示图形硬件上的不同寄存器。
引用《GPU 编程与CG 语言之阳春白雪下里巴人》的一段话来概括:
1
2
3
4
5
6
7
81. in: 修辞一个形参只是用于输入,进入函数体时被初始化,且该形参值 的改变不会影响实参值,这是典型的值传递方式。
2. out: 修辞一个形参只是用于输出的,进入函数体时并没有被初始化,这 种类型的形参一般是一个函数的运行结果;
3. inout: 修辞一个形参既用于输入也用于输出,这是典型的引用传递。 举例如下:
void myFunction(out float x); //形参 x,只是用于输出
void myFunction(inout float x); //形参 x,即用于输入时初始化,也用于输出数据
void myFunction(in float x); //形参 x,只是用于输入
void myFunction(float x); /等价与 in float x,这种用法和 C\C++完全一致 也可以使用 return 语句来代替 out 修辞符的使用。输入\输出修辞符通常和语
义词一起使用,表示顶点着色程序和片段着色程序的输入输出。
使用Lambert的vertex自定义函数的时候编辑器默认会报错,这个时候加入下面代码。这些代码可以看作是对Direcxtx11的hack。
1 | UNITY_INITIALIZE_OUTPUT(Input,o); |
如果直接使用_Time * Float 那么默认使用_Time.x
1 | float4 _Time : Time (t/20, t, t*2, t*3), use to animate things inside the shaders |