Surface Shader dont batch correctly. (solved)

Hey guys,

im trying to write a shader for gras, that takes his object local up vector to calculate the normals. I want this, so that every vertex is lit by the same color to have a smooth color transition between the ground and the gras. The problem is, that the gras (two planes crossing each other with a simple texture) dont batch. Everything is working fine when i have the Disablebatching set to true. But when i set it to false the lightning of the gras “jumps” when i move and rotate the ground. (Need the rotation, because the game is placed on a cube).

Im using Unity 5.3.4f1 and this is the shader:

Shader "Cubiverse/FX/Gras" {
  Properties {
  _MainTex ("Texture", 2D) = "white" {}
  }
  SubShader {
  Tags { "RenderType"="Opaque" "ForceNoShadowCasting"="True"}  // Shader works fine when using "DisableBatching" = "True"
     Cull Off

  CGPROGRAM
  #pragma surface surf Lambert vertex:vert
 
  struct Input {
  float2 uv_MainTex;
  };
   
  sampler2D _MainTex;

     void vert (inout appdata_full v) {
     // face the normal always to the top; all vertecies have the same "light direction"
  v.normal = float3(0.0,1.0,0.0);
  }
   
  void surf (Input IN, inout SurfaceOutput o) {
       float4 tex = tex2D (_MainTex, IN.uv_MainTex);
  o.Albedo = tex.rgb;
       clip(tex.a -0.1);
  }
  ENDCG
  }
  Fallback "Diffuse"
  }

Can somebody help me with this? When do unity batch and when not?

Documentation says: “Some shaders (mostly ones that do object-space vertex deformations) do not work when Draw Call Batching is used.”

Thanks for any help!

Julian

For posterity:

If you batch meshes the origin of the vertices change. For the new batched-mesh the origin will usually be positioned somewhere else as described here “that’s because batching transforms all geometry into world space, so “object space” is lost”. That means that absolute values used for deformations or manipulation of the vertices will usually result in unexpected behaviour.
If possible use relative values to manipulate the vertices.

I don’t know what is going wrong with this specific sample posted above as I don’t have enough time to look into it, but it will most likely be related.

This seems as though it might cause problems when the origin changes but I could not say how to fix it.

v.normal = float3(0.0,1.0,0.0);

1 Like

Hey BenSan,

thanks for the answer!

For my special case i could just modify the normals in the mesh itself in the 3d application. Than i could use the normal shader without changing the normals at all. I needed to long to figure this out :smile:

I found also a good article about this “problem”: Wypierpapier: Vertex Normal tutorial

Thanks again,

Julian