I want to layer one texture over top of another on the same mesh, but map the textures to different UV maps.

The example for Detail Maps in the Surface Shader Examples looks almost identical to what I want, but it seems that it uses the same UV map as the albedo texture, multiplied by 2.

I will admit I am very new to ShaderLab, but I am willing to put the work in and research: I just haven't seemed to be able to find the right documentation for what I want to do, or at least I do not understand how to use it.

I have achieved this result in blender this way, though I understand obviously there isn't a 1:1 conversion here.

Graph in Blender

I also have it working with ShaderGraph, which is neat, but I need it to work using the internal Unity shader for the project I am working on, so unfortunately ShaderGraph is out.


My understanding is that I would declare the UV maps under the Input struct like

struct Input {
    float2 uv_MainTex : TEXCOORD0;
    float2 uv2_Detail : TEXCOORD1;

and then grab the textures from the Properties input by doing

sampler2D _MainTex;
sampler2D _Detail;

and then use the inputs similarly to the _MainTex call which is

fixed4 c = tex2d(_MainTex, IN.uv_Detail).rgb * _Color;

I have also seen this answer but it doesn't really seem to solve the problem for me, it still doesn't seem to access my second UV map.

I do know that there is some confusion with how UV maps are used in HLSL vs. in Unity. Generally speaking I'm not concerned about overwriting UVs with lightmaps or stuff like that, and if that is an issue I can just add dummy maps when I export from blender to put my custom UV map as the 4th index.

My question is: how do I make one image map use a certain UV Channel and a second image use a second UV channel? Currently my setup is basically just a standard Lit Shader that I added the properties for the detail map to.

Right now it is only displaying the _MainTex on UV0.

Code in full here.

  • \$\begingroup\$ What do you mean by test this? Switching these out seems to only rotate the entire UV map by 90d on the Y axis (unity coords) so I will try re-exporting from Blender to see if I did something boneheaded. \$\endgroup\$ – Rug Jun 2 '20 at 21:51

Reviewing the Surface Shader documentation:

Surface Shader input structure

The input structure Input generally has any texture coordinates needed by the shader. Texture coordinates must be named “uv” followed by texture name (or start it with “uv2” to use second texture coordinate set).


struct Input{
    float2 uv_MainTex : TEXCOORD0;
    float2 uv2_Detail : TEXCOORD1;
  • \$\begingroup\$ I'm not sure I understand: that is exactly what I have written.. \$\endgroup\$ – Rug Jun 2 '20 at 21:45
  • \$\begingroup\$ Look closely. One is uv_... and the other is uv2_... \$\endgroup\$ – DMGregory Jun 2 '20 at 21:50
  • \$\begingroup\$ Fair point! I do have that in my original question - oops! My pastebin link does have that change fixed, but it still seems that it isn't recognizing that UV Map. I am going to go back and ensure I haven't missed something on export. \$\endgroup\$ – Rug Jun 2 '20 at 21:57
  • \$\begingroup\$ "uv2" does not appear in your question text. Don't count on users clicking through external links - make sure all details required to understand your problem are present in your question itself. \$\endgroup\$ – DMGregory Jun 2 '20 at 21:58
  • \$\begingroup\$ Good idea - I will edit that. Is there any chance I am missing something else as that has not fixed my problem - it just doesn't seem to grab the second UV map no matter what. \$\endgroup\$ – Rug Jun 2 '20 at 22:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.