Skip to main content
gamedev.net
🔒 Locked

Graphics Optimization Help

Started by leif_dragon Dec 12, 2008 at 12:07 AM 2 replies 1k views
Original Post
leif_dragon
leif_dragon
Hey all. I've been developing a dynamic lighting system for the 2D space game I am making. I have tried out a number of methods to achieve the proper effect. The goal is to have multiple light sources that cast a light, which is then used to render a normal mapped image for my space crafts, asteroids, etc. I've tried 3 different methods of rendering so far. 1. Get the normal mapped argb values, draw them on a separate blank image, and then simple draw the ships image, and then the normal mapped image (which is roughly half transparent) to the screen. Thus giving the effect of a proper normal mapped image. 2. Get the normal mapped argb values, combine each value with that of the corresponding ship image's argb value for the particular pixel. Draw each combined pixel value to a new rendered image, which is then drawn to the screen. 3. Get the normal mapped argb values. Draw the ships image to the new rendered image (java, bufferedImage), then set the alpha composite to 50% and draw the normal mapped image on top. The result ends up looking something like this... Photobucket All of these methods require the program to run through each pixel in the heightMap image in order to calculate the correct normal mapping value for each pixel (This is if there is only 1 light source by the way). This sadly is not very efficient. So my question is,... is there anyway to optimize normal mapping? Is there a way to get hardware support for this sort of thing?
spek
spek
If I understand correctly, you draw each pixel yourself (I mean, no OpenGL / DirectX used here)? I'm not into Java, but probably you won't use any hardware acceleration at all in that case(= slow). If this is the case, I strongly recommend you to look into OpenGL for Java or something like that.

Anyway, I don't quiet understand why should loop through all normalMap pixels per screen-pixel. Let's say you want to draw an asteroid somewhere on the screen (a sprite). Basically you draw a bitmap at a certain position:
for x:=0 to bmp.width-1 do   for y:=0 to bmp.height-1 do     screen[x + sprite.position.x, y + sprite.position.y] := bmp.pixels[x,y];

Now, before drawing this pixel to the screen, you'll have to modify it with the light(s) first. Basically this is what a shader does, but then on the GPU instead of CPU. You can pick the corresponding normalMap pixel from a second "normalMap" bitmap that belongs to this sprite. Unless you want a tiled normalMap, you can use the same texture coordinates that you use for picking the asteroid/spaceship image pixel. With this normal, you can calculate the diffuse term(s):
for x:=0 to bmp.width-1 do   for y:=0 to bmp.height-1 do    begin       // get pixel data      imagePix   := imageBitmap.pixels[x,y];      normalPix  := normalBitmap.pixels[x,y];      resultPix  := RGB(0,0,0);      diffuseLight := RGB(0,0,0);      // ... you can also add a specularMap here           // Simple Diffuse lighting for each lightSource that affect this sprite      for z:=0 to lights.Count-1 do          // Compare the normal with the light direction          // I assume that both normalMap pixels and light directions are both          // in world-space          vector3 diffuseTerm := dotProduct( normalPix, lights[z].direction );          diffuseTerm := max( 0, min( 1, diffuseTerm )); // make sure its 0..1          // Add to the result           diffuseLight.rgb := diffuseLight.rgb + lights[z].color * diffuseTerm;          // Eventually you can add attenuation or specular lighting here as well       end; // for z            resultPix := imagePix * diffuseLight;      // Now draw the modified image pixel on the screen, the result      screen[x + sprite.position.x, y + sprite.position.y] := resultPix;   end; // for x/y


This code demonstrates how you could do it via the CPU per pixel. Nevertheless, its still slow if you process every pixel via the CPU. That's why they invented video-cards and GPU's :) Maybe I understood you wrong and you actually are using the hardware to draw. Well, the principle of normalMapping with 1 or many lights stays the same. However, looping through a variable number of lights is more difficult with shaders since shaders don't like dynamic loops.

Greetings,
Rick
Andrew Kabakwu
Andrew Kabakwu
I believe if you use Volatile images in Java you get hardware acceleration.

Google "java volatile image"

I got the following -

Google Result
leif_dragon
leif_dragon
Thanks for the replies guys. Yeah I think you definitely have good points. I will test my image use, with images loaded to volatileImages to see if there is a performance boost. And I believe shaders are exactly what I have been looking for. For some reason I believed that I would be able to run java code through a gpu, but now I realize that I wasnt thinking. Thanks for the heads up :)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.