AuthorTopic: I'd like some help/information on SNES sprite art & methods for a PC game  (Read 10456 times)

Offline Mu

  • 0001
  • *
  • Posts: 3
  • Karma: +0/-0
    • View Profile
edit: I've just realized I've posted in the wrong area. Got so caught up in browsing through all the posted pixel art threads. Sorry!

Hello,

I'm a bit of a C++ programmer and an artist. I hope to become somewhat competent at pixel art, and I aim to develop a PC game which would have gameplay and art similar to Secret of Mana/Secret of Evermore/Terranigma, etc. I would like to restrict myself to most of the limitations of SNES games in order to be authentic, but also for a couple legitimate reasons which I'll talk (and ask) about.

Limitations:

http://en.wikibooks.org/wiki/Super_NES_Programming/SNES_Specs

  • Picture Processor Unit: 15-Bit
  • Video RAM: 64 KB of VRAM for screen maps (for 'background' layers) and tile sets (for backgrounds and objects); 512 + 32 bytes of 'OAM' (Object Attribute Memory) for objects; 512 bytes of 'CGRAM' for palette data.
  • Palette: 256 entries; 15-Bit color (BGR555) for a total of 32,768 colors.
  • Maximum colors per layer per scanline: 256.
  • Maximum colors on-screen: 32,768 (using color arithmetic for transparency effects).
  • Resolution: between 256x224 and 512x448. Most games used 256x224 pixels since higher resolutions caused slowdown, flicker, and/or had increased limitations on layers and colors (due to memory bandwidth constraints); the higher resolutions were used for less processor-intensive games, in-game menus, text, and high resolution images.
  • Maximum onscreen objects (sprites): 128 (32 per line, up to 34 8x8 tiles per line).
  • Maximum number of sprite pixels on one scanline: 256. The renderer was designed such that it would drop the frontmost sprites instead of the rearmost sprites if a scanline exceeded the limit, allowing for creative clipping effects.
  • Most common display modes: Pixel-to-pixel text mode 1 (16 colors per tile; 3 scrolling layers) and affine mapped text mode 7 (256 colors per tile; one rotating/scaling layer).

I feel that one of the most important things here is 15-bit color (32768 colors). So, 5 bits (32 unique vals) for each of the three color channels of RGB. This means (I believe), color values (represented in bytes, 0-255), should only ever be multiples of 8. So, "16 8 40" is a valid SNES color. This also means (I believe), that while "0 0 0" is valid, "255 255 255" isn't. "White" I assume would then be "248 248 248". Would this be right?

Manual restrictions while painting:

One issue I have is it's uncomfortable to draw in MSPaint using only values with multiples of 8, since I have to manually define the values myself. Normally that's not a problem, but there is the possibility of human error -- what if I accidentally draw with "214 214 214" (invalid) when I intended to draw with "224 224 224" (valid)? I wouldn't notice (and no one else would), but it would still be incorrect! Is there some method or program that supports drawing in 15-bit color, so that the tool itself would "support" the limitation, and not be "faked" manually by myself?

Palettes:

This is more of a programming question, but I assume someone else has done this, post-SNES. I'm interested in sprite palettes for a few reasons. In SNES games, it seems that sprites generally don't use over 16 colors, and they like to re-use colors. Of course, if there is indeed a limit of 16 colors, then obviously reusing colors wherever possible is smart. In the image below, Guile's (via Capcom) skin ranges from white to peach to brown. The browns are reused on his boots and pants, the white is reused for highlights all over, and even the peach is reused in his hair color. The blue pixel for his eyes is the same blue of his tattoo, etc. There are also many games where different characters use the same color palettes, so the total palettes saved is cut down. I understand these things, but I would like to know if my assumptions are right, and anything else that might be interesting or useful about this.



One thing I want to say here is that the # of colors stated is only representative of the # of colors in the pictured frame. Therefore, they may (probably) have one or more colors in their REAL palettes. (Perhaps it really is 16 total?)

One feature that I admire greatly, which is actually used more than I initially realized, is swapping out one or more color values in a palette at any time. This is used so frequently in SNES games! In Street Fighter II: TNC, you can pick different palettes for your fighter by pressing a different attack (rather than light punch) at character select. This is a palette swap for the whole session until you lose and pick a character again. This means (though, I'm still making assumptions here) the game does not store multiple sprite sheets for every skin, but rather just one, and swaps the colors out as required. Another example from SFII: TNC is Ryu's fireball. Normally, it has a white-to-blue palette. However, if you do a slightly longer sequence you get a fiery fireball, using a yellow-to-red palette. It would surely be wasteful to have to store frames for the blue and red fireball separately, since they can be palette-swapped for the same effect.

In countless RPGs, like Final Fantasy, Chrono Trigger, and even Secret of Evermore (kid & dog pictured above, via Square USA), partial palette swapping occurs to illustrate status effects. The dark gray border of the kid above turns lime green if he is poisoned, and cycles smoothly from lime green, to black, to lime green, and repeats. In this case, only that single value in his palette would be swapped out. In FF6 and some other games, poison is illustrated differently. Instead of the outline changing, their actual skin color (3 or so colors) turns pale purple. I wanted to demonstrate that cool effect on the Evermore kid, but I realized they used one of his skin tones in his brown vest. :) However, if the user had the option to change the Secret of Evermore kid's shirt and pants color, they could use the same feature by swapping out only those colors (assuming they were fine with the two light blue pixels on the eyes being changed as well).



Nowadays, when people develop retro-looking games, I believe they usually just make multiple sprite sheets with the alternate colors. Computers now aren't limited by memory or processing power, so it's sometimes easier to just do it that way.

However, on top of being truly optimized for memory, there were other awesome features of palette swapping. Use a Candy on yourself in Secret of Mana and watch what happens. The palette of your entire character temporarily cycles through a blue-to-white gradient, which gives an impressive magical shimmer on the entire character (possible excluding the color value for his shadow). The fact that this is done in an optimized, limited manner, is excellent. Adding additional frames on the sprite sheet itself just to accomplish the same feature seems a bit lazy and wasteful, especially if I want to support multiple colors (i.e. blue-to-white for heal, red-to-yellow for burned, green-to-purple for plagued, etc).

I believe I understand the theory (assuming the things I've said in this post are correct), but I don't quite understand the "how". If anyone has any information on how to actually render graphics in this indexed manner (using only indexed images is a starting point, but I'm unsure from there) and take advantage of palette swapping, it would be wonderful. Also, of course, the renderer could (hopefully) only support 15-bit color. (Because plain rendering 24-bit PNGs through DirectX with "manually-imposed" limitations is definitely not the same thing..!)

I haven't been really asking precise questions, but I'd be very appreciative of knowledge on any of these subjects, or anything I haven't mentioned but would appear to be helpful or interesting. Thank you! :)
« Last Edit: March 29, 2013, 12:21:10 pm by Mu »

Offline Pix3M

  • 0010
  • *
  • Posts: 265
  • Karma: +1/-0
    • View Profile
Do not mindlessly imitate SNES sprite art.  :'(

While you are interested in old technical limitations, there is a technical concern a modern pixel artist needs to be wary of that a SNES pixel artist does not need to worry about. Back then, we had blurry monitors. Today, we have sharp LCD monitors. SNES sprites were never designed to look good on sharp monitors in mind.

Where two colors border, a line is created. That Guile sprite was intended to be rendered with gradient shading and stuff, but on a blurry monitor, the pixels are blurred and you get a gradient. Now you have lines chopping up the sprite work and it is a pretty unsightly visual effect. Some SNES sprite art naturally looks worse than others since some styles try to be more highly rendered, but if you really want to look like an SNES game, this is an important part of art history you want to know about.

Offline surt

  • 0011
  • **
  • Posts: 570
  • Karma: +0/-0
  • Meat by-product
    • not_surt
    • http://pixeljoint.com/p/2254.htm
    • View Profile
    • Uninhabitant
I believe ProMotion allows you limit colours to a chosen bits-per-component, though it'd be easy enough to snap the colours the assets by batch, or on load.

You should be able to do indexed rendering with a pixel shader mapping a greyscale image value to an offset into a palette image.

Offline Crow

  • 0011
  • **
  • Posts: 647
  • Karma: +0/-0
  • Technicanimal
    • View Profile
edit: I've just realized I've posted in the wrong area. Got so caught up in browsing through all the posted pixel art threads. Sorry!

Successfully moved :)
Discord: Ennea#9999

Offline Ai

  • 0100
  • ***
  • Posts: 1057
  • Karma: +2/-0
  • finti
    • http://pixeljoint.com/pixels/profile.asp?id=1996
    • finticemo
    • View Profile
    edit: I've just realized I've posted in the wrong area. Got so caught up in browsing through all the posted pixel art threads. Sorry!
    • Palette: 256 entries; 15-Bit color (BGR555) for a total of 32,768 colors.

    I feel that one of the most important things here is 15-bit color (32768 colors). So, 5 bits (32 unique vals) for each of the three color channels of RGB. This means (I believe), color values (represented in bytes, 0-255), should only ever be multiples of 8. So, "16 8 40" is a valid SNES color. This also means (I believe), that while "0 0 0" is valid, "255 255 255" isn't. "White" I assume would then be "248 248 248". Would this be right?

    Manual restrictions while painting:

    One issue I have is it's uncomfortable to draw in MSPaint using only values with multiples of 8, since I have to manually define the values myself. Normally that's not a problem, but there is the possibility of human error -- what if I accidentally draw with "214 214 214" (invalid) when I intended to draw with "224 224 224" (valid)? I wouldn't notice (and no one else would), but it would still be incorrect! Is there some method or program that supports drawing in 15-bit color, so that the tool itself would "support" the limitation, and not be "faked" manually by myself?
    Yes, GrafX2 supports this (give the /RGB [number_of_levels] commandline parameter or rightclick on the 'palette' button and adjust 'RGB scale')

    Quote
    Palettes:

    This is more of a programming question, but I assume someone else has done this, post-SNES. I'm interested in sprite palettes for a few reasons. In SNES games, it seems that sprites generally don't use over 16 colors
    Aside from cutting costs, 16 colors (minus one for transparency) is standard because that fits into exactly 4 bits (2**4 == 16), meaning exactly two pixels can fit into a single byte.
    Any 'sprite' that appears to have more than 16 colors, counting 'transparency', is probably a layered combination of 2 or more sprites.
    Modern games often don't care, and just use 8bit/256 color sprites even if they only use 16 or 24 colors in them.

    IMO 16 colors is close to a 'sweet spot' though, where you can get a nice balance of flexibility and simplicity. I suspect the actual ideal palette size is between 14 and 20 colors, according to the type of asset.



    Quote
    , and they like to re-use colors.
    This is an aesthetic and practical thing; there's no other reason than 'it looks good/consistent' and 'need to conserve color slots'

    Quote
    There are also many games where different characters use the same color palettes, so the total palettes saved is cut down.
    This is asset pruning IMO (don't have more palettes if you can have less). It improves consistency  and reduces coordination burden but isn't otherwise notable.

    Quote
    I believe I understand the theory (assuming the things I've said in this post are correct), but I don't quite understand the "how". If anyone has any information on how to actually render graphics in this indexed manner (using only indexed images is a starting point, but I'm unsure from there) and take advantage of palette swapping, it would be wonderful.
    You just take an 8bit surface (which naturally has a palette attached) and render it onto a 24bit surface. Most "game" libraries can do this, eg. SDL, Allegro. If you want a DirectX specific solution, you could look at how their Windows-specific code uses DirectX to perform that task.

    Quote
    Also, of course, the renderer could (hopefully) only support 15-bit color. (Because plain rendering 24-bit PNGs through DirectX with "manually-imposed" limitations is definitely not the same thing..!)
    This is probably not going to make any visual difference, unless you mean that the palettes would be 15bit only.  That just takes some math/ a lookup table to convert [0..255] from/to [0..31]. The blitter's palette format will certainly use [0..255].


    Changing topic slightly, what Pix3M says
    Quote
    Do not mindlessly imitate SNES sprite art
    is sound advice. However, using a colordepth restriction to help yourself to avoid fiddling around with 'meaningless' color tweaking is helpful as a general practice. I like Amiga restrictions (12bpp / 16 RGB levels) personally. The more of a novice at pixel art you are, the more benefit your art will see from using increasingly harsh restrictions.
    [/list]
    « Last Edit: March 30, 2013, 06:16:08 am by Ai »
    If you insist on being pessimistic about your own abilities, consider also being pessimistic about the accuracy of that pessimistic judgement.

    Offline PixelPiledriver

    • 0011
    • **
    • Posts: 997
    • Karma: +6/-0
    • Yo!
      • View Profile
      • My Blog
    Quote
    plain rendering 24-bit PNGs through DirectX with "manually-imposed" limitations is definitely not the same thing..!
    You can also write HLSL code to swap palettes.
    http://www.neatware.com/lbstudio/web/hlsl.html

    And knowing that it is, we seek what it is... ~ Aristotle, Posterior Analytics, Chapter 1

    Offline Ai

    • 0100
    • ***
    • Posts: 1057
    • Karma: +2/-0
    • finti
      • http://pixeljoint.com/pixels/profile.asp?id=1996
      • finticemo
      • View Profile
    Quote
    plain rendering 24-bit PNGs through DirectX with "manually-imposed" limitations is definitely not the same thing..!
    You can also write HLSL code to swap palettes.
    http://www.neatware.com/lbstudio/web/hlsl.html
    A proper swap (rather than RGB tinting) seems more complicated than you'd think, but this person managed to get it working.
    If you insist on being pessimistic about your own abilities, consider also being pessimistic about the accuracy of that pessimistic judgement.