CustomData dilemma

When writing my own shader which expects customdata, I’m met with a dilemma which I don’t know if Unity could provide a better solution. So here is an example which illustrates my issue:

struct appdata {
    half3 texcoord : TEXCOORD0;
    half4 color : COLOR;
};

v2f vert (appdata v) {
    v2f o;
    o.color = v.color * texcoord.z;
    return o;
}

“texcoord.z” is to receive custom1.x from particle system, the not so nice part of this is that x/y/z (except w) of any TEXCOORD is given the default value of zero, that means unless texcoord.z receives value from particle system custom1.x, “o.color” will become zero, rendering the shader unusable without particle system enabling customdata. Naturally the preferable default value would be 1 because the calculation is often multiplication. To fix that, I come up with a poor workaround which I really don’t like:

o.color = v.color * (texcoord.z + 1);

And then custom1.x in particle system will need to be subtracted by 1 for the expected result. The bigger problem is that using any other curve multiplier than 1 will be even trickier. Of course I could use only texcoord.w, but I have more than 1 component of CustomData needs to be fetched to the shader, the issue of default zero of texcoord.xyz will still linger.

My approach is to add a toggle parameter and use a shader keyword to enable or disable it.

[Toggle(USE_CUSTOM_DATA)] _UseCustomData (“Enable Wild & Crazy Stuff, Yo!”, Float) = 0

#pragma shader_feature _ USE_CUSTOM_DATA

o.color = v.color;
#if defined(USE_CUSTOM_DATA)
o.color *= v.texcoord.z;
#endif

If you want to be frugal with your keywords just reuse one from another shader you know won’t be needed for this one (like any of the plethora of shader feature keywords the Standard shader uses). Just be sure to include a comment on what it’s really doing so your future self isn’t confused.

3 Likes