- Home /
Shader with two textures separated by an alpha channel?
I have a bunch of wall assets which look like this (quick screenshot, the full texture tiles):
I am trying to make the red parts animate and move horizontally, whereas the gray foreground parts stay static. Currently this is my solution:
Use two planes with separate textures, one 0.001 units behind the other.
For the foreground, use a cutout alpha shader to mask out the parts that should be red/animated.
For the background, use a separate texture with a script that changes the X offset and time it so that it tiles.
While this works, it's clumsy to use two planes for each wall section, it makes it harder to snap to a grid since it often snaps to the element with an offset, and it uses more draw calls through separate materials.
Is there a way to make a shader which has these properties?
Use a diffuse map which is masked by its alpha channel.
Use a second diffuse map which uses no alpha and always renders below the first one.
Have the second diffuse map be targetable with a script so its offset can be animated separately.
This way I could do it all in a single plane with no (or minimal) extra draw calls and it'd all work much more elegantly. I'm not very knowledgeable on shaders and any material on this kind of approach I found online was either incomplete or obsolete at this point. This is a mobile-targeted game so optimally there'd only be a diffuse map and it'd be lit with a lightmap.
Yes. With the standard shader, you can use the Secondary$$anonymous$$aps area. Sliding offset2 will animate the red parts of yours. In a custom shader, generally you make/animate both textures and end with: finCol=lerp(col2,col1,col1.a);
Answer by toddisarockstar · May 14, 2017 at 10:59 PM
is this what you need ?
Shader "2 layers transparent" {
Properties {
// _Color ("Overall Color", Color) = (1,0.5,0.5,1)
_t1 ("texture in white", 2D) = "white" {}
_tint1 ("Tint1", Color) = (1.0, 0.6, 0.6, 1.0)
_t2 ("texture in red", 2D) = "white" {}
_tint2 ("Tint2", Color) = (1.0, 0.6, 0.6, 1.0)
_t3 ("use for alpha channel", 2D) = "white" {}
_rc ("low cutoff", Range(1,80)) = 1.0
}
SubShader {
//Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Lambert
float _rc;
sampler2D _t1;
sampler2D _t2;
sampler2D _t3;
fixed4 _tint1;
fixed4 _tint2;
struct Input {
float2 uv_t1;
float2 uv_t2;
float2 uv_t3;
};
void surf (Input IN, inout SurfaceOutput o) {
float f;
half4 pix = tex2D (_t1, IN.uv_t1)*_tint1;
half4 pix2 = tex2D (_t2, IN.uv_t2)*_tint2;
f=tex2D (_t3, IN.uv_t3).a;
f=f*_rc;
if(f>1){f=1;}
f=1-f;
pix=pix*f;
f=1-f;
pix=pix+pix2*f;
o.Albedo = pix.rgb;
}
ENDCG
}
FallBack "Diffuse"
}
Thanks! This seems to work well in displaying the texture properly, though I'm having some problems making the animation - I've named the texture to be animated "Background" in the shader, and got a script with this code:
void Update () {
meshRenderer.material.SetTextureOffset("Background", meshRenderer.material.GetTextureOffset("Background") + new Vector2((0.01f * Time.deltaTime), 0f));
if (meshRenderer.material.GetTextureOffset("Background").x >= offsetAmount)
meshRenderer.material.SetTextureOffset("Background", defaultPos);
}
When running the game I got a "$$anonymous$$aterial doesn't have a texture property 'Background'" error - any thoughts on this?
//animate like this
float newoff;
newoff = newoff + Time.deltaTime;
if(newoff>1){newoff=0;}
gameObject.renderer.material.SetTextureOffset("_t2",new Vector2(newoff,0f));
when you are looking up a texture in a shader, you have to reference the variable in the shader script that is holding the texture......not the name of the actual asset. if you look near the top of the script, i named the variable holding the second texture as "_t2". It doesn't matter the name of the texture you drag into it.
also i was just re reading your question. i wrote this so that it would make it look like blood running through tubes. did you want to have the position of the red tubes to move? i could give you another shorter script for that if that's all you what wanted to do. otherwise you would move the offset of both "_t2" and "_t3".
actually with this script you could both move the position of the tubes with "_t3" and if you moved "_t2" a bit faster you would get an effect of stuff moving through the tubes at the same time!!!
Replacing "Background" with the correct variable worked well, thanks!
Indeed all I need to do is animate the red part, and keep the alpha and foreground still- your shader seems to do the job fine so far, thank you for the assistance :)
Your answer
Follow this Question
Related Questions
Soft edge shader - Issues when objects using same material overlap 0 Answers
(c#) Transparency Problem - Toggle not Gradient 1 Answer
Shader: separate alpha texture, independent offset 1 Answer
Boat wake/foam 0 Answers
How can i get mixed texture from one shader and set it for another object with another shader? 0 Answers