Writing a shader to replace/mask colors on a map image with textures?

Hey! I’m sorry about the super late reply, I’ve been a bit behind on some things.

Thanks a lot for taking the time to write such a detailed post! This is really helpful for trying to make sure they don’t overlap, but if you don’t mind me asking, I’m still not entirely sure how I can pass all my different textures into the one image. :stuck_out_tongue: I was able to use the custom shader that Unity creates automatically to get started, but I couldn’t seem to get it to work with my metallic and ambient maps, which is why I tried working off of the downloadable Standard shader here on the forums . This worked great, acting just like the normal Standard shader, so I went ahead and defined my properties for each of the textures and the colors they would apply to.

_MainTex("Original Texture", 2D) = "white" {}            // Most likely will be ignored, as other textures will layer over this and fully cover it.

_MaskTex("Mask Texture", 2D) = "white" {}            // Stores the main texture that is used as a reference for what region each texture masks to depending on the color.

_MaskColor1("Mask Color 1", Color) = (1,1,1,1)            // Stores the color of what to mask. Eyedropper in Inspector will set each of these colors.
_MaskReplace1("Replacement Texture", 2D) = "white" {}    // Stores the texture that will replace the mask color.

_MaskColor2("Mask Color 2", Color) = (1,1,1,1)
_MaskReplace2("Replacement Texture", 2D) = "white" {}

_MaskColor3("Mask Color 3", Color) = (1,1,1,1)
_MaskReplace3("Replacement Texture", 2D) = "white" {}

_MaskColor4("Mask Color 4", Color) = (1,1,1,1)
_MaskReplace4("Replacement Texture", 2D) = "white" {}

_MaskColor5("Mask Color 5", Color) = (1,1,1,1)
_MaskReplace5("Replacement Texture", 2D) = "white" {}

_MaskColor6("Mask Color 6", Color) = (1,1,1,1)
_MaskReplace6("Replacement Texture", 2D) = "white" {}

_MaskColor7("Mask Color 7", Color) = (1,1,1,1)
_MaskReplace7("Replacement Texture", 2D) = "white" {}

_MaskColor8("Mask Color 8", Color) = (1,1,1,1)
_MaskReplace8("Replacement Texture", 2D) = "white" {}

Filtering may very well be a significant issue, but my main problem is that I’m not sure how I would go about telling Unity to only display each texture over its correct corresponding color—I’m not really experienced in shader coding :P. I’ve seen this accomplished with one texture before, but not with more than one on different parts of a model. I assume that I would have to pass these textures into my _MaskTex through only the albedo property, but I’m not entirely sure where or how to do this part. I’m working in a deferred setup, so I know it has to fit somewhere in here within the custom shader (although it happens to reference the UnityStandardCore shader as well, so that may require editing):

// ------------------------------------------------------------------
        //  Deferred pass
        Pass
        {
            Name "DEFERRED"
            Tags { "LightMode" = "Deferred" }

            CGPROGRAM
            #pragma target 3.0
            #pragma exclude_renderers nomrt


            // -------------------------------------

            #pragma shader_feature _NORMALMAP
            #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
            #pragma shader_feature _EMISSION
            #pragma shader_feature _METALLICGLOSSMAP
            #pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
            #pragma shader_feature _ _SPECULARHIGHLIGHTS_OFF
            #pragma shader_feature ___ _DETAIL_MULX2
            #pragma shader_feature _PARALLAXMAP

            #pragma multi_compile_prepassfinal
            #pragma multi_compile_instancing
            // Uncomment the following line to enable dithering LOD crossfade. Note: there are more in the file to uncomment for other passes.
            //#pragma multi_compile _ LOD_FADE_CROSSFADE

            #pragma vertex vertDeferred
            #pragma fragment fragDeferred

            #include "UnityStandardCore.cginc"

            ENDCG
        }
// ------------------------------------------------------------------

I’m not sure if there’s a certain way to accomplish this, but I think this is giving me the most difficulty right now. Unfortunately, I think a shader is my only solution in this case, as I have six different character models and each has about 80 different pieces of clothing that can be swapped. As for the filtering, I could very well separate each of my color masks into layers, but right now I don’t believe any of my masking textures have overlap between their colors—this may or may not be helpful with Unity’s filtering, but the pixels are only solid colors for each different region.


(That picture actually blurs it a little, as it’s not blurry at all in the original file) I wish there was really an easier way of doing something like this. I have seen this done in modeling programs before, but only when the textures were not meant to be interchanged often. Still, thanks a lot for getting back so quickly earlier! Would you have an idea of how I could implement this?