The short answer

Z-buffer vs painter’s algorithm is about where the visibility decision happens. The painter’s algorithm sorts every polygon by depth. Then it paints them back to front, so nearer surfaces cover farther ones. That sort costs work, and it still fails whenever polygons overlap in a cycle or pass through each other. Instead, the z-buffer works differently. It keeps one depth value per pixel and tests each polygon’s pixels against that value directly. So no sorting happens at all. Because the test runs per pixel, cyclic overlap and intersecting polygons cause no trouble. That correctness costs memory, though: a whole extra buffer, at screen resolution. Modern GPUs implement the z-buffer directly in hardware. Still, the painter’s algorithm survives in simple 2D layering, where its overdraw barely matters.

Every 3D scene packs several surfaces onto the same few pixels. So a renderer has to decide, pixel by pixel, which surface actually shows. That decision is called hidden surface removal, and two classic methods solve it in almost opposite ways.

GATE and university papers test this topic through short trace questions. Given a few polygon depths, you work out what a z-buffer holds after each step. Examiners also ask why the painter’s algorithm can fail outright, not just run slowly. This guide covers both methods in full, then walks the same pixel through both, side by side.

Hidden surface removal runs late in the pipeline. It waits until a scene is fully transformed and placed on screen. Only then can a renderer ask which surface wins each pixel. That transform step is covered in geometric transformation vs coordinate transformation.

Three overlapping rectangles at depths 0.9, 0.6 and 0.4, with the nearest 0.4 rectangle shaded teal and drawn on top of the other two
Three polygons at different depths: only the nearest one, at 0.4, should end up visible.

The Hidden Surface Problem

A 3D scene is really a pile of flat polygons in space. So many of them project onto the very same pixel on screen. Only the nearest one should actually appear there; the rest sit behind it, hidden from the camera.

Skip that decision, and a renderer just draws polygons in whatever order they arrive. For example, a wall behind a chair could paint right over the chair. The picture would look wrong, even though every polygon on its own was perfectly correct.

This decision comes late in the pipeline, after clipping and mapping are already done. Before that, clipping trims away geometry outside the view, the job covered in Cohen-Sutherland vs Liang-Barsky. Mapping then places what remains onto the actual screen, through a viewport. After that, hidden surface removal runs, once every polygon already has its final screen position.

Two classic algorithms answer the visibility question in opposite ways. The painter’s algorithm sorts polygons before it draws a single pixel. The z-buffer tests depth at every pixel instead, without sorting anything at all.

The Painter’s Algorithm

The painter’s algorithm gets its name from an actual painting technique. A painter blocks in the background, then layers detail over it, with nearer objects on top. So the algorithm copies that order exactly.

It starts by sorting every polygon by depth. That sort works in object space, on whole polygons, not on individual pixels. Painting itself then happens in image space, one polygon at a time.

Polygons get drawn back to front, the nearest one landing on top. So each later polygon simply paints over whatever came before it at the same pixel. Because painting follows strict depth order, the nearest polygon always wins in the end.

This approach needs no per-pixel depth storage. That was its whole appeal on early, memory-poor hardware, back when a full depth buffer was too expensive to keep.

But that sort is not free. So its cost grows with the number of polygons in the scene, not just the number of pixels on screen. A single pixel can also get written several times, once for every polygon that lands on it. Every write except the last one is wasted work, called overdraw.

Advantages of the painter’s algorithm.

  • Needs no per-pixel depth buffer, so it suited memory-poor hardware.
  • Simple to implement once polygons are sorted by depth.
  • Still useful for flat 2D layering, where draw order is already fixed.

Disadvantages of the painter’s algorithm.

  • Sort cost grows with polygon count, not pixel count.
  • Overdraw wastes work, since a pixel may be painted several times.
  • Fails outright on cyclic overlap and on intersecting polygons, unless they are split first.

The Z-Buffer Algorithm

The z-buffer algorithm, also called the depth-buffer algorithm, solves visibility per pixel instead of per polygon. So it keeps a second buffer alongside the frame buffer, one depth value for every pixel, at the same resolution.

Both buffers start with a clean slate. The depth buffer initialises to the farthest possible value. The frame buffer, meanwhile, initialises to the background colour.

Then each polygon gets processed, in any order at all. For every pixel that polygon covers, the algorithm computes that pixel’s depth. If that depth is nearer than the value stored, it writes the new colour and depth. Otherwise, it discards the pixel and simply moves on.

So no sorting is required anywhere in this process. Polygons can arrive in any order, since every pixel resolves its own nearest surface on its own.

Because the test runs per pixel, not per polygon, cyclic overlap and intersecting polygons cause no trouble at all. So splitting is never needed.

Advantages of the z-buffer.

  • Needs no sort; polygons can arrive in any order and the result stays correct.
  • Handles cyclic overlap and intersecting polygons directly, with no splitting.
  • Implemented in graphics hardware, so modern GPUs run it at full speed.

Disadvantages of the z-buffer.

  • Costs memory for a full extra buffer, at screen resolution.
  • Still suffers overdraw, unless the scene happens to arrive front to back.
  • Guarantees only the correct final pixel, not less drawing work overall.

Z-Buffer vs Painter’s Algorithm: Comparison Table

Infographic comparing the painter's algorithm and the z-buffer on sorting, extra memory, whether visibility is decided per polygon or per pixel, and behaviour on cyclic overlap
Z-buffer vs painter’s algorithm at a glance: sorting, extra memory, decision level, and cyclic overlap.
AspectZ-BufferPainter’s Algorithm
How visibility is decidedCompares each pixel’s depth to a stored valueSorts polygons, then paints back to front
Sorting requiredNoYes, every polygon by depth
Extra memory requiredYes, a full depth buffer at screen resolutionNo per-pixel depth storage needed
Where the test happensPer pixelPer polygon
Handling of cyclic overlapCorrect, with no special handlingFails; no back-to-front order exists
Handling of intersecting polygonsCorrect, resolved per pixelFails unless the polygons are split
Need for polygon splittingNever neededNeeded for cyclic or intersecting cases
OverdrawStill occurs, unless input arrives front to backOccurs whenever polygons overlap on screen
Order sensitivity of inputResult does not depend on arrival orderResult depends on a correct depth sort
Hardware supportImplemented directly in GPU hardwareRarely implemented in hardware today
Effect of scene complexityCost tracks pixel count and overdrawSort cost grows with polygon count
Resolution dependenceDepth buffer size grows with resolutionSort cost does not depend on resolution
Typical use todayStandard method in modern 3D renderingSimple 2D layering, some basic renderers
Main limitationExtra memory for the depth bufferCannot handle cycles or intersections alone

Worked Example: One Pixel, Both Ways

Take one pixel on screen. Three polygons project onto it. Polygon A sits at depth 0.9, polygon B at 0.4, and polygon C at 0.6. A smaller number means nearer to the camera.

Watch the z-buffer process them in arrival order: A, then B, then C. The depth buffer starts at 1.0, the farthest possible value.

StepPolygonDepthTest against bufferActionBuffer after
0initialise1.0, background
1A0.90.9 < 1.0, nearerwrite A0.9, colour A
2B0.40.4 < 0.9, nearerwrite B0.4, colour B
3C0.60.6 is not < 0.4discard0.4, colour B

Trace it row by row. A arrives at 0.9, nearer than the 1.0 start, so it gets written. B arrives next, at 0.4, nearer than 0.9, so it overwrites A. C arrives last, at 0.6, not nearer than 0.4, so it gets discarded.

The final pixel holds colour B, the nearest of the three. No sorting happened at any point in this process.

In contrast, run the painter’s algorithm on the same pixel. It sorts first, farthest to nearest: A at 0.9, C at 0.6, B at 0.4. Painting then follows that order. A goes down first, C paints over it, and B paints over both, last.

The final pixel again holds colour B.

Both methods land on the same answer. Still, the real difference is the work behind it. The painter’s algorithm needed a full sort across three polygons, then wrote the pixel three times. Instead, the z-buffer needed no sort at all, just three cheap depth comparisons.

Where the Painter’s Algorithm Breaks

Depth sorting assumes each polygon has one clear depth relative to every other. But two situations break that assumption completely.

The first is cyclic overlap. Picture three long, thin polygons, A, B, and C, arranged like a pinwheel. A sits in front of B. B sits in front of C. C sits in front of A. Each relationship looks fine alone, but together they form a loop. So no back-to-front order can satisfy all three at once.

Three long rectangles labelled A, B and C arranged in a triangle so that B covers A, C covers B and A covers C, forming a cycle with no valid back-to-front order
Cyclic overlap: B covers A, C covers B, and A covers C, so no back-to-front order exists.

The second is intersecting polygons. Neither surface sits wholly in front of the other, since they pass through each other in space. So a single depth value per polygon cannot describe that. Different parts of the same polygon end up at different depths relative to its neighbour.

Both cases share one fix: split the polygons where the ordering breaks down. Each piece then gets a single, consistent depth. That splitting step adds real cost, and simple renderers often skip it entirely.

The z-buffer never runs into this problem. Its test happens per pixel, not per polygon. So a cycle or an intersection resolves correctly, one pixel at a time, with no splitting needed.

What the Depth Buffer Costs

A depth buffer is not free. It needs one value, usually 16, 24, or 32 bits wide, for every single pixel on screen.

Throughout this table, 1 MiB means 1,048,576 bytes, the binary definition, not the rounder 1,000,000-byte one.

ResolutionDepth bitsPixelsDepth buffer
1024 × 76816786,4321,572,864 bytes = 1.50 MiB
1024 × 76824786,4322,359,296 bytes = 2.25 MiB
1920 × 1080242,073,6006,220,800 bytes = 5.93 MiB
1920 × 1080322,073,6008,294,400 bytes = 7.91 MiB

Take the 1920 × 1080 row at 24 bits. Multiply width by height: 1920 × 1080 = 2,073,600 pixels. At 24 bits, that is 3 bytes per pixel, so 6,220,800 bytes in total, or 5.93 MiB.

Move to 32 bits at that same resolution, and the buffer grows to 8,294,400 bytes, or 7.91 MiB. So extra depth precision costs real memory.

This buffer does not replace anything already there. It sits alongside the frame buffer, which stores colour, not depth. So a working display needs both buffers, at the same resolution, held in memory at once.

Where Each One Is Used

The z-buffer is the standard method today. It ships in graphics hardware, so every modern GPU runs it as a routine part of the rendering pipeline. So games, CAD software, and 3D modelling tools all rely on it by default.

The painter’s algorithm has not vanished, though. Simple 2D layering, where draw order is already fixed, still uses it directly. Some basic renderers, without real 3D depth data, use it too. A sort stays cheap when the scene is small.

Once visibility is decided, a renderer still has to draw each visible polygon’s edges. That rasterising step works pixel by pixel, on whichever surface just won the depth test, using algorithms such as DDA vs Bresenham line drawing algorithm.

Exam papers usually pair a z-buffer trace with a painter’s algorithm failure case. In fact, both questions test the same underlying idea: deciding, correctly, what a viewer should actually see.

Interview Questions

The painter’s algorithm decides visibility per polygon, so every polygon needs a correct back-to-front order before drawing starts. The z-buffer decides visibility per pixel instead. Each pixel compares its own depth values directly, so no global order across polygons is ever needed.

Cyclic overlap means A is ahead of B, B ahead of C, and C ahead of A. A back-to-front order needs one consistent position for every polygon. A cycle makes that impossible, since no single ordering can satisfy all three relationships at once.

No, it does not. A pixel can still be written more than once, if several polygons cover it. The z-buffer only guarantees that the colour left behind is the correct, nearest one. So it does not reduce how many times a pixel gets touched.

The z-buffer’s per-pixel test is simple and regular. It runs well in parallel, across many pixels at once, which suits dedicated hardware. The painter’s algorithm needs a global sort up front, a step that does not parallelise the same way.

Frequently Asked Questions

The painter’s algorithm sorts every polygon by depth, then paints back to front. The z-buffer instead keeps one depth value per pixel. It tests each polygon against that value directly, with no sorting at all. That difference decides how each one handles cyclic overlap, memory use, and overdraw.

Modern GPUs use the z-buffer, implemented directly in hardware. The painter’s algorithm still appears in simple 2D layering and in some basic renderers. It is not the method behind mainstream 3D graphics today.

Intersecting polygons pass through each other, so neither one sits wholly in front of the other. A single depth value per polygon cannot capture that. The polygons must be split into pieces before a valid back-to-front order becomes possible.

No, it does not. Polygons can arrive in any order, and the result stays correct either way. Indeed, each pixel resolves its own nearest surface independently, which is exactly why no sorting step is needed.

That resolution holds 2,073,600 pixels. At 24 bits each, the depth buffer needs 6,220,800 bytes, which equals 5.93 MiB. That buffer sits alongside the frame buffer, so the display needs both in memory at once.

Yes, it can, with no special handling required. The depth test runs per pixel, not per polygon. So a cycle among three or more polygons resolves correctly on its own. No splitting step is needed, unlike with the painter’s algorithm.

Wrapping Up

Z-buffer vs painter’s algorithm comes down to where the decision happens. The painter’s algorithm decides per polygon, after a full depth sort. The z-buffer decides per pixel, with a cheap comparison and no sort at all.

Remember the trap cases for your exam. Cyclic overlap and intersecting polygons break the painter’s algorithm outright, unless the polygons are split beforehand. The z-buffer handles both correctly, without any splitting, since its test never depends on polygon order.

Finally, keep the memory cost in mind too. A depth buffer adds real bytes, at screen resolution, alongside the frame buffer already in use. That cost buys a correctness guarantee the painter’s algorithm cannot match alone.

Related reading on DiffStudy:


Whatsapp-color Created with Sketch.

By Arun Kumar

Full Stack Developer with a BE in Computer Science, working with React, Next.js, Node.js, MongoDB, and AI/ML tools. Founder of DiffStudy — built to help CS students ace GATE and university exams, and keep developers up to date across AI, cloud, system design, web development, and every field of computer science. Every article is written from real hands-on experience, not just theory.

Leave a Reply

Your email address will not be published. Required fields are marked *


You cannot copy content of this page