Advertisement

new image format (WIP) ... feedback wanted

Started by September 02, 2007 10:04 PM
5 comments, last by wodinoneeye 17 years, 4 months ago
okay so i had this idea for a new 2d pixel image format designed specifically for games with a primary focus toward mmo's (came up with the idea while working on the mana world project) that want to allow players to really customize their characters. i want some feedback from game designers as to how much better it may or may not be compared to a 32-bit png (RGBA). also i need some help standardizing the format so that a photoshop/gimp plugin and maybe library can be written like libpng. i think the format should be released under the gpl and be patent free. ok so here's the gist of the format. i got the idea when i was using photoshop to do some general artwork and noticed a process that i happen to use frequently when i make pixel artwork from vector artwork first made in illustrator. i would frequently copy a path from illustrator, paste it into the paths palette in photoshop, ctrl+click the path to make a selection, make a fresh layer on the layers palette and fill it with black. from there i would apply layer styles like drop shadows, color overlays, gradient overlays, or even use the black image is a mask for some under image. okay some may say my way of doing things is odd; it probably is but that's the way i got used to doing it several years ago and it just stuck. so my format idea is to use the black shape to create a piece of the artwork used by a game (definable by each game). lets say you have a character sprite of guy and you want to allow users to customize that characters skin color, hair color, pants color, etc. you would break each one of these customizable elements into a black image, that you could programaticaly re-color and then stack in a specified order (such as pants don't go under the nude base of the character but go overtop) and then make a memory snapshot in a format that could be loaded as an sdl surface or something. your probably saying i can do that already with a black png. well, there's more to the format. how can we save more space than with a png. don't get me wrong png is a tight format but i've got some ideas that will make this new format stick out abit more. here goes ... each pixel is defined tentatively by up to 7 bits, but could be as low as 2 bits. i think the format should be headerless to keep the info stored as small as possible. by headerless i mean no metadata that tells you what the dimensions of the image are, who the author was, etc. i think the dimensions of the image are implied by the actual image itself. ok so a pixel is either 7 bits or 2 ... the first bit of a pixel says whether that pixel has a positive or negative color space; or for those who don't understand color spaces from a graphic designers standpoint, does it have some level of opacity or is it fully transparent. if the pixel's first bit is 1 (positive color) the next 5 bits tell what level of opacity the pixel has; these 5 bits give us 32 possibilities, a 3.125% opacity change per step (or 8 steps on a scale of 256 levels). the human eye (at least mine) has a hard time seeing all 256 levels of transparency that a png file preserves, so this format will kinda dumbs down the image in a way that the human eye can't really tell the difference. it's a lossy form of compression but i think its an acceptable one (as opposed to jpeg artifacting). the final bit (whether positive or negative color) tells whether this pixel is the end of a horizontal row. this can allow the image to end a row of color data early if the rest of the pixels would be transparent. now to give the image a little bit of structure, the first horizontal row should not terminate early, but continue to use a 2 bit combination of 00 (negative color, not the end of a row) until it actually reaches the end of the row and uses a 01 combo, stating the next pixel is the start of a new row. also giving some structure vertically a 01 combo is used for every row that doesn't have any pixels to color, until it reaches the final row. the only other way that i can think to avoid adding structure to the image like this is to either have a very brief header (which i want to avoid) or to maybe allow game makers to define predetermined dimensions for the images based on file extension. like say a file named "0001.pants" would graphics for pants and the game designer would specify that a pants file has dimensions of 256x256 (or whatever numbers they want). i think this would be the best other way, because maybe part of the dimension definitions might also include an x or y offset, since say pants will typically occupy the bottom half of the image you could discard the top half of this new image and just specify that it start at row 128. this image data can be used to create artwork that is programatically recolored with a solid color or gradient (radial or linear), or even used as a mask for another image. anyways i think that's it ... now give me some feedback. good, bad, indifferent ... doesn't matter to me. i was thinking the format should be called the cel format, since it would primarily be good for cell shaded styled images (cartoony) as opposed to realistic.
Quote:
you would break each one of these customizable elements into a black image, that you could programaticaly re-color and then stack in a specified order

Is this the only new feature your format has to offer? This technique has been employed for a number of years using existing image formats -- it's the recoloring that is the tricky part, not defining the region that is to be recolored (although the recoloring problem has been solved for a while as well).

Quote:
i think the dimensions of the image are implied by the actual image itself.

They are not, in fact. Your image format is impossible to load without the size, which you've chosen to inflexibly store externally -- this is just a pointless and inconvient micro-optimization -- in fact most of the compression "tricks" you've described here aren't doing much better than any existing format, and they render the asset very annoying to work with.

In the content-heavy world of today's games, flexible assets are a must. Fretting over a couple stupid bits here and there -- especially at the cost of asset-wrangling flexibility -- is a good way to ensure your game costs twice as much to develop.
Advertisement
you say my image is impossible to load ... i'm not trying to be a smart alec or anything, but how so? i'm curious. you start reading the file the first 7 or 2 bits (depending on the alignment) is how the top left pixel should look and then it reads the rest of the pixels left to right until a row is terminated, and then loops until the end of the image.
You are trying to cut corners where you are not suppose to. Image size is only 2 numbers. You will save like 64 bytes. If you want to put a limit to how big it is, then use that. If you don't, then include the height + width, it is only 64 bytes...

Quote:
until a row is terminated

Using row terminators will take more space than just defining the size. (in big pics at least). '\n' is a char, so 8 bytes. Which means that 4 rows with terminators will take more space than just height x width
You didn't remove the size, then. You just moved it. If you store the row termination bit at the end of every row, you waste X - 1 bits of storage, where X is the number of rows in the image. Storing two 32 bit numbers for the size costs 64 bits, your format is less efficient for X > 65.

Alternatively, you mark only the termination of the first row (still implicitly storing the size, but trying to be clever about it). This means you tightly bitpack the remaining rows, which means you successively misalign each row by one bit every time, which makes actually loading your image rather inefficient. Now you've traded storage for run-time performance, which is even worse than trading storage for development-time performance.
this the kind of feedback i wanted. another guy i was talking to seemed to think this was a good idea and actually recommended the row termination idea. my original idea was just postive/negative color, if positive color the next 5 bits is level of transparency, else if negative the next bit is the start of a new pixel.
Advertisement
Good compression might be useful. If each player can customize and the point is to have other players see those customizations, then the server must transmit the pattern for all the other players customization to the client. That can be organized to cache on disk (so you dont have to retransmit data for people ypu see day after day) and only transmit people near you (maybe mips for further ones...).
Considering you might have a hundred players in one place (think of when you walk up to the 'bank'), the size of the custom pattern also has to be small enough to work adaquately with some median hardwares memory capacity.
--------------------------------------------[size="1"]Ratings are Opinion, not Fact

This topic is closed to new replies.

Advertisement