Inconsistent behavior with duplicated objects and vertex positions

I am experiencing inconsistent behavior when using vertex positions of duplicated objects with the same shader.

Here is a simple example shader which reproduces the problem :

Shader "_Vertex Z Test" {
  Properties {
    _MainTex ("Texture", 2D) = "white" {}
  }

  SubShader {
    Tags { "RenderType" = "Opaque" }    
    CGPROGRAM    
    #pragma surface surf Lambert vertex:vert
    
    struct Input {
        float2 uv_MainTex;
        float3 customColor;
    };
    
    void vert (inout appdata_full v, out Input o) {

        
      [B]  if( v.vertex.z > 0 ) o.customColor = float4(1,0,0,1);  [/B]
        
    }
    
    sampler2D _MainTex;    
    void surf (Input IN, inout SurfaceOutput o) {
        o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
        o.Albedo *= IN.customColor;
    }    
    ENDCG    
  } 
  
  Fallback "Diffuse"
}

Setting vertex colors based on their position produces inconsistent behavior when duplicated objects are created, and their world positions are differentiated.

Here’s a scene with duplicated cubes all with the above shader - which appears to show the vertex position is based on world position ( front cube at world 0,0,0 ):

When the 2 front cubes are deleted, the rear cube ( which hasn’t moved ) - has its coloring change - as though the vertex position is now relative to the cube’s space:

When the Camera is moved to some specific positions, the cubes coloring will also change:

Also, when the Camera’s direction is re-oriented from this position, the coloring will change again:

So, I’m wondering if this is the intended behavior for the ‘v.vertex’ position?

And/Also, what space is ‘v.vertex’ position in / relative to : model, world, projection, … ?

( I’m new to shader dev, so may be missing something fundamental… )

Thanks.

Model. You need to account for batching. Batched meshes’ space is the same as world space. Make perfect sense, now?

I see, thanks.

So it’s model by default - unless there is batching, where it actually becomes ‘Batched model space’ which is world space?

( Although I’m not certain how this explains the camera position / orientation inconsistencies - but they are possibly artifacts of the batching algorithm… )

Is there any way to ensure/transform to (individual) model space, even when batching is occurring?

Model space no longer means anything when you have batching. A bunch of meshes are now one mesh.

Yeah, batching definitely can seem random and unpredictable; you need to account for that if you’re going to use it.

Your screenshots work like this:
3 batched
No batch (1 mesh)
2 batched + 1 unbatched
same as previous, different combo

Thanks for the clarification, it didn’t occur to me that batching would effect the shader functionality.