Texture blending in PBR/Standard Shader

I’m trying to understand the art pipeline of the standard physically based shader in Unity 5.

I was first aiming for doing texture blending based on vertex coloring. Think of a stone texture that has some moss on parts of it where one stone texture and one moss texture can be reused between many models.

Blending using vertex coloring was however not available in the standard shader but I found that you can use the Detail Mask and the Detail Albedo x2. Nice, but multiplication between the two textures was not was I was looking for though so I took a look in the standard shader code to find out how it is actually implemented and what my options are. The code looked like this:

half3 Albedo(float4 texcoords)
{
half3 albedo = _Color.rgb * tex2D (_MainTex, texcoords.xy).rgb;
#if _DETAIL
#if (SHADER_TARGET < 30)
half mask = 1; // no detail mask on SM2.0
#else
half mask = DetailMask(texcoords.xy);
#endif
half3 detailAlbedo = tex2D (_DetailAlbedoMap, texcoords.zw).rgb;
#if _DETAIL_MULX2
albedo *= LerpWhiteTo (detailAlbedo * unity_ColorSpaceDouble.rgb, mask);
#elif _DETAIL_MUL
albedo *= LerpWhiteTo (detailAlbedo, mask);
#elif _DETAIL_ADD
albedo += detailAlbedo * mask;
#elif _DETAIL_LERP
albedo = lerp (albedo, detailAlbedo, mask);
#endif
#endif
return albedo;
}

There I found the _DETAIL_LERP mode. But continuing the search reveals that it is actually never used and the only code that is ever used is the _DETAIL_MULX2.

Question to Unity people:

  • Will DETAIL_LERP be a feature that is going to be enabled down the road when 5.0 ships?

Questions to others:

  • Is vertex painting and texture blending not used that commonly?

  • Is texture blending on models commonly used at all or is there another better approach to this?

Baking into multiple high resolution textures for each different model seems like a waste to me when you can use a much lower resolution detail blending texture instead.

texture blending is used very often in games… vertex color blending, blending with height maps, etc.

no idea why the standard shader doesn’t have any blending functionality. I guess standard shader can only do so much before it just gets too complicated, as far as the user experience goes, and the underlying code. Under the hood the standard shader has a lot of different variants. If there’s some way to support blending without making the user interface confusing then it would be great if the standard shader supported blending.

Ultimately, unity needs a build in material editor like UE4. Shader forge is great but unity needs a built-in solution.

For the time being, i think the latest version of shader forge now more or less supports unity 5 and uses the unity 5 PBR model. so you could try shader forge.

It does have the blending functions, as you can clearly see in the code. It’s easy to change, just clone the standard shader and moidfy line 76:

#pragma shader_feature ___ _DETAIL_MULX2

Change “_DETAIL_MULX2” to something else, such as _DETAIL_LERP to use the lerp instead.

I’m not sure why there isn’t a drop-down menu to toggle between, such a thing would be easy to implement but perhaps most people don’t need to use them, and if they do it’s easy to switch with a custom shader anyway. Perhaps MUL2X is the fastest option so enabling it by default makes the standard shader as optimised as possible. I looked at blending mode codes, and a similar function such as Overlay is much more computationally expensive, as it requires several conditional statements which kill performance on shaders, as GPUs aren’t optimised for branching statements like a CPU is

1 Like

While that’s already pretty interesting, I can’t really figure out either how to get vertex colors into the whole equation. Using a control map and vertex colors wouldn’t need any conditional statements, I think, and especially with a built-in vertex color painter it would be a very useful tool, i.e. for painting moss, dirt, snow etc.