最近论坛看到有人提出这样的问题:
Shader "Unlit/testinout"
{
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);
if(pos.x<0){
col=float4(1,0,0,1);
}
else
{
col=float4(0,1,0,1);
}
}
void frag(inout float4 col:COLOR) //输出的并不是col的颜色?????
{
}
ENDCG
}
}
}
这个问题其实是语义绑定的规则,上面的片段着色器其实输出的是pos这个变量,并不是col。
注意:语义绑定是顶点和片段之间的桥梁,是一对一的关系,是根据类型进行匹配的,不是根据名称去匹配的。
正确的写法有如下几种
方法一:增加输入参数
Shader "a958832776/testinout"
{
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);
if(pos.x<0){
col=float4(1,0,0,1);
}
else
{
col=float4(0,1,0,1);
}
}
void frag(in float4 pos:POSITION,inout float4 co:COLOR) //注意需要带上顶点输出的POSITION语义
{
}
ENDCG
}
}
}
方法二:直接返回值
Shader "a958832776/testinout"
{
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
//直接返回颜色
float4 vert(in float2 objPos:POSITION,out float4 pos:POSITION):COLOR
{
float4 col=float4(0,0,0,0);
pos=float4(objPos,0,1);
if(pos.x<0){
col=float4(1,0,0,1);
}
else
{
col=float4(0,1,0,1);
}
return col;
}
void frag(inout float4 co:COLOR)
{
}
ENDCG
}
}
}
方法三:定义结构体
Shader "a958832776/testinout"
{
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
struct out_data{
float4 pos:POSITION;
float4 col:COLOR;
};
out_data vert(float2 objPos:POSITION)
{
out_data data;
data.pos=float4(objPos,0,1);
if(data.pos.x<0){
data.col=float4(1,0,0,1);
}
else
{
data.col=float4(0,1,0,1);
}
return data;
}
float4 frag(out_data d):COLOR
{
return d.col;
}
ENDCG
}
}
}
推荐使用方法三,这样结构更清晰明了,也不会出错。