diff --git a/batch.go b/batch.go
index b82253620915e5a8ba42debb0c53819e211f812b..fe48e35d1f43eb89bddcf73ae137e9418c65828e 100644
--- a/batch.go
+++ b/batch.go
@@ -81,14 +81,13 @@ func (b *Batch) MakeTriangles(t Triangles) TargetTriangles {
 
 // MakePicture returns a specialized copy of the provided Picture that draws onto this Batch.
 func (b *Batch) MakePicture(p Picture) TargetPicture {
-	if p.Original() != b.cont.Picture.Original() {
-		panic(fmt.Errorf("(%T).MakePicture: Picture is not a slice of Batch's Picture", b))
+	if p != b.cont.Picture {
+		panic(fmt.Errorf("(%T).MakePicture: Picture is not the Batch's Picture", b))
 	}
 	bp := &batchPicture{
 		pic: p,
 		dst: b,
 	}
-	bp.orig = bp
 	return bp
 }
 
@@ -149,27 +148,14 @@ func (bt *batchTriangles) Draw() {
 }
 
 type batchPicture struct {
-	pic  Picture
-	orig *batchPicture
-	dst  *Batch
+	pic Picture
+	dst *Batch
 }
 
 func (bp *batchPicture) Bounds() Rect {
 	return bp.pic.Bounds()
 }
 
-func (bp *batchPicture) Slice(r Rect) Picture {
-	return &batchPicture{
-		pic:  bp.pic.Slice(r),
-		orig: bp.orig,
-		dst:  bp.dst,
-	}
-}
-
-func (bp *batchPicture) Original() Picture {
-	return bp.orig
-}
-
 func (bp *batchPicture) Draw(t TargetTriangles) {
 	bt := t.(*batchTriangles)
 	if bp.dst != bt.dst {
diff --git a/data.go b/data.go
index dbe44f30df78bc1a58a1fee7455e891dc7e2fdcd..826369363e980fc4de941256e6b8d6c2f34c5f6a 100644
--- a/data.go
+++ b/data.go
@@ -132,7 +132,6 @@ type PictureData struct {
 	Pix    []color.NRGBA
 	Stride int
 	Rect   Rect
-	Orig   *PictureData
 }
 
 // MakePictureData creates a zero-initialized PictureData covering the given rectangle.
@@ -144,7 +143,6 @@ func MakePictureData(rect Rect) *PictureData {
 		Rect:   rect,
 	}
 	pd.Pix = make([]color.NRGBA, w*h)
-	pd.Orig = pd
 	return pd
 }
 
@@ -263,22 +261,6 @@ func (pd *PictureData) Bounds() Rect {
 	return pd.Rect
 }
 
-// Slice returns a sub-Picture of this PictureData inside the supplied rectangle.
-func (pd *PictureData) Slice(r Rect) Picture {
-	return &PictureData{
-		Pix:    pd.Pix[pd.Index(r.Min):],
-		Stride: pd.Stride,
-		Rect:   r,
-		Orig:   pd.Orig,
-	}
-}
-
-// Original returns the most original PictureData that this PictureData was obtained from using
-// Slice-ing.
-func (pd *PictureData) Original() Picture {
-	return pd.Orig
-}
-
 // Color returns the color located at the given position.
 func (pd *PictureData) Color(at Vec) NRGBA {
 	if !pd.Rect.Contains(at) {
diff --git a/drawer.go b/drawer.go
index b7bdc5fd4abb5b11d8734f2945bfa6b00fbda31e..72b5708e421cffb5a7e367a0e31d86632aa2fedd 100644
--- a/drawer.go
+++ b/drawer.go
@@ -78,12 +78,11 @@ func (d *Drawer) Draw(t Target) {
 		return
 	}
 
-	pic := d.pics[targetPicturePair{t, d.Picture.Original()}]
+	pic := d.pics[targetPicturePair{t, d.Picture}]
 	if pic == nil {
-		pic = t.MakePicture(d.Picture.Original())
-		d.pics[targetPicturePair{t, d.Picture.Original()}] = pic
+		pic = t.MakePicture(d.Picture)
+		d.pics[targetPicturePair{t, d.Picture}] = pic
 	}
-	pic = pic.Slice(d.Picture.Bounds()).(TargetPicture)
 
 	pic.Draw(tri)
 }
diff --git a/interface.go b/interface.go
index ed705ed7ed5614eb2372dc351fb9bef68d477ed0..8f0f8241d1417fca776853cd99f8514bdbff00da 100644
--- a/interface.go
+++ b/interface.go
@@ -108,19 +108,6 @@ type Picture interface {
 	// Bounds returns the rectangle of the Picture. All data is located witih this rectangle.
 	// Querying properties outside the rectangle should return default value of that property.
 	Bounds() Rect
-
-	// Slice returns a sub-Picture with specified Bounds.
-	//
-	// A result of Slice-ing outside the original Bounds is unspecified.
-	Slice(Rect) Picture
-
-	// Original returns the most original Picture (may be itself) that this Picture was created
-	// from using Slice-ing.
-	//
-	// Since the Original and this Picture should share the underlying data and this Picture can
-	// be obtained just by slicing the Original, this method can be used for more efficient
-	// caching of Pictures.
-	Original() Picture
 }
 
 // TargetPicture is a Picture generated by a Target using MakePicture method. This Picture can be drawn onto
diff --git a/pixelgl/canvas.go b/pixelgl/canvas.go
index 01a36bf497a5f981958baa414f7a7d092e9f5c7d..0439bb07133b18fac45397b487b77b3765421d0d 100644
--- a/pixelgl/canvas.go
+++ b/pixelgl/canvas.go
@@ -92,9 +92,8 @@ func (c *Canvas) MakePicture(p pixel.Picture) pixel.TargetPicture {
 	// Canvas special case
 	if canvas, ok := p.(*Canvas); ok {
 		return &canvasCanvasPicture{
-			src:    canvas,
-			dst:    c,
-			bounds: c.bounds,
+			src: canvas,
+			dst: c,
 		}
 	}
 
@@ -140,12 +139,11 @@ func (c *Canvas) MakePicture(p pixel.Picture) pixel.TargetPicture {
 	cp := &canvasPicture{
 		tex:    tex,
 		pixels: pixels,
-		borders: pixel.R(
+		bounds: pixel.R(
 			float64(bx), float64(by),
 			float64(bw), float64(bh),
 		),
-		bounds: bounds,
-		dst:    c,
+		dst: c,
 	}
 	cp.orig = cp
 	return cp
@@ -261,25 +259,6 @@ func (c *Canvas) Clear(color color.Color) {
 	})
 }
 
-// Slice returns a sub-Canvas with the specified Bounds.
-//
-// The type of the returned value is *Canvas, the type of the return value is a general
-// pixel.Picture just so that Canvas implements pixel.Picture interface.
-func (c *Canvas) Slice(bounds pixel.Rect) pixel.Picture {
-	sc := new(Canvas)
-	*sc = *c
-	sc.bounds = bounds
-	return sc
-}
-
-// Original returns the most original Canvas that this Canvas was created from using Slice-ing.
-//
-// The type of the returned value is *Canvas, the type of the return value is a general
-// pixel.Picture just so that Canvas implements pixel.Picture interface.
-func (c *Canvas) Original() pixel.Picture {
-	return c.orig
-}
-
 // Color returns the color of the pixel over the given position inside the Canvas.
 func (c *Canvas) Color(at pixel.Vec) pixel.NRGBA {
 	if c.orig.dirty {
@@ -311,7 +290,7 @@ type canvasTriangles struct {
 	dst *Canvas
 }
 
-func (ct *canvasTriangles) draw(tex *glhf.Texture, borders, bounds pixel.Rect) {
+func (ct *canvasTriangles) draw(tex *glhf.Texture, bounds pixel.Rect) {
 	ct.dst.orig.dirty = true
 
 	// save the current state vars to avoid race condition
@@ -339,12 +318,6 @@ func (ct *canvasTriangles) draw(tex *glhf.Texture, borders, bounds pixel.Rect) {
 		} else {
 			tex.Begin()
 
-			ct.dst.s.SetUniformAttr(canvasTexBorders, mgl32.Vec4{
-				float32(borders.Min.X()),
-				float32(borders.Min.Y()),
-				float32(borders.W()),
-				float32(borders.H()),
-			})
 			ct.dst.s.SetUniformAttr(canvasTexBounds, mgl32.Vec4{
 				float32(bounds.Min.X()),
 				float32(bounds.Min.Y()),
@@ -369,14 +342,13 @@ func (ct *canvasTriangles) draw(tex *glhf.Texture, borders, bounds pixel.Rect) {
 }
 
 func (ct *canvasTriangles) Draw() {
-	ct.draw(nil, pixel.Rect{}, pixel.Rect{})
+	ct.draw(nil, pixel.Rect{})
 }
 
 type canvasPicture struct {
-	tex     *glhf.Texture
-	pixels  []uint8
-	borders pixel.Rect
-	bounds  pixel.Rect
+	tex    *glhf.Texture
+	pixels []uint8
+	bounds pixel.Rect
 
 	orig *canvasPicture
 	dst  *Canvas
@@ -386,22 +358,11 @@ func (cp *canvasPicture) Bounds() pixel.Rect {
 	return cp.bounds
 }
 
-func (cp *canvasPicture) Slice(r pixel.Rect) pixel.Picture {
-	sp := new(canvasPicture)
-	*sp = *cp
-	sp.bounds = r
-	return sp
-}
-
-func (cp *canvasPicture) Original() pixel.Picture {
-	return cp.orig
-}
-
 func (cp *canvasPicture) Color(at pixel.Vec) pixel.NRGBA {
 	if !cp.bounds.Contains(at) {
 		return pixel.NRGBA{}
 	}
-	bx, by, bw, _ := intBounds(cp.borders)
+	bx, by, bw, _ := intBounds(cp.bounds)
 	x, y := int(at.X())-bx, int(at.Y())-by
 	off := y*bw + x
 	return pixel.NRGBA{
@@ -417,32 +378,19 @@ func (cp *canvasPicture) Draw(t pixel.TargetTriangles) {
 	if cp.dst != ct.dst {
 		panic(fmt.Errorf("(%T).Draw: TargetTriangles generated by different Canvas", cp))
 	}
-	ct.draw(cp.tex, cp.borders, cp.bounds)
+	ct.draw(cp.tex, cp.bounds)
 }
 
 type canvasCanvasPicture struct {
 	src, dst *Canvas
-	bounds   pixel.Rect
-	orig     *canvasCanvasPicture
 }
 
 func (ccp *canvasCanvasPicture) Bounds() pixel.Rect {
-	return ccp.bounds
-}
-
-func (ccp *canvasCanvasPicture) Slice(r pixel.Rect) pixel.Picture {
-	sp := new(canvasCanvasPicture)
-	*sp = *ccp
-	sp.bounds = r
-	return sp
-}
-
-func (ccp *canvasCanvasPicture) Original() pixel.Picture {
-	return ccp.orig
+	return ccp.src.Bounds()
 }
 
 func (ccp *canvasCanvasPicture) Color(at pixel.Vec) pixel.NRGBA {
-	if !ccp.bounds.Contains(at) {
+	if !ccp.Bounds().Contains(at) {
 		return pixel.NRGBA{}
 	}
 	return ccp.src.Color(at)
@@ -453,7 +401,7 @@ func (ccp *canvasCanvasPicture) Draw(t pixel.TargetTriangles) {
 	if ccp.dst != ct.dst {
 		panic(fmt.Errorf("(%T).Draw: TargetTriangles generated by different Canvas", ccp))
 	}
-	ct.draw(ccp.src.orig.f.Texture(), ccp.src.orig.borders, ccp.bounds)
+	ct.draw(ccp.src.orig.f.Texture(), ccp.Bounds())
 }
 
 const (
@@ -474,16 +422,14 @@ const (
 	canvasTransform int = iota
 	canvasColorMask
 	canvasBounds
-	canvasTexBorders
 	canvasTexBounds
 )
 
 var canvasUniformFormat = glhf.AttrFormat{
-	canvasTransform:  {Name: "transform", Type: glhf.Mat3},
-	canvasColorMask:  {Name: "colorMask", Type: glhf.Vec4},
-	canvasBounds:     {Name: "bounds", Type: glhf.Vec4},
-	canvasTexBorders: {Name: "texBorders", Type: glhf.Vec4},
-	canvasTexBounds:  {Name: "texBounds", Type: glhf.Vec4},
+	canvasTransform: {Name: "transform", Type: glhf.Mat3},
+	canvasColorMask: {Name: "colorMask", Type: glhf.Vec4},
+	canvasBounds:    {Name: "bounds", Type: glhf.Vec4},
+	canvasTexBounds: {Name: "texBounds", Type: glhf.Vec4},
 }
 
 var canvasVertexShader = `
@@ -532,15 +478,8 @@ void main() {
 	} else {
 		color = vec4(0, 0, 0, 0);
 		color += (1 - Intensity) * colorMask * Color;
-
-		float bx = texBounds.x;
-		float by = texBounds.y;
-		float bw = texBounds.z;
-		float bh = texBounds.w;
-		if (bx <= Texture.x && Texture.x <= bx + bw && by <= Texture.y && Texture.y <= by + bh) {
-			vec2 t = (Texture - texBorders.xy) / texBorders.zw;
-			color += Intensity * colorMask * Color * texture(tex, t);
-		}
+		vec2 t = (Texture - texBounds.xy) / texBounds.zw;
+		color += Intensity * colorMask * Color * texture(tex, t);
 	}
 }
 `