Trying to use uv2 without texture

Hi

I’m trying to make a custom tweak to the standard shader. For this I want to read a texture from the B channel of a texture but inputting it to the surface via uv2.

This works great if I place an empty texture, but I can’t seem to make a custom struct input of a uv2 texcoord without a texture. This is very ugly, if I remove the dummy texture the shader compiler ignores my custom uv2 float2.

I can use a [HideInInspector] to hide the dummy texture from the user but it is an ugly hack.

Pseudo code below

[HideInInspector]_DummyTex("DummyTex UV2", 2D) = "white" {} //If I comment this out the shader doesn't compile 0.Albedo // Very silly


           sampler2D _DummyTex;

struct Input
{
               float2 uv2_DummyTex;
};

void surf(Input IN, inout SurfaceOutputStandard o) 
{
               fixed3 custom = tex2D(_SomeOtherMap, IN.uv2_DummyTex);
               o.Albedo = custom.g;
}

Unity’s surface shaders try to be “smart” and strip data you’re not using, in this case too “smart” (ie: dumb) as you are using those UVs.

The other sane ways to try to do this would be adding uvs for _MainTex twice, like this:

struct Input {
  float2 uv_MainTex;
  float2 uv2_MainTex;
};

Or using the TEXCOORD symatics explicitly

struct Input {
  float2 uv_MainTex;
  float2 secondUV : TEXCOORD1;
};

But I believe both of those will fail as the surface shader will strip them out still, so you instead have to use “custom data computed per-vertex”. See:

Really it’s just a way to tell the surface shader, “No, really, I want this data, don’t 'f with it.”

2 Likes

@bgolus

Thank you very much. I overlooked that part due to my lack of understanding. This will come in handy in the future.