- Home /
How to get Vertex Color in a cg shader?
I can't figure this one out...I need to read the vertex colors of the mesh and multiply it with the diffuse color (or use them as masks).
In ShaderLab this is done by adding the following lines: ColorMaterial AmbientAndDiffuse Lighting Off
I tried adding these to my cg shader but it doesn't return the vertex colors, so I'm sure I have to do it in the vertex shader but I don't know how.
Do i need to use a second pass for that? Thanks!
Answer by CHPedersen · Nov 28, 2011 at 02:40 PM
Vertex Colors behave a little weird in Unity's CG code. If you were using Cg from OpenGL, for example, it would be enough to just mark the input variable with the : COLOR semantic. That's supposed to tell the Cg compiler that you want it to store the vertex color in that variable. But in Unity, you don't have the same control over what data is passed to the shader, because that kind of stuff is wrapped inside the Mesh class. I was tearing out my hair over this for half a day a couple of months ago, until I read this site closely:
http://unity3d.com/support/documentation/Components/SL-VertexProgramInputs.html
Look at the text right above where it describes the 6 vertex attributes that you can pass. Notice that it says "If you want to access different vertex data, you have to declare vertex structure yourself. The structure members must be from the following list:"
As I said, it took me half a day to realize that when they write "must be", they mean business, and it really does mean MUST BE. So, to get the vertex colors, you HAVE to declare a struct for the input value, and the variable MUST be called "color". Here's an example Cg vertex program that correctly grabs the vertex colors in a way Unity accepts (it's just a vertex/pixel shader pass-through):
Shader "Custom/ExampleVertexColorShader" { Properties { } SubShader { Tags { "RenderType"="Opaque"} pass { CGPROGRAM #pragma vertex wfiVertCol #pragma fragment passThrough #include "UnityCG.cginc"
struct VertOut
{
float4 position : POSITION;
float4 color : COLOR;
};
struct VertIn
{
float4 vertex : POSITION;
float4 color : COLOR;
};
VertOut wfiVertCol(VertIn input, float3 normal : NORMAL)
{
VertOut output;
output.position = mul(UNITY_MATRIX_MVP,input.vertex);
output.color = input.color;
return output;
}
struct FragOut
{
float4 color : COLOR;
};
FragOut passThrough(float4 color : COLOR)
{
FragOut output;
output.color = color;
return output;
}
ENDCG
}
}
FallBack "Diffuse"
}
Again, Unity is really totally anal about this: The variable MUST be called "color", and it MUST be defined in a struct, or it won't store the vertex color in it.
Thanks for your answer Christian! It was very helpful. I actually figured it out last night and was able to get vertex colors to appear, but I didn't know that the "color" variable HAD to be defined in a struct...you saved me hours of scratching my head for future shaders lol
$$anonymous$$aybe you can help me out with another question I have about shaders, take a look here: http://answers.unity3d.com/questions/189574/shade4pointlights-and-shadevertexlights-custom-sha.html
Thanks again!
You're very welcome. :) Perhaps I might persuade you to mark the answer as accepted, then? I'll take a look at the other question in the meantime.
Crap sorry I completely forgot to mark it as accepted, it's done now :) Thanks again!
Hi Folks, how can i put a difuse texture on this shader? its possible ?