diff --git a/pixelgl/canvas.go b/pixelgl/canvas.go
index 25da93989fcc9402d4fa3b763d3b8c6e7fb47b52..5bc8437952b959e5c5c17a79d72ecef5e26caf33 100644
--- a/pixelgl/canvas.go
+++ b/pixelgl/canvas.go
@@ -327,6 +327,9 @@ func (ct *canvasTriangles) draw(tex *glhf.Texture, bounds pixel.Rect) {
 			}
 
 			ct.vs.Begin()
+			if clip, has := ct.ClipRect(); has {
+				gl.Scissor(int32(clip.Min.X), int32(clip.Min.Y), int32(clip.W()), int32(clip.H()))
+			}
 			ct.vs.Draw()
 			ct.vs.End()
 
diff --git a/pixelgl/gltriangles.go b/pixelgl/gltriangles.go
index f2581021bb2ca25b177e9776ea1310888b8238aa..557f420a01322423d0546b05fdbecfbfc435905c 100644
--- a/pixelgl/gltriangles.go
+++ b/pixelgl/gltriangles.go
@@ -16,6 +16,7 @@ type GLTriangles struct {
 	vs     *glhf.VertexSlice
 	data   []float32
 	shader *glhf.Shader
+	clip   pixel.Rect
 }
 
 var (
@@ -213,3 +214,14 @@ func (gt *GLTriangles) Picture(i int) (pic pixel.Vec, intensity float64) {
 	intensity = float64(gt.data[i*gt.vs.Stride()+8])
 	return pixel.V(float64(tx), float64(ty)), intensity
 }
+
+// SetClipRect sets the rectangle to scissor the triangles by
+func (gt *GLTriangles) SetClipRect(r pixel.Rect) {
+	gt.clip = r.Norm()
+}
+
+// ClipRect gets the clipping rectangle and returns true if that
+//	rectangle is not the Zero Rectangle
+func (gt *GLTriangles) ClipRect() (pixel.Rect, bool) {
+	return gt.clip, gt.clip.Area() != 0
+}