here’s the code:
Shader "Debug/VertexColor"
{
Properties
{
_MainTex ("Texture", 2D) = "white" { } // SpriteRenderer needs this
}
SubShader
{
Tags
{
"Queue" = "Transparent"
"RenderType" = "Transparent"
"RenderPipeline" = "UniversalPipeline"
}
Cull Off
ZWrite Off
ZTest Always
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
Tags { "LightMode" = "Universal2D" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct Attributes
{
float3 position : POSITION;
float4 color : COLOR;
};
struct v2f
{
float4 position : SV_POSITION;
float4 color : COLOR;
};
v2f vert(Attributes v)
{
v2f o;
o.position = UnityObjectToClipPos(v.position);
o.color = v.color;
return o;
}
float4 frag(v2f i) : SV_Target
{
return i.color;
}
ENDCG
}
}
}
I’m using SpriteRenderer to test the material, and the returned i.color is always white.
I created another shader by ShaderGraph, with a Vertex Color node inside, and it performed well.
I created my own mesh with mesh.SetColors, and render it using MeshRenderer, this shader then can display vertex color as well.
Why this shader fails to access vertex color from SpriteRenderer?
I think there’s something I’ve missed…
btw I’m using URP 2D.
The issue you’re facing occurs because SpriteRenderer in Unity doesn’t use per-vertex color attributes directly in the same way as a MeshRenderer. Instead, it handles color by applying a uniform tint color (_Color) across the entire sprite, and this tint is not stored in the vertex attributes (COLOR semantics).
Updated Shader
Shader "Debug/VertexColor"
{
Properties
{
_MainTex ("Texture", 2D) = "white" { }
_Color ("Color Tint", Color) = (1, 1, 1, 1) // SpriteRenderer color
}
SubShader
{
Tags
{
"Queue" = "Transparent"
"RenderType" = "Transparent"
"RenderPipeline" = "UniversalPipeline"
}
Cull Off
ZWrite Off
ZTest Always
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
Tags { "LightMode" = "Universal2D" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct Attributes
{
float3 position : POSITION;
float4 color : COLOR;
};
struct v2f
{
float4 position : SV_POSITION;
float4 color : COLOR;
};
UNITY_DECLARE_COLOR;
v2f vert(Attributes v)
{
v2f o;
o.position = UnityObjectToClipPos(v.position);
o.color = v.color * UNITY_ACCESS_COLOR; // Multiply by SpriteRenderer color
return o;
}
float4 frag(v2f i) : SV_Target
{
return i.color;
}
ENDCG
}
}
}
Hope this helps
wow, this is the first time I realize that Vertex Color is not only the color attribute from vertex input… Thanks a lot.
what, wait, this post Changing the Sprite Renderer's Color property has no effect in my Custom Shader is telling me that it access ‘color’ vertex input attribute…? I’m now confused because _Color looks not working somethimes, for example this shader doesn’t work in unity 6:
Shader "Custom/RectAlphaFade"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Color ("Color", Color) = (1,1,1,1)
_OpaqueMin ("Opaque Rect Min (World)", Vector) = (-10,-10,0)
_OpaqueMax ("Opaque Rect Max (World)", Vector) = (10,10,0)
_TransparentMin ("Transparent Rect Min (World)", Vector) = (-5,-5,0)
_TransparentMax ("Transparent Rect Max (World)", Vector) = (5,5,0)
}
SubShader
{
Tags { "RenderType"="Transparent" "Queue"="Transparent" }
LOD 100
Blend SrcAlpha OneMinusSrcAlpha, One OneMinusSrcAlpha
ZWrite Off
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
float4 pos : SV_POSITION;
float3 worldPos : TEXCOORD0;
};
fixed4 _Color;
float4 _OpaqueMin, _OpaqueMax;
float4 _TransparentMin, _TransparentMax;
v2f vert (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
return _Color;
}
ENDCG
}
}
}