- Home /
Rewrite simple alphamask fixed function shader to surface or cg shader
Until now I've used this shader to dynamically make transparent holes in a texture.
Shader "AlphaMask" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_AlphaTex ("Alpha (A)", 2D) = "white" {}
}
SubShader {
Tags { "RenderType" = "Transparent" "Queue" = "Transparent"}
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
ColorMask RGB
Pass {
SetTexture[_MainTex] { Combine texture }
SetTexture[_AlphaTex] { Combine previous, texture }
}
}
}
_MainTex is a high-resolution texture that's read-only, while _alphaTex is a low-res texture that's frequently updated with SetPixels()/Apply().
After updating from my custom 2D-system where I used texture2D to the new Sprite-class, the SpriteRenderer won't accept this shader since it's fixed function.
I've spent time searching for a solution to this, but no luck so far. Surely there's some simple way to update this code for surface or cg?
Answer by OP_toss · Dec 07, 2013 at 12:06 AM
So I don't normally code things for people, on principle, but this seemed like the easiest way to explain it. And it's mostly copy pasted from unity docs. I just tweaked it to serve your purpose.
(I also didn't test it so I'll leave the bugs to you :) )
I made it a transparent shader by placing it in the right queue and setting the correct blend mode.
I added 2 textures as input.
I use the same uvs for both.
I read in main tex.
Then I read in alphatex and set the alpha based on my alphatex's alpha.
Shader "Tutorial/Textured Colored" { Properties { _Color ("Main Color", Color) = (1,1,1,0.5) _MainTex ("Texture", 2D) = "white" { } _AlphaTex ("Texture", 2D) = "white" { } } SubShader {
Tags { "RenderType"="Transparent" "Queue"="Transparent" } LOD 200 Blend SrcAlpha OneMinusSrcAlpha ZTest Less Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" float4 _Color; sampler2D _MainTex; sampler2D _AlphaTex; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; float4 _MainTex_ST; v2f vert (appdata_base v) { v2f o; o.pos = mul (UNITY_MATRIX_MVP, v.vertex); o.uv = TRANSFORM_TEX (v.texcoord, _MainTex); return o; } half4 frag (v2f i) : COLOR { half4 texcol = tex2D (_MainTex, i.uv); texcol.a = tex2D (_AlphaTex, i.uv).a; return texcol * _Color; } ENDCG } } Fallback "VertexLit" }
I tried it out, and with that code the transparency works, but the main texture is rendered with only one color. I'm sure it would work with some $$anonymous$$or modification (I'm a neophyte with shaders though). $$anonymous$$eanwhile, I found another way to make it work http://answers.unity3d.com/questions/272749/how-to-write-unlit-surface-shader.html. Thanks for taking the time to answer, it got the Tags and some other details sorted out.
So I actually ended up testing it and it definitely works for me... Did you leave the Color var set to white with full alpha??
I used the code as is. I assigned it to a new Foreground$$anonymous$$aterial in the editor. In the inspector the $$anonymous$$ain Color is (255,255,255,255), and textures were added. Still, where the main texture should be rendered, just the selected main color is rendered. If I comment this line out "texcol.a = tex2D (_AlphaTex, i.uv).a;" the main texture is rendered (but transparency of course disappears). Any idea what might be wrong?
Well yeah a number of possibilities:
Does your maintex texture have an alpha? If not, then it won't be transparent without using the alphatex.
Does your alphatex have an alpha? If not, then use a different channel.
Why did you comment out that line?
What exactly is going wrong?
Shoot me answers to those questions and I should be able to sort you out, if you haven't figured it out already.
Can you close this question by either answering it yourself or accepting my answer please? Hope I helped, thanks!
Answer by transporter_gate_studios · Mar 11, 2018 at 08:35 PM
This works for me except for one strange issue. The edges of the sprite are being "repeat stretched". Have no idea what could be doing this. I do have many sprites near each other.