- Home /
Transparent Solid Color Shader
Hi,
I know nothing of making shaders in Unity, and I'm trying to make a Solid Color shader which is transparent. I currently have the following, which works:
Properties
{
_Color ("Color", Color) = (1,1,1,.5)
}
SubShader
{
Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
LOD 100
ZWrite On
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
Lighting Off
Color [_Color]
}
}
The problem is though that you can see parts of the model itself that are behind it:
Anyone knows how to fix this? I need/want a solid color, without those bright spots.
Thanks for the help!
Answer by ScroodgeM · Jul 27, 2012 at 09:30 PM
shader below is do what you want. but your platform should support GrabPass technology. this can be not supported by some mobile platforms.
i can propound 2 more ways without grabpass:
create a 2-pass shader that first draws only to alpha-channel and the second draws just color based on alpha value, this can be achieved by blending options
create a object mask using render-texture and put it to main camera on top. this way is same as previous but uses render texture instead of shader calculations and blending
anyway issue is not so simple. with a just default blending two surfaces will be drawn twice and it will look not same as single surface.
shader
Shader "Unity Answers/Solid Transparency Color" { Properties { _Color ("Color", Color) = (0.5, 0.5, 0.5, 0.5) } SubShader { Tags {"Queue" = "Transparent"} ZWrite Off GrabPass { } Pass { Fog { Mode Off } Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
fixed4 _Color;
sampler2D _GrabTexture;
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
float4 pos : SV_POSITION;
float4 uv : TEXCOORD0;
};
v2f vert (appdata v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = o.pos;
return o;
}
half4 frag(v2f i) : COLOR
{
float2 coord = 0.5 + 0.5 * i.uv.xy / i.uv.w;
fixed4 tex = tex2D(_GrabTexture, float2(coord.x, 1 - coord.y));
return fixed4(lerp(tex.rgb, _Color.rgb, _Color.a), 1);
}
ENDCG
}
}
}
Thanks! I get an error "No subshader can run on this graphics card" though. Any idea? I'm using Unity Indie, can this be a problem?
AFAI$$anonymous$$ shaders are not depends on Unity license. so this is a hardware limits. which hardware do you use? graphic adapter model? and try menu "edit -> graphic emulation" - does it affect shader? which modes? i think GrabPass{} can be not supported y some cards
I currently have a Nvidia 460gtx. I already tried changing the graphic emulation, though that didn't change anything (currently it's at none.) And what do you mean by "which modes" ? Btw, thanks a lot for helping.
that's very strange. shader model 2.0 support must be enough to run this shader. your card supports up to shader model 5.0. did you edit this shader? try to use it as is. also, try to switch to fantastic mode in quality settings. if it still doesn't work, try to remove 'GrabPass {}' line. shader will not work properly then, but should draw an object (without transparency). it should help to detect what's wrong in shader. write response here.
Ok I tried all what you said. Changing the quality settings doesn't do anything. Removing the GrabPass removes the error, though as you said it's not transparant.
Answer by Pawl · May 04, 2016 at 12:57 AM
This is an old question, but I implemented the two pass shader (with texturing) suggested by @ScroodgeM and it works great. This was tested on Unity 4 and the vertex/fragment shaders were based on the samples from the Unity docs here.
The secret ShaderLab sauce is ColorMask and Blend, as seen on the stoned dino below. Enjoy! =)
Shader "Custom/FlatTransparent" {
Properties {
_Color("Main Color", Color) = (1,1,1,1)
_MainTex("Base (RGB) Trans (A)", 2D) = "white" {}
}
SubShader {
Tags{ "Queue" = "Transparent" "IgnoreProjector" = "False" "RenderType" = "Transparent" }
/////////////////////////////////////////////////////////
/// First Pass
/////////////////////////////////////////////////////////
Pass {
// Only render alpha channel
ColorMask A
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
fixed4 _Color;
float4 vert(float4 vertex : POSITION) : SV_POSITION {
return mul(UNITY_MATRIX_MVP, vertex);
}
fixed4 frag() : SV_Target {
return _Color;
}
ENDCG
}
/////////////////////////////////////////////////////////
/// Second Pass
/////////////////////////////////////////////////////////
Pass {
// Now render color channel
ColorMask RGB
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
sampler2D _MainTex;
fixed4 _Color;
struct appdata {
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f {
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
v2f vert(appdata v) {
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.uv;
return o;
}
fixed4 frag(v2f i) : SV_Target{
fixed4 col = _Color * tex2D(_MainTex, i.uv);
return col;
}
ENDCG
}
}
Fallback "Diffuse"
}
Quick heads up to future readers: This method works well with a single mesh, but doesn't work with a model that's made up of multiple meshes.
still a pretty amazing result. 2020 and still works!
I also found another solution posted here: http://wiki.unity3d.com/index.php?title=AlphaVertexLitZ. Is there any advantages to using @Scroodge$$anonymous$$'s approach compared to first rendering only into the depth buffer? Is this basically the same thing? Is one faster than the other?
Your answer
Follow this Question
Related Questions
About shader! 0 Answers
Shader: Masked Tint with Transparency 0 Answers
Shader Warning Problem 0 Answers
Transparent shaders render as fullbright 0 Answers