# How to clip game objects to a rectangular area

I'm trying to figure out how to do this but am coming up short. I'm making a slot machine in unity 2d and would like to clip the tile prefabs when they leave a given rectangular area.

I can't seem to figure out how to do this. All of the references I've found say to use a clipping shader with a mask texture, but it seems like massive overkill to use a masking texture when I just need an easy pre-defined rectangular area.

• In the roadmap this is listed as "2D: Masking" unity3d.com/unity/roadmap it's planned for next spring sigh – jhocking Aug 28 '15 at 20:27

What your are looking for, is called scissor test in OpenGL/Direct3D vocabulary. But unfortunately you don't have direct access to that feature in unity. I've been looking for a solution to same problem a few weeks ago, and I came across people suggesting to use multiple cameras with different render area to simulate this behavior.

Here are some articles that I've found back then, which you can read for further explanations.

If it's a 2D game and you want to clip to some rectangular area, why not just use an overlay with a cutout for the area you want exposed? There would be no runtime tests required. Just place all the tiles, then place your mask layer over top.

This is the same sort of technique that is used for most HUDs. Eg. A border around the edge of the screen.

The caveat would be that your mask would be a static image, so if you want the background outside of the clipping area to be dynamic (such as a generated or animated image), then it will be more complicated and you may need to use another method of clipping like what you or Ali.S has suggested.

• You know what, you're right. I've spent all day fighting with extra cameras and what the viewport units really mean and positioning everything the way I want. This is what I'm doing. It's just not worth it otherwise. – ReaperUnreal Aug 28 '15 at 18:54

I ended up doing something different. I used a shader to clip the sprites I was scrolling to a certain area of screen space. And here's the code for that shader since I know I was looking for it and could never find it.

Shader "Sprites/Clipped"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
[MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
_ClipX ("Clip X", Range(0.0, 2000.0)) = 0
_ClipY ("Clip Y", Range(0.0, 1000.0)) = 0
_Width ("Width", Range(0.0, 2000.0)) = 2000
_Height ("Height", Range(0.0, 1000.0)) = 1000
}

{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}

Cull Off
Lighting Off
ZWrite Off
Blend One OneMinusSrcAlpha

Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile _ PIXELSNAP_ON
#include "UnityCG.cginc"

struct appdata_t
{
float4 vertex   : POSITION;
float4 color    : COLOR;
float2 texcoord : TEXCOORD0;
};

struct v2f
{
float4 vertex    : SV_POSITION;
fixed4 color     : COLOR;
half2 texcoord   : TEXCOORD0;
float2 screenPos : TEXCOORD1;
};

fixed4 _Color;

v2f vert(appdata_t IN)
{
v2f OUT;
OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
OUT.texcoord = IN.texcoord;
OUT.color = IN.color * _Color;
#ifdef PIXELSNAP_ON
OUT.vertex = UnityPixelSnap (OUT.vertex);
#endif
OUT.screenPos.xy = ComputeScreenPos(OUT.vertex).xy * _ScreenParams.xy;

return OUT;
}

sampler2D _MainTex;
float _Width;
float _Height;
float _ClipX;
float _ClipY;

fixed4 frag(v2f IN) : SV_Target
{
if ((IN.screenPos.x < _ClipX) || (IN.screenPos.x > _ClipX + _Width) || (IN.screenPos.y < _ClipY) || (IN.screenPos.y > _ClipY + _Height))
{
fixed4 transparent = fixed4(0, 0, 0, 0);
return transparent;
}

fixed4 c = tex2D(_MainTex, IN.texcoord) * IN.color;
c.rgb *= c.a;
return c;
}
ENDCG
}
}
}


c *= step(_ClipX, IN.screenPos.x) * step(IN.screenPos.x, _ClipX+_Width) *