- Home /
Merging (alpha) Unlit shader with Cutout shader
Hi! I'm currently confused as to how I could modify an alpha cutout shader to ignore lighting. I've read that it's something to do with using the surface pragma which enables interaction with Unity's lighting effects, however adding fragment and vertex pragmas just breaks the program. I've been searching for hours and tried many different combinations but to no avail.
Basically, I am trying to merge this cutout effect (code below) with Unity's in-built Unlit/Transparent shader. This is for a circular healthbar displayed on an in-game computer screen and thus it needs to appear like it's lit-up (and not dark from lack of Unity lighting).
Below is the current shader I am using. Any help would be greatly appreciated!
Shader "Custom/AlphaCutout"
{
Properties
{
_Color ("Main Color", Color) = (1,1,1,1)
_MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
_CutTex ("Cutout (A)", 2D) = "white" {}
_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
}
SubShader
{
Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
LOD 200
CGPROGRAM
#pragma surface surf Lambert alpha
sampler2D _MainTex;
sampler2D _CutTex;
fixed4 _Color;
float _Cutoff;
struct Input
{
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o)
{
fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
float ca = tex2D(_CutTex, IN.uv_MainTex).a;
o.Albedo = c.rgb;
if (ca > _Cutoff)
o.Alpha = c.a;
else
o.Alpha = 0;
}
ENDCG
}
Fallback "Transparent/VertexLit"
}
Answer by zharik86 · Oct 31, 2014 at 07:02 AM
There are two ways without use of light. The first is to write HLSL a shader. (an example see below). The second - to add function of processing of light to "surface" shader. Your shader, most likely, is used in mobile devices. Therefore I will write HLSL with for this purpose:
Shader "Custom/CutoutMobHLSL" {
Properties {
_Color ("Main Color", Color) = (1,1,1,1)
_MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
_CutTex ("Cutout (A)", 2D) = "white" {}
_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
}
SubShader {
Tags { "Queue" = "Transparent" }
Pass {
ZWrite Off // don't write to depth buffer
Blend SrcAlpha OneMinusSrcAlpha // use alpha blending
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
uniform float4 _Color; // define shader property for shaders
uniform sampler2D _MainTex;
uniform sampler2D _CutTex;
uniform float _Cutoff;
struct vertexInput {
float4 vertex : POSITION;
float4 texcoord : TEXCOORD0;
};
struct vertexOutput {
float4 pos : SV_POSITION;
float4 tex : TEXCOORD0;
};
vertexOutput vert(vertexInput input) {
vertexOutput output;
output.tex = input.texcoord;
output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
return output;
}
float4 frag(vertexOutput input) : COLOR {
float2 tp = float2(input.tex.x, input.tex.y); //get textures coordinate
float4 col = tex2D(_MainTex, tp) * _Color; //load main texture
float newOpacity = tex2D(_CutTex, tp).a; //load cuttext
if(newOpacity < _Cutoff) {
newOpacity = 0.0;
}
return float4(col.r, col.g, col.b, newOpacity);
}
ENDCG
}
}
}
I hope that it will help you.
Thank you very much, zharik86! I did some playing around and modified the last few lines of the frag method and it works perfectly.
if (newOpacity < _Cutoff)
col.a = 0;
return float4(col.r, col.g, col.b, col.a);
The shader works exactly like originally but without Unity's lighting system affecting the texture, which is exactly what I was trying to achieve. Thanks again for your help!
thank you, Zharik86, your shader script helped me solve something that i had been trying to find out for about 4 months.
Thanks! One thing to tweak:
Add
if(col.a < newOpacity){
newOpacity = col.a;
}
within the frag function below
if(newOpacity < _Cutoff) {
newOpacity = 0.0;
}
So the original alpha won't get overwritten if the texture has some!
Answer by GainPlay · May 24, 2017 at 01:42 PM
Hi,
I've tried the shader "CutoutMobHLSL" that @zharik86 posted, i know its an old post but maybe someone can help.
As you see in the pictere 1&2) there is a object infront of the sides but at 3) you see the objects that are rendered behind the front object.
any suggestions?
with kind regards,
a shader scrub
Answer by Tudor · Jun 06, 2017 at 09:28 AM
@GainPlay That happens because everything drawn by this shader does not write to the depth buffer (and therefore is not Z sorted). This is done by this line: ZWrite Off // don't write to depth buffer
. Just comment it out.
PS: the unity login system is haywire on this answers platform. Even with 3rd party cookies disabled in chrome I can't log in, and can't post comments. It only logs me in when I click on Post Answer or Ask Question.