基于顶点和片面的shader和surface shader还是有很多区别的,其中最基本的是语法区别。surface shader可以理解为是包装好的基于顶点和片面的shader语句。学习基于顶点和片面的shader语句更能理解其中蕴含的逻辑原理。
1、首先看一个简单的点和片面的shader语句:
Shader "Example/vf" {
SubShader {
pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
void vert(in float2 objPos:POSITION,out float4 pos:POSITION,out float4 col:COLOR)
{
pos=float4(objPos,0,1);
col=pos;
}
void frag(inout float4 col:COLOR)
{
//col=float4(0,1,0,1);
}
ENDCG
}
}
}
2、在这个语句里,首先需要在subshader里建一个pass通道,然后在通道里定义cg模块,接着需要顶底顶点函数(#pragma vertex vert),片面函数(#pragma fragment frag),然后在顶点函数中输入相关的颜色信息void vert(in float2 objPos:POSITION,out float4 pos:POSITION,out float4 col:COLOR),在片段函数中输出颜色信息void frag(inout float4 col:COLOR)。
接着,来看一个变种,就是顶点函数既然是输出函数,那么我们直接用Return返回颜色,岂不是更直观,所以在这里修改一下顶点输出函数。那么直接看一下上述代码的修改版(float4 vert(in float2 objPos:POSITION,out float4 pos:POSITION):COLOR)。
Shader "Example/vf" {
SubShader {
pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
float4 vert(in float2 objPos:POSITION,out float4 pos:POSITION):COLOR
{
pos=float4(objPos,0,1);
return pos;
}
float4 frag(in float4 col:COLOR):color
{
//col=float4(0,1,0,1);
return col;
}
ENDCG
}
}
}
3、更进一步,上面发现顶点函数只是输出颜色信息,如果我们需要物体的位置信息,那就比较麻烦了,所以直接应用结构(struct)来解决多个数据传输的问题.这里在结构体里传递位置信息,颜色信息,看以下代码。
Shader "Example/vf" {
SubShader {
pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
struct v2f{
float4 pos:POSITION;
float2 objPos:TEXCOORD0;
float4 col:color;
} ;
v2f vert(in float2 objPos:POSITION)
{
v2f o;
o.pos=float4(objPos,0,1);
o.objPos=float2(1,0);
o.col=float4(0,1,0,1);
return o;
}
float4 frag(v2f IN):color
{
//col=float4(0,1,0,1);
//return float4(objPos,0,1);
return IN.col;
}
ENDCG
}
}
}
效果同上。