Blend one texture to another

Hi guys. I suck at shaders and I need help with one I’m modifying (the reflective bumped spec shader). Basically, I want to blend between two textures using a slider so that texture 2 becomes visible using the slider.

Here is what I have so far:

Shader "ShaderThing"
{
	Properties
	{
		_Color ("Main Color", Color) = (1,1,1,1)
		_SpecColor ("Specular Color", Color) = (0.5,0.5,0.5,1)
		_Shininess ("Shininess", Range (0.01, 1)) = 0.078125
		_ReflectColor ("Reflection Color", Color) = (1,1,1,0.5)
		_TexBlend ("Texture Blend", Range (0, 1)) = 0.0
		_MainTex ("Base (RGB) RefStrGloss (A)", 2D) = "white" {}
		_EnergyTex ("Energy (RGB)", 2D) = "white" {}
		_Cube ("Reflection Cubemap", Cube) = "" { TexGen CubeReflect }
		_BumpMap ("Bumpmap (RGB)", 2D) = "bump" {}
	}

	Category
	{
		Fog { Color [_AddFog] }
		
		SubShader
		{
			UsePass "Reflective/Bumped Unlit/BASE" 
			
			Pass
			{ 
				Name "BASE"
				Tags {"LightMode" = "Vertex"}
				Blend AppSrcAdd AppDstAdd
				
				Material
				{
					Diffuse [_Color]
					Shininess [_Shininess]
					Specular [_SpecColor]
				}
				
				Lighting On
				SeparateSpecular on
				
				SetTexture [_MainTex]
				{
					combine texture alpha * primary DOUBLE, texture * primary
				}
			}
			
			Pass
			{
				Name "Energy"
				Tags {"LightMode" = "Always"}
				Color [_PPLAmbient]
				Fog { Color (1, 1, 1) }
				Blend One One
				
				SetTexture [_EnergyTex]
				{
					constantColor (0,0,0,[_TexBlend])
					combine texture lerp (constant) previous
				}
			}
			
			UsePass "Bumped Specular/PPL"
		}
	}
	
	FallBack "Reflective/VertexLit", 1
}

Right now, this shader works perfectly for what I need, except that the energy texture’s grayscale is being taken into account. As a result the texture’s black parts are being made invisible (against texture 1) when all I want is for the entire texture 2 to be seen (no grayscale usage).

Have you tried the SrcAlpha modes for blending rather than AppSrcAdd? If I understand correctly, you want alpha blending here rather than additive.

Those didn’t work. At this point I’m just guessing as to what the correct combination of commands are to make the shader work the way I want.

Why is Shader programming so hard? All I want is to modify this Shader so that a slider fades texture two in. Just the texture, no light, no spec, no reflection or texture 1 showing up in the dark parts of texture 2.

This is the shader I’ve got so far, it’s very close to done but when you blend to texture 2 the dark parts are see through and react to reflection and such.

Shader "ShaderThing"
{
	Properties
	{
		_Color ("Main Color", Color) = (1,1,1,1)
		_SpecColor ("Specular Color", Color) = (0.5,0.5,0.5,1)
		_Shininess ("Shininess", Range (0.01, 1)) = 0.078125
		_ReflectColor ("Reflection Color", Color) = (1,1,1,0.5)
		_TexBlend ("Texture Blend", Range (0, 1)) = 0.0
		_MainTex ("Base (RGB) RefStrGloss (A)", 2D) = "white" {}
		_EnergyTex ("Energy (RGB)", 2D) = "white" {}
		_Cube ("Reflection Cubemap", Cube) = "" { TexGen CubeReflect }
		_BumpMap ("Bumpmap (RGB)", 2D) = "bump" {}
	}

	Category
	{
		Fog { Color [_AddFog] }
		
		SubShader
		{
			UsePass "Reflective/Bumped Unlit/BASE" 
			
			Pass
			{ 
				Name "BASE"
				Tags {"LightMode" = "Vertex"}
				Blend One One
				
				Material
				{
					Diffuse [_Color]
					Shininess [_Shininess]
					Specular [_SpecColor]
				}
				
				Lighting On
				SeparateSpecular on
				
				SetTexture [_MainTex]
				{
					combine texture * primary DOUBLE, texture * primary
				}
			}
			
			Pass
			{
				Name "Energy"
				Tags {"LightMode" = "Always"}
				Blend One One
				
				SetTexture [_EnergyTex]
				{
					constantColor (1,1,1,[_TexBlend])
					combine texture lerp (constant) previous
				}
			}
		}
	}
	
	FallBack "Reflective/VertexLit", 1
}

Can anyone help me? Because I seriously can’t do this.

I don’t have Unity on this machine, so this is untested. However, you should be able to accomplish what you want like this:

Shader "ShaderThing"
{
   Properties
   {
      _Color ("Main Color", Color) = (1,1,1,1)
      _SpecColor ("Specular Color", Color) = (0.5,0.5,0.5,1)
      _Shininess ("Shininess", Range (0.01, 1)) = 0.078125
      _ReflectColor ("Reflection Color", Color) = (1,1,1,0.5)
      _TexBlend ("Texture Blend", Range (0, 1)) = 0.0
      _MainTex ("Base (RGB) RefStrGloss (A)", 2D) = "white" {}
      _EnergyTex ("Energy (RGB)", 2D) = "white" {}
      _Cube ("Reflection Cubemap", Cube) = "" { TexGen CubeReflect }
      _BumpMap ("Bumpmap (RGB)", 2D) = "bump" {}
   }

   Category
   {
      Fog { Color [_AddFog] }
      
      SubShader
      {
         UsePass "Reflective/Bumped Unlit/BASE"
         
         Pass
         {
            Name "BASE"
            Tags {"LightMode" = "Vertex"}
            Blend One One
            
            Material
            {
               Diffuse [_Color]
               Shininess [_Shininess]
               Specular [_SpecColor]
            }
            
            Lighting On
            SeparateSpecular on
            
            SetTexture [_MainTex]
            {
               combine texture * primary DOUBLE, texture * primary
            }
            SetTexture [_EnergyTex]
            {
               constantColor (1,1,1,[_TexBlend])
               combine texture lerp (constant) previous
            }
         }
      }
   }
   
   FallBack "Reflective/VertexLit", 1
}

“previous” refers only to the previous SetTexture operation in the same Pass. Luckily, your first pass only used one texture operation, so lumping the second one in there shouldn’t hurt compatibility meaningfully. Only the oldest cards have less than two texture units.

Thanks Dan but it’s still not what I’m looking for. I tried that method earlier and it was the closest I got.

When I blend to texture 2, you can still see parts of the pass in the darker parts of texture 2 (the previous texture, bumpmap and reflection are present). What I want is to use the slider to blend in a texture and have it be solid and not show the contents of the reflection, texture 1 etc.

Thanks for the help so far! :slight_smile:

Ah, so you want to use the alpha slider as a cutoff value rather than a blending coefficient. In that case, you will need a second pass unless you write your own fragment shader. The second pass should use Blend One Zero and AlphaTest Greater [_TexBlend] to discard fragments with alpha values below your threshold. Your SetTexture command can be a simple as Combine texture.

Sorry Dan. The alpha test uses cutoff and I want texture 1 (with lighting, reflections etc) to “fade” into texture 2 (WITHOUT lighting, reflections etc) showing just the texture.

I think I need to provide some pictures of what I’m going for. They are attached at the bottom of this post and numbered accordingly. :slight_smile:

1). This is what I get when texture blend is at 0 and is perfect (shows texture 1).

2). This is what I want to have happen when texture blend reaches 1 (shows texture 2). As you can see, there are no lights or reflections acting on it.

3). This is what I get when texture blend reaches 1. The dark parts of texture 2 become see through and you can see parts of texture 1, lights and reflections. This is not what I want.

What I want is for the texture blend slider to fade from the solution in pic 1 to pic 2. How would you go about conquering this problem, Dan? I’ll be ever grateful. :slight_smile:

240336–8602–$pics_103.zip (213 KB)