Backgrounds: Difference between revisions

From SNESdev Wiki
Jump to navigationJump to search
(Adds padding to priorities in BG mode table.)
(→‎Mode 5 & 6: 16x8 tiles even when interlaced)
 
(13 intermediate revisions by 2 users not shown)
Line 17: Line 17:
! [[#Mode 0|0]]
! [[#Mode 0|0]]
| 2 || 2 || 2 || 2 ||
| 2 || 2 || 2 || 2 ||
| <tt style="white-space: nowrap">&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S3</span> <span style="background-color:#ffdddd>1b</span> <span style="background-color:#ddddff>2b</span> <span style="background-color:#ffffdd>S2</span> <span style="background-color:#ffdddd>1a</span> <span style="background-color:#ddddff>2a</span> <span style="background-color:#ffffdd>S1</span> <span style="background-color:#ddffdd>3b</span> <span style="background-color:#ffddff>4b</span> <span style="background-color:#ffffdd>S0</span> <span style="background-color:#ddffdd>3a</span> <span style="background-color:#ffddff>4a</span></tt>
| <tt style="white-space: nowrap">&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S3</span> <span style="background-color:#ffdddd>1H</span> <span style="background-color:#ddddff>2H</span> <span style="background-color:#ffffdd>S2</span> <span style="background-color:#ffdddd>1L</span> <span style="background-color:#ddddff>2L</span> <span style="background-color:#ffffdd>S1</span> <span style="background-color:#ddffdd>3H</span> <span style="background-color:#ffddff>4H</span> <span style="background-color:#ffffdd>S0</span> <span style="background-color:#ddffdd>3L</span> <span style="background-color:#ffddff>4L</span></tt>
|-
|-
! [[#Mode 1|1]]
! [[#Mode 1|1]]
| 4 || 4 || 2 ||  ||
| 4 || 4 || 2 ||  ||
| <tt style="white-space: nowrap"><span style="background-color:#ddffdd>3c</span> <span style="background-color:#ffffdd>S3</span> <span style="background-color:#ffdddd>1b</span> <span style="background-color:#ddddff>2b</span> <span style="background-color:#ffffdd>S2</span> <span style="background-color:#ffdddd>1a</span> <span style="background-color:#ddddff>2a</span> <span style="background-color:#ffffdd>S1</span> <span style="background-color:#ddffdd>3b</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S0</span> <span style="background-color:#ddffdd>3a</span></tt>
| <tt style="white-space: nowrap"><span style="background-color:#ddffdd>3H</span> <span style="background-color:#ffffdd>S3</span> <span style="background-color:#ffdddd>1H</span> <span style="background-color:#ddddff>2H</span> <span style="background-color:#ffffdd>S2</span> <span style="background-color:#ffdddd>1L</span> <span style="background-color:#ddddff>2L</span> <span style="background-color:#ffffdd>S1</span> <span style="background-color:#ddffdd>3H</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S0</span> <span style="background-color:#ddffdd>3L</span></tt>
|-
|-
! [[#Mode 2|2]]
! [[#Mode 2|2]]
| 4 || 4 ||[[Offset-per-tile|OPT]]||  ||
| 4 || 4 ||[[Offset-per-tile|OPT]]||  ||
| <tt style="white-space: nowrap">&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S3</span> <span style="background-color:#ffdddd>1b</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S2</span> <span style="background-color:#ddddff>2b</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S1</span> <span style="background-color:#ffdddd>1a</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S0</span> <span style="background-color:#ddddff>2a</span></tt>
| <tt style="white-space: nowrap">&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S3</span> <span style="background-color:#ffdddd>1H</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S2</span> <span style="background-color:#ddddff>2H</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S1</span> <span style="background-color:#ffdddd>1L</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S0</span> <span style="background-color:#ddddff>2L</span></tt>
|-
|-
! [[#Mode 3|3]]
! [[#Mode 3|3]]
| 8 || 4 ||  ||  ||
| 8 || 4 ||  ||  ||
| <tt style="white-space: nowrap">&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S3</span> <span style="background-color:#ffdddd>1b</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S2</span> <span style="background-color:#ddddff>2b</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S1</span> <span style="background-color:#ffdddd>1a</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S0</span> <span style="background-color:#ddddff>2a</span></tt>
| <tt style="white-space: nowrap">&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S3</span> <span style="background-color:#ffdddd>1H</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S2</span> <span style="background-color:#ddddff>2H</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S1</span> <span style="background-color:#ffdddd>1L</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S0</span> <span style="background-color:#ddddff>2L</span></tt>
|-
|-
! [[#Mode 4|4]]
! [[#Mode 4|4]]
| 8 || 2 ||OPT||  ||
| 8 || 2 ||OPT||  ||
| <tt style="white-space: nowrap">&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S3</span> <span style="background-color:#ffdddd>1b</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S2</span> <span style="background-color:#ddddff>2b</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S1</span> <span style="background-color:#ffdddd>1a</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S0</span> <span style="background-color:#ddddff>2a</span></tt>
| <tt style="white-space: nowrap">&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S3</span> <span style="background-color:#ffdddd>1H</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S2</span> <span style="background-color:#ddddff>2H</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S1</span> <span style="background-color:#ffdddd>1L</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S0</span> <span style="background-color:#ddddff>2L</span></tt>
|-
|-
! [[#Mode 5|5]]
! [[#Mode 5|5]]
| 4 || 2 ||  ||  || ✔
| 4 || 2 ||  ||  || ✔
| <tt style="white-space: nowrap">&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S3</span> <span style="background-color:#ffdddd>1b</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S2</span> <span style="background-color:#ddddff>2b</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S1</span> <span style="background-color:#ffdddd>1a</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S0</span> <span style="background-color:#ddddff>2a</span></tt>
| <tt style="white-space: nowrap">&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S3</span> <span style="background-color:#ffdddd>1H</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S2</span> <span style="background-color:#ddddff>2H</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S1</span> <span style="background-color:#ffdddd>1L</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S0</span> <span style="background-color:#ddddff>2L</span></tt>
|-
|-
! [[#Mode 6|6]]
! [[#Mode 6|6]]
| 4 ||  ||OPT||  || ✔
| 4 ||  ||OPT||  || ✔
| <tt style="white-space: nowrap">&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S3</span> <span style="background-color:#ffdddd>1b</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S2</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S1</span> <span style="background-color:#ffdddd>1a</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S0</span></tt>
| <tt style="white-space: nowrap">&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S3</span> <span style="background-color:#ffdddd>1H</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S2</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S1</span> <span style="background-color:#ffdddd>1L</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S0</span></tt>
|-
|-
! [[#Mode 7|7]]
! [[#Mode 7|7]]
| 8 ||(7)||  ||  ||
| 8 ||(7)||  ||  ||
| <tt style="white-space: nowrap">&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S3</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S2</span> <span style="background-color:#ddddff>2b</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S1</span> <span style="background-color:#ffdddd>1a</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S0</span> <span style="background-color:#ddddff>2a</span></tt>
| <tt style="white-space: nowrap">&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S3</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S2</span> <span style="background-color:#ddddff>2H</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S1</span> <span style="background-color:#ffdddd>1L</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="background-color:#ffffdd>S0</span> <span style="background-color:#ddddff>2L</span></tt>
|}
|}


Line 52: Line 52:
Each of the 4 BG layers has several independent properties:
Each of the 4 BG layers has several independent properties:
* [[Tilemap]] VRAM address: [[PPU registers#BGnSC|BGnSC]]
* [[Tilemap]] VRAM address: [[PPU registers#BGnSC|BGnSC]]
* [[Tiles|tileset]] (CHR) VRAM address: [[PPU registers#BG12NBA|BG12NBA]], [[PPU registers#BG34NBA|BG34NBA]]
* [[Tiles|Tileset]] (CHR) VRAM address: [[PPU registers#BG12NBA|BG12NBA]], [[PPU registers#BG34NBA|BG34NBA]]
* Multiple tilemaps in 1x1, 2x1, 1x2, 2x2 arrangements: [[PPU registers#BGnSC|BGnSC]]
* Multiple tilemaps in 1x1, 2x1, 1x2, 2x2 arrangements: [[PPU registers#BGnSC|BGnSC]]
* Tile size of 8x8 (or 16x8) or 16x16: [[PPU registers#BGMODE|BGMODE]]
* Tile size of 8x8 (or 16x8) or 16x16: [[PPU registers#BGMODE|BGMODE]]
Line 59: Line 59:
* [[Mosaic]]: [[PPU registers#MOSAIC|MOSAIC]]
* [[Mosaic]]: [[PPU registers#MOSAIC|MOSAIC]]


Each of the 4 BG layers can be independently activated for the main and sub-screen.
Each of the 4 BG layers can be independently activated for the main and sub-screen: [[PPU registers#TM|TM]], [[PPU registers#TS|TS]]
* If [[color math]] is enabled, the main screen can be blended with the subscreen.
* If [[color math]] is enabled, the main screen can be blended with the subscreen.
* If high resolution is enabled ([[PPU registers#SETINI|SETINI]]) the main-screen appears on even columns, and the sub-screen appears on odd columns.
* If high resolution is enabled ([[PPU registers#SETINI|SETINI]]) the main-screen appears on even columns, and the sub-screen appears on odd columns.
Line 75: Line 75:
In the [[#Priority table|mode table above]]:
In the [[#Priority table|mode table above]]:
* <tt><span style="background-color:#ffffdd>S3</span> <span style="background-color:#ffffdd>S2</span> <span style="background-color:#ffffdd>S1</span> <span style="background-color:#ffffdd>S0</span></tt> are the [[sprite]] layers with priority 3, 2, 1 and 0.
* <tt><span style="background-color:#ffffdd>S3</span> <span style="background-color:#ffffdd>S2</span> <span style="background-color:#ffffdd>S1</span> <span style="background-color:#ffffdd>S0</span></tt> are the [[sprite]] layers with priority 3, 2, 1 and 0.
* <tt><span style="background-color:#ffdddd>1b</span> <span style="background-color:#ffdddd>1a</span></tt> is BG1 layers with high (b) and low (a) priority.
* <tt><span style="background-color:#ffdddd>1H</span> <span style="background-color:#ffdddd>1L</span></tt> is BG1 layers with high (H) and low (L) priority.
* <tt><span style="background-color:#ddddff>2b</span> <span style="background-color:#ddddff>2a</span></tt> is BG2 layers with high (b) and low (a) priority.
* <tt><span style="background-color:#ddddff>2H</span> <span style="background-color:#ddddff>2L</span></tt> is BG2 layers with high (H) and low (L) priority.
* <tt><span style="background-color:#ddffdd>3c</span> <span style="background-color:#ddffdd>3b</span> <span style="background-color:#ddffdd>3a</span></tt> BG3 in mode 1 has two different high priority positions, selected by [[PPU registers#BGMODE|BGMODE]]. Depending on the BGMODE setting, high can be either at the top (c) or middle (b), the low (a) priority is always in the same position.
* <tt><span style="background-color:#ddffdd>3H</span> <span style="background-color:#ddffdd>3L</span></tt> is BG3 layers with high (H) and low (L) priority. In mode 1 only, one of two different high priority positions can be chosen via [[PPU registers#BGMODE|BGMODE]].
* <tt><span style="background-color:#ffddff>4b</span> <span style="background-color:#ffddff>4a</span></tt> is BG4 layers with high (b) and low (a) priority.
* <tt><span style="background-color:#ffddff>4H</span> <span style="background-color:#ffddff>4L</span></tt> is BG4 layers with high (H) and low (L) priority.


In mode 7 BG1 only has one layer (a), but [[#EXTBG|EXTBG]] can enable BG2 split into two layers (b, a).
In mode 7 BG1 only has one layer (a), but [[#EXTBG|EXTBG]] can enable BG2 split into two layers (b, a).
Line 89: Line 89:


The main-screen appears on every even column, and the sub-screen appears on every odd column.
The main-screen appears on every even column, and the sub-screen appears on every odd column.
[[Color math]] may still be available, but since the sub-screen is no longer a hidden layer it has limited use.
[[Color math]] with a fixed color is still available.


In [[#Mode 5|modes 5 and 6]] high-resolution is forced, and the background layers are automatically de-interleaved into the main and sub-screens,
In [[#Mode 5|modes 5 and 6]] high-resolution is forced, and the background layers are automatically de-interleaved into the main and sub-screens,
Line 99: Line 99:
some games use the alternating columns as an alternative to [[color math]], providing something like a 50% "blend" of the main and sub screens.
some games use the alternating columns as an alternative to [[color math]], providing something like a 50% "blend" of the main and sub screens.
This usage is sometimes known as '''pseudo hi-res'''. (See: Jurassic Park, Kirby's Dream Land 3.)
This usage is sometimes known as '''pseudo hi-res'''. (See: Jurassic Park, Kirby's Dream Land 3.)
In modes 5 and 6, horizontal scrolling ([[PPU_registers#BGnHOFS|BGnHOFS]]) is in coarse increments of 2 high-resolution pixels. (Interlacing, on the other hand, automatically provides a fine vertical scroll.)


=== Interlacing ===
=== Interlacing ===
Line 110: Line 112:


In other modes, you would have to manually change the picture between even and odd fields to make use of the increased vertical resolution.
In other modes, you would have to manually change the picture between even and odd fields to make use of the increased vertical resolution.
In modes 5 and 6, vertical scrolling ([[PPU_registers#BGnVOFS|BGnVOFS]]) is automatically adjusted for interlacing, providing a fine high-resolution vertical scroll position, unlike horizontal high-resolution.


The lowered framerate has the drawback of a visible "flickering". Perception of this flickering varies from person to person,
The lowered framerate has the drawback of a visible "flickering". Perception of this flickering varies from person to person,
Line 123: Line 127:
The only mode which has 4 independent BG layers. Its drawback is that each layer is only 2bpp (4 color).
The only mode which has 4 independent BG layers. Its drawback is that each layer is only 2bpp (4 color).


Each of the 4 layers and choose one of 8 4-color palettes from a different subset of [[CGRAM]]:
The first 128 colors of [[CGRAM]] are divided into 32 4-color palettes, and each BG layer uses its own sequential non-overlapping 8-palette subset:
* BG0 at CGRAM 0
 
* BG1 at CGRAM 16
* BG0 uses CGRAM indices 0-31 (which is the same as the 2bpp layers in modes 1, 4, and 5)
* BG2 at CGRAM 32
* BG1 uses CGRAM indices 32-63
* BG3 at CGRAM 48
* BG2 uses CGRAM indices 64-95
* BG3 uses CGRAM indices 96-127


== Mode 1 ==
== Mode 1 ==
Line 134: Line 139:
BG3 has an additional [[priority]] control in mode 1. Its priority bit in [[PPU registers#BGMODE|BGMODE]] allows it to be rendered either above or below BG1 and BG2.
BG3 has an additional [[priority]] control in mode 1. Its priority bit in [[PPU registers#BGMODE|BGMODE]] allows it to be rendered either above or below BG1 and BG2.


BG3 selects a palette from the first 16 entries of [[CGRAM]].
BG3 selects a palette from the first 32 entries of [[CGRAM]].


In many games, BG1 and BG2 are used for a colourful main background with parallax, and BG3 to overlay a HUD or text box.
In many games, BG1 and BG2 are used for a colourful main background with parallax, and BG3 to overlay a HUD or text box.
Line 149: Line 154:
Mode 3 also has a 4bpp (16 color) auxiliary layer BG2.
Mode 3 also has a 4bpp (16 color) auxiliary layer BG2.


Mode 4 instead has a 2bpp (2 color) auxiliary layer BG2, and BG3 is used to encode [[offset-per-tile]]. (BG2 palettes are stored in the first 16 entries of [[CGRAM]].)
Mode 4 instead has a 2bpp (2 color) auxiliary layer BG2, and BG3 is used to encode [[offset-per-tile]]. (BG2 palettes are stored in the first 32 entries of [[CGRAM]].)


{{anchor|Mode 5|Mode 6}}
{{anchor|Mode 5|Mode 6}}
Line 157: Line 162:
The 8x8 pixel tilemap tile size selectable via [[PPU registers#BGMODE|BGMODE]] is replaced with a 16x8 pixel tile mode instead. The 16x16 mode is still 16x16.
The 8x8 pixel tilemap tile size selectable via [[PPU registers#BGMODE|BGMODE]] is replaced with a 16x8 pixel tile mode instead. The 16x16 mode is still 16x16.


If interlacing is enabled ([[PPU registers#SETINI|SETINI]]), the vertical tile density is automatically doubled as well, giving the option for vertical high-resolution as well.
If interlacing is enabled ([[PPU registers#SETINI|SETINI]]), the vertical tile density is automatically doubled as well, giving the option for vertical high-resolution as well. Note that the [[PPU registers#BGMODE|BGMODE]] register still chooses between 16x8 and 16x16. The provides the only way to have insufficient nametable to fill a whole screen: the combination of mode 5 or 6 with interlacing and 16x8 tiles and the smallest size nametable (32x32).


Horizontal scrolling in these modes only has a resolution of 2 hi-res pixels (i.e. 1/256 of the screen per increment), but when interlaced the vertical scrolling has fine control (1/480).
Horizontal scrolling in these modes only has a resolution of 2 hi-res pixels (i.e. 1/256 of the screen per increment), but when interlaced the vertical scrolling has fine control (1/480).
Line 171: Line 176:


This provides a single background layer that has a unique transformation property.
This provides a single background layer that has a unique transformation property.
:See: [[Mode 7 transform]]


The [[PPU registers#M7SEL|M7SEL]] register provides a few unusual properties just for mode 7:
The [[PPU registers#M7SEL|M7SEL]] register provides a few unusual properties just for mode 7:
* The entire tilemap can be horizontally or vertically flipped.
* The entire screen can be horizontally or vertically flipped.
* Outside the boundary of the square, three options are provided:
* Outside the boundary of the 1024x1024 pixel tilemap, three options are provided:
** Transparency
** Transparency.
** Fill with tile 0
** Fill with tile 0.
** Infinite horizontal and vertical wrapping (repetition) of the tilemap
** Infinite horizontal and vertical wrapping (repetition) of the tilemap.


Mode 7 tiles can use [[direct color]], if desired.
Mode 7 tiles can use [[direct color]], if desired.
Line 187: Line 193:
Normally mode 7 is a single layer on BG1 only, but [[PPU registers#SETINI|SETINI]] can be used to enable '''Mode 7 EXTBG''' which activates BG2 as a duplicate of BG1, but split into two layers.
Normally mode 7 is a single layer on BG1 only, but [[PPU registers#SETINI|SETINI]] can be used to enable '''Mode 7 EXTBG''' which activates BG2 as a duplicate of BG1, but split into two layers.


EXTBG BG2 treats the high bit of each tile's pixel color like a tilemap priority bit, allowing BG2 to be split into two layers which can appear above and below sprites. This sort of makes BG2 into two "7bpp" layers but they are not independently transformed or scrolled.
EXTBG BG2 treats the high bit of each tile's pixel value like a tilemap priority bit, allowing BG2 to be split into two layers which can appear above and below sprites. This sort of makes BG2 into two "7bpp" layers but they are not independently transformed or scrolled.
 
=== Affine Transformation ===
 
Instead of rendering normally, this tilemap (effectively a 1024x1024 pixel square) can be given an arbitrary 2D [https://en.wikipedia.org/wiki/Affine_transformation affine transformation], which means this is a square that can:
* Translate or slide its position up, down, left or right.
* Rotate at any angle.
* Zoom in and out or be squashed, but the scaling must be uniform along any axis (i.e. it can stretch along a straight line, but it cannot "bend").
* Shear or skew.
 
It is conceptually similar to [https://en.wikipedia.org/wiki/Texture_mapping texture mapping] a single quad on a modern GPU. Conversely, it is also like selecting a [https://en.wikipedia.org/wiki/Parallelogram parallelogram] region from the tilemap, and stretching its four corners to the rectangle of the screen.
 
The affine transformation can be changed every scanline via [[HDMA]], allowing versatile perspective and distortion effects.
: See: [[Mode 7 perspective effects]]
 
The usual scrolling registers for [[PPU registers#M7HOFS|M7HOFS]], [[PPU registers#M7VOFS|M7VOFS]], which pre-scroll the tilemap before transformation.
 
The affine transformation is applied by [[PPU registers#M7A|M7A]], [[PPU registers#M7B|M7B]], [[PPU registers#M7C|M7C]], [[PPU registers#M7D|M7D]], with an additional pivot-point center offset via [[PPU registers#M7X|M7X]], [[PPU registers#M7Y|M7Y]].
 
ABCD defines a [https://en.wikipedia.org/wiki/Transformation_matrix transformation matrix], which combined with the offset and pivot maps screen pixel coordinats (Sx,Sy) to texel coordinates (Tx,Ty):
+--    --+  +--              --+  +-- --+  +-  -+
| M7A M7B |  | Sx + M7HOFS - M7X |  | M7X |  | Tx |
|        | * |                  | + |    | = |    |
| M7C M7D |  | Sy + M7VOFS - M7Y |  | M7Y |  | Ty |
+--    --+  +--              --+  +-- --+  +-  -+


==== Affine Matrix ====
EXTBG does not support [[direct color]] for BG2. BG2 ignores the [[PPU registers#CGWSEL|CGWSEL]] direct color setting and will always use indexed color, though direct color can still be used for BG1.
 
'''M7A''', '''M7B''', '''M7C''', '''M7D''' together define how to map the tilemap "texture" to the screen, as pixels are rasterized left to right, top to bottom. In this explanation a ''pixel'' is an output pixel on the screen, and a ''texel'' is the color fetched from the 1024x1024 background tilemap. Each of these is an 8.8 fixed point value.
 
When you move one ''pixel'' to the right on the screen:
* '''M7A''' is how many ''texels'' to move to the right on the background.
* '''M7C''' is how many ''texels'' to move down.
 
When you move one ''pixel'' down on the screen:
* '''M7B''' is how many ''texels'' to move right.
* '''M7D''' is how many ''texels'' to move down.
 
In modern computer graphics terms: (M7A,M7C) and (M7B,M7D) are [https://en.wikipedia.org/wiki/Vector_(mathematics_and_physics) 2D vectors] defining Δ''u'' and Δ''v'' for [https://en.wikipedia.org/wiki/Texture_mapping texture mapping].
 
This is why the [[Init code|recommended default values]] of (1,0) (0,1) makes mode 7 behave like a normal background. 1 pixel to the right = 1 texel to the right. 1 pixel down = 1 texel down.
 
'''Scaling''' can be accomplished by changing the length of these vectors.
* (2,0) (0,1) will move 2 texels right for every 1 pixel, shrinking by 1/2 in the horizontal.
* (1,0) (0,-0.1) will move 0.1 texels up for every 1 pixel, stretching by 10 in the vertical and flipping upside down.
 
'''Rotation''' can be accomplished by rotating these vectors.
* (''cos'' ϴ, ''sin'' ϴ) (''-sin'' ϴ, ''cos'' ϴ) form a standard [https://en.wikipedia.org/wiki/Rotation_matrix rotation matrix] that will rotate the map by ϴ degrees.
:: On screen: it will rotate the map counter-clockwise relative to the pivot-point.
:: On map: it will rotate the view parallelogram clockwise.
* (0.866, 0.500) (-0.500, 0.866) will rotate by 30 degrees (CCW on screen, CW on map).
 
'''[https://en.wikipedia.org/wiki/Shear_mapping Shearing]''' creates a slanted mapping by adding to one coordinate unevenly.
* (1,0) (0.2,1) causes the background to gradually slide to the left as it proceeds down the screen.
 
Scaling, rotation, and shearing together can be combined into a single [https://en.wikipedia.org/wiki/Transformation_matrix transformation matrix] in A/B/C/D. This can be computed by [https://en.wikipedia.org/wiki/Matrix_multiplication matrix multiplication].
 
==== Center Adjustment ====
 
'''M7X''' and '''M7Y''' define a ''texel'' coordinate that becomes the center (a.k.a. pivot-point) of the scaling/rotation applied by the affine transformation matrix ABCD. This allows you to rotate around some other point besides the top left of the map.
 
'''M7HOFS''' and '''M7VOFS''' define a starting point for rasterization. After the transformation ABCD/XY is applied, this is a ''pixel'' coordinate that shifts the top-left of the screen. E.g. increasing M7HOFS by 1 will have the effect of moving whatever is in view 1 pixel to the left. With the default matrix this is exactly the same as just scrolling the map in other modes.
 
==== Summary ====
 
On screen:
* Start with a view of the top left 256x224 pixels of the tilemap.
* From that view, pick a pivot-point on the map (M7X,M7Y) and rotate and scale around that point (ABCD).
* Now (M7HOFS,M7VOFS) will move (right,down) in screen-space, scrolling over the transformed map.
 
On the map:
* (A,C) and (B,D) are vectors that define the angle and size of a parallelogram that will be the screen's view.
* The top-left corner of the parallelogram is a more complicated computation involving all 8 register values.
* Increasing M7HOFS or M7VOFS by 1 will move the top-left corner along the direction of the parallelogram sides equivalent to 1 screen pixel.


== See Also ==
== See Also ==
Line 266: Line 201:
* [[Tiles]]
* [[Tiles]]
* [[Uncommon graphics mode games]]
* [[Uncommon graphics mode games]]
== External Links ==
* [https://novasquirrel.github.io/Mode7Preview/ Novasquirrel: Mode 7 Preview] - Javascript preview of mode 7 register effect
* [https://dev.telinc1.com/mode7/index.html Telinc1: Mode 7 Simulator] - Javascript preview of mode 7 register effect


== References ==
== References ==
Line 276: Line 207:
* [https://www.youtube.com/watch?v=3FVN_Ze7bzw Retro Game Mechanics Explained: SNES Background Mode 7] - video
* [https://www.youtube.com/watch?v=3FVN_Ze7bzw Retro Game Mechanics Explained: SNES Background Mode 7] - video
* [https://www.youtube.com/watch?v=AnEuk8Vj3w0 Retro Game Mechanics Explained: SNES Background Modes Higher Resolutions] - video
* [https://www.youtube.com/watch?v=AnEuk8Vj3w0 Retro Game Mechanics Explained: SNES Background Modes Higher Resolutions] - video
[[Category:Graphics]]

Latest revision as of 19:08, 8 July 2024

The SNES backgrounds consist of one or more layers of tilemaps.

There are 8 available background modes, which can be changed at any time via BGMODE, even mid-screen.

Each mode has 1-4 layers, consisting of tiles that are 2bpp (4-color), 4bpp (16-color), or 8bpp (256-color).

Mode BG1 BG2 BG3 BG4 Hi-res Priority (front ↔ back)
0 2 2 2 2    S3 1H 2H S2 1L 2L S1 3H 4H S0 3L 4L
1 4 4 2 3H S3 1H 2H S2 1L 2L S1 3H    S0 3L
2 4 4 OPT    S3 1H    S2 2H    S1 1L    S0 2L
3 8 4    S3 1H    S2 2H    S1 1L    S0 2L
4 8 2 OPT    S3 1H    S2 2H    S1 1L    S0 2L
5 4 2    S3 1H    S2 2H    S1 1L    S0 2L
6 4 OPT    S3 1H    S2       S1 1L    S0
7 8 (7)    S3       S2 2H    S1 1L    S0 2L

Properties

Each of the 4 BG layers has several independent properties:

Each of the 4 BG layers can be independently activated for the main and sub-screen: TM, TS

  • If color math is enabled, the main screen can be blended with the subscreen.
  • If high resolution is enabled (SETINI) the main-screen appears on even columns, and the sub-screen appears on odd columns.
  • If neither color math nor high resolution is enabled, only the main screen is seen.

The 4 BG layers and sprites (OBJ) are composited to make the main and sub-screens, layered according to their priority

Priority

The way background layers and sprites are composited on top of each other is different for each mode.

Each of the background layers BG1-4 is further subdivided into a high and low priority layer, using tilemap attributes. Sprites (OBJ) are also subdivided into 4 layers of their own using their OAM attributes.

In the mode table above:

  • S3 S2 S1 S0 are the sprite layers with priority 3, 2, 1 and 0.
  • 1H 1L is BG1 layers with high (H) and low (L) priority.
  • 2H 2L is BG2 layers with high (H) and low (L) priority.
  • 3H 3L is BG3 layers with high (H) and low (L) priority. In mode 1 only, one of two different high priority positions can be chosen via BGMODE.
  • 4H 4L is BG4 layers with high (H) and low (L) priority.

In mode 7 BG1 only has one layer (a), but EXTBG can enable BG2 split into two layers (b, a).

High resolution

High resolution is automatically used in mode 5 and 6, but can be manually enabled for other modes via SETINI.

This doubles the horizontal resolution of the SNES from 256 to 512 pixels.

The main-screen appears on every even column, and the sub-screen appears on every odd column. Color math with a fixed color is still available.

In modes 5 and 6 high-resolution is forced, and the background layers are automatically de-interleaved into the main and sub-screens, rendering each tile at half its usual width, but with twice the density of pixels.

In other modes you would have to compose the main/sub-screen with alternating columns.

However, because 512px output tends to get blurred significantly on TVs through normal composite output, some games use the alternating columns as an alternative to color math, providing something like a 50% "blend" of the main and sub screens. This usage is sometimes known as pseudo hi-res. (See: Jurassic Park, Kirby's Dream Land 3.)

In modes 5 and 6, horizontal scrolling (BGnHOFS) is in coarse increments of 2 high-resolution pixels. (Interlacing, on the other hand, automatically provides a fine vertical scroll.)

Interlacing

Interlacing can also be enabled via SETINI.

Interlacing shifts every second frame (field) down by half a line. The result is that over 2 frames you get twice the vertical resolution, but at half the framerate. STAT78 can be used to determine whether you're currently on an even or odd field.

In modes 5 and 6, if interlacing is enabled the vertical tile density is automatically doubled across the two fields.

In other modes, you would have to manually change the picture between even and odd fields to make use of the increased vertical resolution.

In modes 5 and 6, vertical scrolling (BGnVOFS) is automatically adjusted for interlacing, providing a fine high-resolution vertical scroll position, unlike horizontal high-resolution.

The lowered framerate has the drawback of a visible "flickering". Perception of this flickering varies from person to person, but it is intensified by images with sharp vertical contrast. Normally interlaced video for broadcast is vertically filtered/blurred to reduce this effect, but this is harder to accomplish on the SNES with its palette limitations.

Care should be taken not to switch interlacing on or off too frequently in the middle of a game. On most modern televisions and capture devices, doing so will often cause the signal to drop and re-synchronize for a few seconds (or more). You might wish to wait for user input to confirm before proceeding into action, after swiching into or out of interlaced mode. Older CRT televisions can generally switch to interlacing instantly, though it cannot be changed mid-frame.

Mode 0

The only mode which has 4 independent BG layers. Its drawback is that each layer is only 2bpp (4 color).

The first 128 colors of CGRAM are divided into 32 4-color palettes, and each BG layer uses its own sequential non-overlapping 8-palette subset:

  • BG0 uses CGRAM indices 0-31 (which is the same as the 2bpp layers in modes 1, 4, and 5)
  • BG1 uses CGRAM indices 32-63
  • BG2 uses CGRAM indices 64-95
  • BG3 uses CGRAM indices 96-127

Mode 1

The most commonly used mode, which has two main 4bpp (16 color) layers BG1 and BG2, and one auxiliar 2bpp (4 color) layer BG3.

BG3 has an additional priority control in mode 1. Its priority bit in BGMODE allows it to be rendered either above or below BG1 and BG2.

BG3 selects a palette from the first 32 entries of CGRAM.

In many games, BG1 and BG2 are used for a colourful main background with parallax, and BG3 to overlay a HUD or text box.

BG3 can also be useful for things like a blended cloud or fog in the foreground, or a third parallax layer in the deep background. (Super Metroid has many good examples.)

Mode 2

Has two 4bpp layers like mode 1, but BG3 is used to encode offset-per-tile for BG1 and BG2, instead of being a visible layer.

Mode 3 & 4

Mode 3 has an 8bpp BG1 layer, allowing use of all 256 colors of CGRAM. This can also be used as direct color, bypassing CGRAM entirely.

Mode 3 also has a 4bpp (16 color) auxiliary layer BG2.

Mode 4 instead has a 2bpp (2 color) auxiliary layer BG2, and BG3 is used to encode offset-per-tile. (BG2 palettes are stored in the first 32 entries of CGRAM.)

Mode 5 & 6

Mode 5 and 6 force high resolution on, and automatically divide the background so that the tiles appear at double horizontal density.

The 8x8 pixel tilemap tile size selectable via BGMODE is replaced with a 16x8 pixel tile mode instead. The 16x16 mode is still 16x16.

If interlacing is enabled (SETINI), the vertical tile density is automatically doubled as well, giving the option for vertical high-resolution as well. Note that the BGMODE register still chooses between 16x8 and 16x16. The provides the only way to have insufficient nametable to fill a whole screen: the combination of mode 5 or 6 with interlacing and 16x8 tiles and the smallest size nametable (32x32).

Horizontal scrolling in these modes only has a resolution of 2 hi-res pixels (i.e. 1/256 of the screen per increment), but when interlaced the vertical scrolling has fine control (1/480).

Mode 5 has a 4bpp (16 color) BG1, and an auxiliary 2bpp (4 color) BG2.

Mode 6 is like mode 5 but replaces BG2 with an invisible BG3 providing offset-per-tile.

Mode 7

Mode 7 ignores most of the layer configuration options, and instead always occupies the entire first half of VRAM with a 128x128 tilemap, and 256 available 8x8 tiles.

See: Mode 7 tilemaps, Mode 7 tiles.

This provides a single background layer that has a unique transformation property.

See: Mode 7 transform

The M7SEL register provides a few unusual properties just for mode 7:

  • The entire screen can be horizontally or vertically flipped.
  • Outside the boundary of the 1024x1024 pixel tilemap, three options are provided:
    • Transparency.
    • Fill with tile 0.
    • Infinite horizontal and vertical wrapping (repetition) of the tilemap.

Mode 7 tiles can use direct color, if desired.

Sometimes mode 7 is used for large rotating boss characters. Even though it has only 1 background layer, sprites can be used to draw things around it that would normally be "background", and another BG mode might be switched to with HDMA to enable a solid floor background at the bottom, for example.

EXTBG

Normally mode 7 is a single layer on BG1 only, but SETINI can be used to enable Mode 7 EXTBG which activates BG2 as a duplicate of BG1, but split into two layers.

EXTBG BG2 treats the high bit of each tile's pixel value like a tilemap priority bit, allowing BG2 to be split into two layers which can appear above and below sprites. This sort of makes BG2 into two "7bpp" layers but they are not independently transformed or scrolled.

EXTBG does not support direct color for BG2. BG2 ignores the CGWSEL direct color setting and will always use indexed color, though direct color can still be used for BG1.

See Also

References