Home   Projects   Photo Gallery   CGC Forumwww.winstons.org   

Sprites With Dynamic Lighting
Download Demo: sprite.zip

I've been working on a 2d rendering engine with dynamic lighting. I'm rendering the sprites as screen aligned quads like a standard 2d engine. However, instead of normal sprites, I have a material color map and a normal map for each sprite.

I store the scene in 3d space, but each object is represented by a sprite instead of a model. I transform the lights into screen space and use the normal information stored in the sprite to to per-pixel dynamic lighting. Essentially this really isn't any different from rendering a 3d scene with normal maps and per pixel lighting, but I don't actually have to transform and rasterize the geometry.

The downside is of course that I can't move the camera, and once you include animations, this could take a lot of memory. But there's no polygon limit. Also, this should scale pretty gracefully to run on low end hardware. I can always turn off dynamic lighting and fall back to static sprites if needed.

I'd like to try adding other terms to the sprites to use in the lighting equation. A local ambient occlusion term would be easy, and for the characters I could even assume they are standing on a flat surface at their feet when calculating it. Also material properties such as emissivemness or specular parameters would be possible.

I'm using 24 bits (8 bits per component) to store the normal information. As an experiment I tried storing x and y only with 16 bits each, just to see the quality difference. On my test sprite the difference is noticeable when you compare them side by side, but it can be pretty subtle.

The difference is more noticeable when the light is close to the sprite. You can see that the gradient is smoother on the 16 bit version. The 16 bit version also makes the assumption that the z component of the normal is always positive (towards the camera). This is generally true for the front facing pixels, but sometimes it fails along the edges (see the last image where pixels with -z are purple). I could steal a bit somewhere (maybe from alpha) to hold the sign of the z term. I'm still not sure if the improved quality is worth the increase in file size.

Demo
The demo loads a sprite file and a couple of png images with the normal and color data. Then it allows you to tweak the lighting in real time. To run, extract the zip file and run sprite.exe. Be sure to keep the directory structure intact.

You'll need GLSL support to run the demo. The GUI is done in wxWidgets and I'm using libpng for loading the sprite data.

Download Demo: sprite.zip

Texture Synthesis
I've been interested in textures synthesis for a while, but after the session at SIGGRAPH last year I had to give it a try. The basic algorithm is very simple. For each pixel in the destination image, it finds the most similar pixel in the source image, based on nearby pixels.

Source Image:

Generated Image:

Here it is tiled. I wrap the texture coords around on the result image during generation, which helps create tileable images.

My first implementation was unfortunatly quite slow. Since the algorithm is essentially a complete search of the source image, there was a lot of room to do things in parrallel. I rewrote the pixel comparison function to use SSE when calculating the pixel error. This gave a 3x speedup. Since I have a dual-core CPU, I also split the search space into two chunks, and sent one chunk to each core. This gave a very nearly 2x improvement. I also made a few other tweaks here and there.

In order to get more speed, I tried implementing an acceleration structure called a k-map. For each pixel in the source, I store the most similar pixels. Then I use this information to limit the search space during generation. With the much smaller search space, the multi-threading was no longer worth it. I kept the SSE pixel difference calculatin code though. Also, the k-map creation itself makes use of both cores. I tried a couple approaches to generating multiple pixels at once, but so far I haven't been happy with the results.

Demo
This is a rough proof of concept. It will assume you have SSE2. When it runs, it will begin generation using the supplied kmap. If you would like it to generate a new K-map, delete the kmap file in the temp directory.

Download Demo: ts.zip







All images and text on this site as well as the site itself are copyright Alexis Winston. Please do not reproduce this material or make use of it without permission.