今天在仿写一个显示模型顶点色的表面着色器时发生了问题,编译器报错如下
‘vert’: output parameter ‘o’ not completely initialized
Compiling Vertex program with DIRECTIONAL
Platform defines: UNITY_ENABLE_REFLECTION_BUFFERS UNITY_USE_DITHER_MASK_FOR_ALPHABLENDED_SHADOWS UNITY_PBS_USE_BRDF1 UNITY_SPECCUBE_BOX_PROJECTION UNITY_SPECCUBE_BLENDING UNITY_ENABLE_DETAIL_NORMALMAP SHADER_API_DESKTOP UNITY_LIGHT_PROBE_PROXY_VOLUME
查了下,发现是由于少了行代码导致的。
更详细的原因是由于着色器的渲染目标定义为Directx 11导致的。貌似现在Unity5.x默认就是Directx 11。
使用Directx 11渲染需要对顶点颜色的输出进行合理的初始化。
需要添加UNITY_INITIALIZE_OUTPUT(Input, name)来进行初始化。
下面是shader代码
Shader "SurfaceShader/VertColor"
{
Properties
{
_MainTint("Global Color Tint", Color) = (1, 1, 1, 1)
}
SubShader
{
Tags{
"RenderType" = "Opaque"}
LOD 200
CGPROGRAM
#pragma surface surf Lambert vertex:vert
float4 _MainTint;
struct Input
{
float2 uv_MainTex;
float4 vertColor;
};
void vert(inout appdata_full v, out Input o)
{
//对输出进行初始化
UNITY_INITIALIZE_OUTPUT(Input, o);
//采集顶点色
o.vertColor = v.color;
}
void surf(Input IN, inout SurfaceOutput o)
{
o.Albedo = IN.vertColor.rgb * _MainTint.rgb;
}
ENDCG
}
}
下图是Unity5.x的默认材质球的效果。
下面是同一个模型使用了顶点色着色器的效果。
最后是使用的材质球。
在照抄这段shader的过程中除了出现以上的初始化问题以外,还出现了另外一个问题。
#pragma surface surf Lambert vertex:vert
就是此段代码的vertex:vert
部分,由于习惯于c#的打一个字段就空格,所以一开始写成了vertex : vert
但是结果会提示警告,说此部分是无法识别的#pragma指令,并且会导致着色器运行不正常。
最后关于模型顶点色目前我所了解到的是可以通过Maya来进行设置,3dMax不知道行不行,使用了此种技术可以在一定程度上减少贴图的数量,将所需信息直接存储在模型顶点上。