- Home /
Prevent ColorMask obscuring parts of an object's mesh
I am trying to use a shader to prevent an object being rendered when it leaves a specific area. However, when using a surface shader to do this, to fix drawing issues I have to use a depth buffer. Currently I am doing this by
Pass {
ColorMask 0
}
However, this is causing an effect that doesn't render the parts of the mesh that are behind the drawn parts of the color mask.
To get round this I attempted to just complete the pass but discard the fragments, this however caused faces to render in the wrong order. This potentially could be due to Cull Off
in the shader script below, however that is not the normal way my program handles the inside rendering, it was just a quick thing to provide reasonable results without lots of code. Also it happens with both Cull Back
and Cull Off
.
How can I make it so that either ColorMask 0
doesn't obscure what is behind it or what CG program could be used to prevent the issue with the faces rendering in the wrong order when all the fragments are discarded?
Shader Code - Lit.shader
Shader "Culling/Lit" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
//Properties normally assigned by script but can be done manually
_SHOWCULL("Show Cull", Int) = 0
_RADIUS("Radius", Float) = 0
_STARTX("Start X", Float) = 0
_STARTY("Start Y", Float) = 0
_STARTZ("Start Z", Float) = 0
_CENTREX("Centre X", Float) = 0
_CENTREY("Centre Y", Float) = 0
_CENTREZ("Centre Z", Float) = 0
_ENDX("End X", Float) = 0
_ENDY("End Y", Float) = 0
_ENDZ("End Z", Float) = 0
_MODE("Mode", Int) = 0
}
SubShader {
Tags{ "Queue" = "Transparent" "RenderType" = "Transparent" "IgnoreProjector" = "True" }
LOD 200
Blend SrcAlpha OneMinusSrcAlpha
ZWrite On
Pass {
//Renders faces in wrong order
/*CGPROGRAM
#pragma vertex vert
#pragma fragment frag
fixed4 _Color;
struct appdata {
float4 vertex : POSITION;
};
struct v2f {
float4 vertex : POSITION;
};
v2f vert (appdata v) {
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
return o;
}
fixed4 frag (v2f i) : COLOR {
discard;
return _Color;
}
ENDCG*/
ColorMask 0
}
Cull Off //Not normally used as provides incorrect light but way to fix is not needed for this and it is here to show example inside
CGPROGRAM
#pragma surface surf Standard fullforwardshadows alpha
#pragma target 3.0
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
float3 worldPos;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
UNITY_INSTANCING_CBUFFER_START(Props)
UNITY_INSTANCING_CBUFFER_END
int _SHOWCULL;
float _RADIUS;
float _STARTX;
float _STARTY;
float _STARTZ;
float _CENTREX;
float _CENTREY;
float _CENTREZ;
float _ENDX;
float _ENDY;
float _ENDZ;
int _MODE;
void surf (Input IN, inout SurfaceOutputStandard o) {
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
if (_MODE == 0) {
//For Cylinder
if (sqrt(((IN.worldPos.x - _CENTREX) * (IN.worldPos.x - _CENTREX)) +
((IN.worldPos.z - _CENTREZ) * (IN.worldPos.z - _CENTREZ))) < _RADIUS
&& IN.worldPos.y > _STARTY && IN.worldPos.y < _ENDY) {
}
else
{
discard; //ignores that pixel - doesnt render it
}
}
else if (_MODE == 1) {
//For Sphere
if (sqrt(((IN.worldPos.x - _CENTREX) * (IN.worldPos.x - _CENTREX)) +
((IN.worldPos.y - _CENTREY) * (IN.worldPos.y - _CENTREY)) +
((IN.worldPos.z - _CENTREZ) * (IN.worldPos.z - _CENTREZ))) < _RADIUS) {
}
else
{
discard; //ignores that pixel - doesnt render it
}
}
else if (_MODE == 2) {
// For Cuboid
if (IN.worldPos.x > _STARTX && IN.worldPos.x < _ENDX
&& IN.worldPos.y > _STARTY && IN.worldPos.y < _ENDY
&& IN.worldPos.z > _STARTZ && IN.worldPos.z < _ENDZ) {
}
else
{
discard; //ignores that pixel - doesnt render it
}
}
}
ENDCG
}
FallBack "Diffuse"
}