Difference between revisions of "PPU sprite priority"

From Nesdev wiki
Jump to: navigation, search
m (Created page with 'In the NES PPU, each sprite has two values that affect '''priority''', or what appears behind what: the index of the sprite within OAM (0 to 63), and the prio...')
 
m
Line 10: Line 10:
  
 
What really happens in the NES PPU is conceptually more like this:
 
What really happens in the NES PPU is conceptually more like this:
# During [[NES PPU#Sprite evaluation|sprite evaluation]] for each scanline (cycles 256 to 319), the eight frontmost sprites on this line get drawn front (lower index) to back (higher index) into a buffer, taking only the first opaque pixel that matches each X coordinate. Priority does not affect ordering in this buffer but is saved with each pixel.
+
# During [[PPU_sprite_evaluation|sprite evaluation]] for each scanline (cycles 256 to 319), the eight frontmost sprites on this line get drawn front (lower index) to back (higher index) into a buffer, taking only the first opaque pixel that matches each X coordinate. Priority does not affect ordering in this buffer but is saved with each pixel.
 
# The background gets drawn to a separate buffer.
 
# The background gets drawn to a separate buffer.
 
# For each pixel in the background buffer, the corresponding sprite pixel replaces it only if the sprite pixel is opaque and front priority.
 
# For each pixel in the background buffer, the corresponding sprite pixel replaces it only if the sprite pixel is opaque and front priority.
 
(Low-level hardware detail: The buffers don't actually exist as full-scanline buffers inside the PPU but instead as a set of counters and shift registers. The above logic is implemented a pixel at a time.)
 
(Low-level hardware detail: The buffers don't actually exist as full-scanline buffers inside the PPU but instead as a set of counters and shift registers. The above logic is implemented a pixel at a time.)

Revision as of 08:06, 11 June 2009

In the NES PPU, each sprite has two values that affect priority, or what appears behind what: the index of the sprite within OAM (0 to 63), and the priority bit (attribute 2 bit 5, set to 0 for front or 1 for back). In some cases, putting a back-priority sprite in front of a front-priority sprite can let the background show through and cover up the front-priority sprite. Super Mario Bros. 3 uses this for power-ups sprouting from blocks, putting a blank block "behind" the block at a low index and then putting the power-up "behind" that at a high index. (You can see the corners of this blank block when Mario hits a note block in World 1-2, as the note block becomes more squared off.)

The Nintendo DS PPU handles priority the "obvious" way,[1] and some NES emulator developers initially think the NES PPU handles it the same way:

  1. Front priority sprites in front
  2. The background plane in the middle
  3. Back priority sprites in back

What really happens in the NES PPU is conceptually more like this:

  1. During sprite evaluation for each scanline (cycles 256 to 319), the eight frontmost sprites on this line get drawn front (lower index) to back (higher index) into a buffer, taking only the first opaque pixel that matches each X coordinate. Priority does not affect ordering in this buffer but is saved with each pixel.
  2. The background gets drawn to a separate buffer.
  3. For each pixel in the background buffer, the corresponding sprite pixel replaces it only if the sprite pixel is opaque and front priority.

(Low-level hardware detail: The buffers don't actually exist as full-scanline buffers inside the PPU but instead as a set of counters and shift registers. The above logic is implemented a pixel at a time.)