Transparency from Vertex colour value?

Hi there,
Sorry for posting a few times here recently but I thought I’d try to knock over a few shaders that I’ve been fighting with.
I’m trying to make a shader that has a basic unlit texture and transparency that is derived from the geometry’s vertex colour, e.g. white verts = solid, black verts = transparent.

This is what i have so far - feel free to laugh if you know anything about shader lab because it’s probably massively wrong.

Shader "Texture Vertex Mask" {
    Properties {
        _MainTex ("Base (RGB)", 2d) = "white"
    }
    Category {
       Lighting on
       ZWrite on
       Cull Back

       ColorMaterial AmbientAndDiffuse
       
       Blend SrcAlpha OneMinusSrcAlpha
       Tags {Queue=Transparent}
       SubShader {
            Pass {
            
               SetTexture [_MainTex] {
                  Combine primary
                }               
            }
        }
    }
}

I’ve searched the forums and tried dissecting shaders and I can get it to work.
any ideas?
thanks
Pete

Unfortunately, there’s no way to do what you mentioned in a fixed function shader, unless you use two passes. However, if you can use the alpha channel of the vert colors, instead of one of the other channels, you can do it like this (which isn’t too far off from what you came up with; good effort!):

SubShader {
	Tags {Queue=Transparent}
	Blend SrcAlpha OneMinusSrcAlpha
	BindChannels {
		Bind "vertex", vertex
		Bind "texCoord", texCoord
		Bind "color", color
	}
	Pass {
		SetTexture[_MainTex] {Combine texture, primary}
	}        
}

(There’s no point in a Category block because you only have one SubShader.)

Jessy was faster :stuck_out_tongue:

I just dragged this together in SSE…(need the practice!)
Since I don’t know how to exclude lighting in SSE, I hacked it in on line 48/49.
It has quite a few lines of obsoleteness in it, but it seems to work :stuck_out_tongue:

Shader "TextureVertexMask"
{
	Properties 
	{
_MainTex("Base (RGB) Gloss (A)", 2D) = "white" {}

	}
	
	SubShader 
	{
		Tags
		{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"

		}

		
Cull Back
ZWrite On
ZTest LEqual
ColorMask RGB
Blend SrcAlpha OneMinusSrcAlpha


		CGPROGRAM
#pragma surface surf BlinnPhongEditor  approxview halfasview vertex:vert
#pragma target 2.0


sampler2D _MainTex;

			struct EditorSurfaceOutput {
				half3 Albedo;
				half3 Normal;
				half3 Emission;
				half3 Gloss;
				half Specular;
				half Alpha;
				half4 Custom;
			};
			
			inline half4 LightingBlinnPhongEditor_PrePass (EditorSurfaceOutput s, half4 light)
			{
half3 spec = light.a * s.Gloss;
half4 c;
//c.rgb = (s.Albedo * light.rgb + light.rgb * spec);
c.rgb = (s.Albedo *(1,1,1,1)); // hacked in: no light, fake-color (white)
c.a = s.Alpha;
return c;

			}

			inline half4 LightingBlinnPhongEditor (EditorSurfaceOutput s, half3 lightDir, half3 viewDir, half atten)
			{
				half3 h = normalize (lightDir + viewDir);
				
				half diff = max (0, dot ( lightDir, s.Normal ));
				
				float nh = max (0, dot (s.Normal, h));
				float spec = pow (nh, s.Specular*128.0);
				
				half4 res;
				res.rgb = _LightColor0.rgb * diff;
				res.w = spec * Luminance (_LightColor0.rgb);
				res *= atten * 2.0;

				return LightingBlinnPhongEditor_PrePass( s, res );
			}
			
			struct Input {
				float2 uv_MainTex;
float4 color : COLOR;

			};

			void vert (inout appdata_full v, out Input o) {
float4 VertexOutputMaster0_0_NoInput = float4(0,0,0,0);
float4 VertexOutputMaster0_1_NoInput = float4(0,0,0,0);
float4 VertexOutputMaster0_2_NoInput = float4(0,0,0,0);
float4 VertexOutputMaster0_3_NoInput = float4(0,0,0,0);


			}
			

			void surf (Input IN, inout EditorSurfaceOutput o) {
				o.Normal = float3(0.0,0.0,1.0);
				o.Alpha = 1.0;
				o.Albedo = 0.0;
				o.Emission = 0.0;
				o.Gloss = 0.0;
				o.Specular = 0.0;
				o.Custom = 0.0;
				
float4 Tex2D0=tex2D(_MainTex,(IN.uv_MainTex.xyxy).xy);
float4 Invert0= float4(1.0, 1.0, 1.0, 1.0) - IN.color;
float4 Lerp0_1_NoInput = float4(0,0,0,0);
float4 Lerp0=lerp(Tex2D0,Lerp0_1_NoInput,Invert0);
float4 Master0_1_NoInput = float4(0,0,1,1);
float4 Master0_2_NoInput = float4(0,0,0,0);
float4 Master0_3_NoInput = float4(0,0,0,0);
float4 Master0_4_NoInput = float4(0,0,0,0);
float4 Master0_7_NoInput = float4(0,0,0,0);
float4 Master0_6_NoInput = float4(1,1,1,1);
o.Albedo = Lerp0;
o.Alpha = IN.color;

				o.Normal = normalize(o.Normal);
			}
		ENDCG
	}
	Fallback "Diffuse"
}

From that, it looks like it’s SSE who needs the practice, interpreting human desire! 8-O

I guess it would be great if the tool had some different presets/modes from which you start building the shader. Now it seems you start from a relatively complicated shader base… If I’m not mistaken, that was a feature request in the SSE thread here, so it can only get better.
But still, to me SSE is invaluable for rapid prototyping :slight_smile:

HI guys, thanks for the help!

I hadn’t realised that Vertex colours actually had an alpha value so I was never going to figure that out :roll_eyes:
I used Jesses code and it works perfect! Thanks again dude, your videos are great by the way… Just something about shader lab i find really confusing.

I had looked into SSE but i think the code it puts out seems a little over the top and I’m always trying to optimise stuff so it scared me a little. It does look pretty handy though.

P.

Okay, could I just ask a quick part 2 to this shader question?
Would it be possible to also use the texture’s alpha channel? This is a mobile shader so I am aware there are some limitations.
would I have to use Blend SrcAlpha OneMinusSrcAlpha again?

Thanks
P.

Certainly.

In that case, you should use GLSL for optimum performance. I’d also put in a color tint because it doesn’t cost anything extra (according to PVRUniSCo). The fixed function SubShader might be slower, but it would only run on obsolete devices anyway.

I recommend it; if you premultiply your graphics instead, and use compression, the alpha multiplication won’t correspond exactly with the alpha channel anymore.

Shader "Texture Vertex Mask" {
	
Properties {
	_Color ("Main Color", Color) = (1,1,1,1)
	_MainTex ("Base (RGB)", 2D) = "white"
}

Category {
	Tags {"Queue"="Transparent"}
	Blend SrcAlpha OneMinusSrcAlpha

	SubShader {Pass {
		GLSLPROGRAM
		varying mediump vec2 uv;
		varying lowp vec4 color;
				
		#ifdef VERTEX
		uniform mediump vec4 _MainTex_ST;
		uniform lowp vec4 _Color;
		void main() {
			gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
			uv = gl_MultiTexCoord0.xy * _MainTex_ST.xy + _MainTex_ST.zw;
			color = gl_Color * _Color;
			color.rgb *= 2.;						
		}
		#endif
		
		#ifdef FRAGMENT
		uniform lowp sampler2D _MainTex;
		void main() {
			gl_FragColor = texture2D(_MainTex, uv) * color;
		}
		#endif  
		ENDGLSL
	}}

	SubShader {Pass {
		BindChannels {
			Bind "vertex", vertex
			Bind "texCoord", texCoord
			Bind "color", color
		}
		SetTexture[_] {Combine primary * constant ConstantColor[_Color]}
		SetTexture[_MainTex] {Combine texture * previous Double, texture * previous}
	}}
}

}
1 Like

Hey thanks Jessy,
That’s really cool. I little scary though, looks like it jumped up a few difficulty notches. :shock: