I need to render some objects but ‘mask’ them off if they are in specific area! (inside a mesh or between two mesh)
I hope that made sense?
I need to render some objects but ‘mask’ them off if they are in specific area! (inside a mesh or between two mesh)
I hope that made sense?
Well, this can’t be done with a mesh as masking geometry, but with mathematical planes. Here’s a simply shader i’ve just written that takes 6 planes as parameters which define a volume that should be masked. Your cylinder has to use that shader and you need a script to setup the 6 planes. I’ve written a small script that uses 6 empty gameobjects to define those 6 planes. Each gameobject represents a plane in it’s x-y-plane while the forward (blue axis) is considered “outside”. So the volume that is “inside” of all those 6 planes will be clipped.
Shader "Custom/ClipMeshShader" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_Plane0 ("Top", Vector) = (0,0,0,0)
_Plane1 ("Bottom", Vector) = (0,0,0,0)
_Plane2 ("Left", Vector) = (0,0,0,0)
_Plane3 ("Right", Vector) = (0,0,0,0)
_Plane4 ("Front", Vector) = (0,0,0,0)
_Plane5 ("Back", Vector) = (0,0,0,0)
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Lambert
sampler2D _MainTex;
float4 _Plane0;
float4 _Plane1;
float4 _Plane2;
float4 _Plane3;
float4 _Plane4;
float4 _Plane5;
struct Input {
float2 uv_MainTex;
float3 worldPos;
};
void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.a;
float p0 = dot(_Plane0.xyz, IN.worldPos) + _Plane0.w;
float p1 = dot(_Plane1.xyz, IN.worldPos) + _Plane1.w;
float p2 = dot(_Plane2.xyz, IN.worldPos) + _Plane2.w;
float p3 = dot(_Plane3.xyz, IN.worldPos) + _Plane3.w;
float p4 = dot(_Plane4.xyz, IN.worldPos) + _Plane4.w;
float p5 = dot(_Plane5.xyz, IN.worldPos) + _Plane5.w;
if(p0<0 && p1<0 && p2<0 && p3<0 && p4<0 && p5<0)
clip(-1);
}
ENDCG
}
FallBack "Diffuse"
}
Here’s the script to set the shaders properties of our Material:
//C#
public class SetClipPlanes : MonoBehaviour
{
public Transform[] Planes; // out 6 empty gameobjects
public Material mat; // the material of the cylinder
void Update ()
{
for (int i = 0; i < 6; i++)
{
Vector4 V = Planes*.forward;*
V.w = -Vector3.Dot(V,Planes*.position);*
mat.SetVector(“_Plane”+i, V);
}
}
}
edit
Keep in mind that “cutting” / clipping a mesh won’t close the mesh at the cut like you have it in your example. It just masks the part in the middle. A shader can’t render something that isn’t there. If you need this you have to manually manipulate the mesh and literally cut out those parts and create new faces at the cut. This would equal what CSG does with boolean operations. However updating such geometry can be quite heavy but there are solutions out there for Unity