- Home /
Shader alpha channel goes unused, whats wrong here?
Hey there,
I'm trying to create a shader that will dipslay only a part of the applied texture.
The material is applied to a plane. Currently the alpha channel is completely ignored, even if I change the _Color variable directly. Color will change but the transparency will not.
The shader has the desired effect if I use
half4 frag (v2f i) : COLOR
{
half4 c = tex2D(_MainTex, i.uv) * _Color;
if(i.uv.x > _Bounds[0] &&
i.uv.x < _Bounds[2] &&
i.uv.y > _Bounds[1] &&
i.uv.y < _Bounds[3]){
c.rgb = 1; //works
//c.a = 1 //will not work
}
else{
c.rgb = 0;
//c.a = 0; //will not work
}
return c;
}
_Bounds will contain the top left and bottom right corner of the piece of the texture that should be rendered. Like: (topLeftX, topLeftY, bottemRigthX, bottemRightY)
Full shader
Shader "Custom/Highlight" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Texture", 2D) = "white" { }
_Bounds ("Bounds", Vector) = (0,0,.5,.5)
}
SubShader {
Tags{"Queue"="Transparent"}
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
float4 _Bounds;
float4 _Color;
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 c = tex2D(_MainTex, i.uv) * _Color;
if(i.uv.x > _Bounds[0] &&
i.uv.x < _Bounds[2] &&
i.uv.y > _Bounds[1] &&
i.uv.y < _Bounds[3]){
c.a = 1;
}
else{
c.a = 0;
}
return c;
}
ENDCG
}
}
Fallback "VertexLit"
}
I could probably solve this by scaling the plane it is applied to but I would rather learn how to use shaders.
Thanks in advance!
P.S, if you know of a way to make it work with tiling as well I would love to know it.
Answer by Jessespike · Nov 11, 2012 at 08:38 AM
half4 frag (v2f i) : COLOR
{
half4 c = tex2D(_MainTex, i.uv) * _Color;
i.uv = i.uv - floor(i.uv); // Floor UV to stay in 0-1 range (For tiling)
if(i.uv.x > _Bounds[0] &&
i.uv.x < _Bounds[2] &&
i.uv.y > _Bounds[1] &&
i.uv.y < _Bounds[3]){
//c.a = 1;
//c.a = _Color.a; // Set to the Color's alpha only
c.a = c.a; // Consider both Color and Texture's alpha
}
else{
// c.a = 0;
discard; // Skip, don't bother drawing
}
return c;
}
You'll also want to add "Blend SrcAlpha OneMinusSrcAlpha" into the SubShader like this (For transparencies):
SubShader {
Tags{"Queue"="Transparent"}
Blend SrcAlpha OneMinusSrcAlpha
Pass { ...
Answer by Skaltum · Nov 11, 2012 at 02:56 PM
Jessepikes answer worked!
I also found this solution. Its all in the clip function, it will discard the pixel if the value is -1.
Shader "Custom/SurfHightlighting" {
Properties {
_MainTex ("Base (RGB) Trans(A)", 2D) = "white" {}
_Bounds ("Bounds", Vector) = (0,0,.5,.5)
_Color ("Color", Color) = (1,1,1,1)
}
SubShader {
Tags{"Queue"="Transparent"}
LOD 200
CGPROGRAM
#pragma surface surf Lambert
sampler2D _MainTex;
float4 _Bounds;
float4 _Color;
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex);
clip(( IN.uv_MainTex.x > _Bounds[0] &&
IN.uv_MainTex.x < _Bounds[2] &&
IN.uv_MainTex.y > _Bounds[1] &&
IN.uv_MainTex.y < _Bounds[3])? 1:-1);
o.Albedo = c.rgb * _Color.rgb;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
Your answer
Follow this Question
Related Questions
Shaders -- Tinting while respecting texture alpha 0 Answers
Shader Graph Increment vector1 1 Answer
Alpha Shader not working with obj collision 1 Answer
Shader / Texturing Model 1 Answer
Generic clipsafe fading ✿ 0 Answers