Gradient Shader breaks on second instance

Hi guys,

I’m writing a gradient shader that lerps between 2 colors over time. It’s all fine until I introduce a second instance of an object having a material with this shader. It works as expected in the scene view, but in-game something really weird happens - only one color appears. Also, when moving one of the objects down on the Y axis the second color starts to show.

What am I missing here? Also, I’m pretty new to writing shaders, is there a better approach?

Here’s the shader itself:

Shader "Shaders/Gradient Shader"
{
  Properties
  {
    _Color1 ("Color 1", Color) = (1, 1, 1, 1)
    _Color2 ("Color 2", Color) = (0, 0, 0, 0)
  }
  SubShader
  { 
    Pass
    {
      CGPROGRAM
      #pragma vertex vert
      #pragma fragment frag
     
      #include "UnityCG.cginc"

      struct appdata
      {
        float4 vertex : POSITION;
      };

      struct v2f
      {
        float4 vertex : SV_POSITION;
        float wave : PSIZE0;
      };

      float4 _Color1;
      float4 _Color2;
     
      v2f vert (appdata v)
      {
        v2f o;
        o.vertex = UnityObjectToClipPos(v.vertex);
        o.wave = (v.vertex.y * (sin(_Time[3]) + 2)) * 2;

        return o;
      }
     
      fixed4 frag (v2f i) : SV_Target
      {
        float l = clamp(i.wave, 0 , 1);
        fixed4 col = lerp(_Color1, _Color2, l);
        return col;
      }
      ENDCG
    }
  }
}

Here’s how things look when I duplicate the cube object in the scene:

This is caused by dynamic batching. When a mesh is batched, either dynamically or statically, Unity combines multiple meshes together into a single larger mesh with the vertex locations positioned in works space. So when you just have one object v.vertex.y = 0 is centered on the object, but as soon as you add the second Unity is batching them and v.vertex.y = 0 is now at the center of the world.

The options are disable batching on the shader, or don’t use the vertex position and instead use a mesh with a custom additional UV channel.

You can also try using an instanced shader.

1 Like

Setting the DisableBatching tag to True worked great, thanks!