Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Trying to use uv2 without texture

Discussion in 'Shaders' started by Skolstvo, Feb 23, 2017.

  1. Skolstvo

    Skolstvo

    Joined:
    Dec 21, 2015
    Posts:
    107
    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
    Code (csharp):
    1.  
    2. [HideInInspector]_DummyTex("DummyTex UV2", 2D) = "white" {} //If I comment this out the shader doesn't compile 0.Albedo // Very silly
    3.  
    4.  
    5.            sampler2D _DummyTex;
    6.  
    7. struct Input
    8. {
    9.                float2 uv2_DummyTex;
    10. };
    11.  
    12. void surf(Input IN, inout SurfaceOutputStandard o)
    13. {
    14.                fixed3 custom = tex2D(_SomeOtherMap, IN.uv2_DummyTex);
    15.                o.Albedo = custom.g;
    16. }
    17.  
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,248
    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:
    Code (csharp):
    1. struct Input {
    2.   float2 uv_MainTex;
    3.   float2 uv2_MainTex;
    4. };
    Or using the TEXCOORD symatics explicitly
    Code (csharp):
    1. struct Input {
    2.   float2 uv_MainTex;
    3.   float2 secondUV : TEXCOORD1;
    4. };
    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:
    https://docs.unity3d.com/Manual/SL-SurfaceShaderExamples.html

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

    Skolstvo

    Joined:
    Dec 21, 2015
    Posts:
    107
    @bgolus

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