Shader global values not acting globally

I created my first vertex shader recently, based on the standard mobile diffuse shader. It has parameters that allow the scene to be curved into the distance and are set up as uniform variables. It all seems to work really well but I get some odd objects that just seem to refuse to deform even though they have the right shader. Also they sometime flicker between the correctly warped position and their original position.

I use Shader.SetGlobalFloat(“curveScale”, value); to set the global value and so I would expect all objects with this shader would warp. Here’s the shader in case its related to it:

Shader "Custom/Diffuse Coloured - Curved" {
    Properties {
        _MainTex ("Base (RGB)", 2D) = "white" {}
        _Color ("Color", Color) = (1.0, 1.0, 1.0, 1.0)
    }
 
SubShader {
    Tags { "RenderType"="Opaque" }
    LOD 150
 
CGPROGRAM
#pragma surface surf Lambert vertex:vert
 
sampler2D _MainTex;
    uniform float4 _Color;
    uniform half curveStart;
    uniform half curveRate;
    uniform half curveScale;
 
struct Input {
    float2 uv_MainTex;
};
 
half4 Bend(half4 v)
{
    half depth = v.z-curveStart;
 
    if (depth<0)
    {
        return v;    // Unchanged
    }
 
    half4 val = v;
    val.x = val.x + ( (1 - cos(depth*curveRate)) * curveScale);
 
    return val;
}
 
 
void vert (inout appdata_full v)
{
    half4 vPos = Bend(v.vertex);
 
    v.vertex = vPos;
}
 
void surf (Input IN, inout SurfaceOutput o) {
    fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
    o.Albedo = c.rgb * _Color;
    o.Alpha = c.a;
}
ENDCG
}
 
Fallback "Mobile/VertexLit"
}

In trying to track down the cause I set up a testbed which creates cubes from a prefab and then setting their color either by setting the sharedMaterial or material. When they are set by material the warping stops working. Now I know it would duplicate the material at this point but the setting of a global float should still apply to all uses of that shader, shouldn’t it?

73077-testdeformshader.png
Here the mixed coloured cubes are fixed but the common shared ones bend. All use the same shader and global values. As someone new to shaders I fear I’m missing something important!

1 Answer

1

In your shader, try adding this to your tags:

"DisableBatching" = "True"

For example, this would give you:

Tags { "RenderType"="Opaque" "DisableBatching" = "True" }

I’m guessing that your cubes are dynamically batching which, in this case, is causing their origin point to move to global (0, 0, 0). Under most circumstances, the batching is a good thing. It can drastically reduce draw calls in your scene. However, it doesn’t often play well with vertex modification in shaders.

Edit: At the very least, if you see a change as a result of this, then it may be a potential lead. The more I think about the problem, the less logical and straightforward the problem seems to be.