Hardware per pixel lighting (2D)

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
__count
Posts: 22
Joined: Thu Mar 23, 2006 8:40 pm

Hardware per pixel lighting (2D)

Post by __count »

I am making a sidescrolling 2D game and I'm trying to do per pixel lighting. Reason: vertex lighting wouldn't look very nice since my vertices can be far apart and aside from that I'm rendering in screenspace right now so it would be hard to implement.

What I've come up with is to create an extra 8 bit framebuffer, one that is palettized to a grayscale palette. Then for each light I render a light texture (which is basically a sphere) to this buffer (additively). Afterwards I render a fullscreen quad with this light buffer set as texture and the texfunc set to GU_TFX_MODULATE.

example light texture (point light)
Image

Problem: you can only render to a 16 or 32 bit texture.

Could I still do this by treating the light buffer as 32 bit? Then each color component (R,G,B,A) would just be a different light pixel. So I would actually store 4 pixels in 1 light buffer pixel as well as the point-light texture (see pic).

The main thing I don't know about this setup is if the Alpha component of the light buffer will get proper additive blending. In other words is each component treated the same or is Alpha a special case?
Last edited by __count on Wed Sep 13, 2006 8:52 pm, edited 1 time in total.
__count
Posts: 22
Joined: Thu Mar 23, 2006 8:40 pm

Post by __count »

Some pics to clarify what I'm trying to accomplish

The frame as rendered so far
Image

The light buffer, rendered using multiple point lights (using texture in 1st post)
Image

Result
Image
chp
Posts: 313
Joined: Wed Jun 23, 2004 7:16 am

Post by chp »

One problem with treating the light-buffer as 32-bit is that you could only offset the buffers for every 4th pixel which would become quite choppy unless you have 4 different textures covering those cases (and you can forget about subpixling, scaling lights, etc).

Alpha is probably not included in the blending operation. But, if you use modulation on the texture you can blend together colored lights instead of sticking to the standard greyscale.
GE Dominator
chp
Posts: 313
Joined: Wed Jun 23, 2004 7:16 am

Post by chp »

A different approach could also be to use a fixed grid that you render your background lighting to with a rather high resolution, then you don't need any fixed textures and you could also use both spotlights and pointlights with specular shading.
GE Dominator
__count
Posts: 22
Joined: Thu Mar 23, 2006 8:40 pm

Post by __count »

chp wrote:One problem with treating the light-buffer as 32-bit is that you could only offset the buffers for every 4th pixel which would become quite choppy unless you have 4 different textures covering those cases (and you can forget about subpixling, scaling lights, etc).
Good points... also I think you'll need 16 different textures since both x and y will be 'choppy'. All the more reason to reject the 8 bit as 32 bit framebuffer thing, I suppose.
Alpha is probably not included in the blending operation. But, if you use modulation on the texture you can blend together colored lights instead of sticking to the standard greyscale.
The main problems with a 32 bit light buffer are

a) costs 544kb of (V)RAM (you have to alloc 512*272*4 byte)
b) I expect it will make the fulllscreen quad render very slowly since the lightbuffer is now huge and it won't be swizzled

But maybe if I render to sysram and swizzle it each frame the overhead would be managable...
Last edited by __count on Thu Sep 14, 2006 12:15 am, edited 1 time in total.
memon
Posts: 63
Joined: Mon Oct 03, 2005 10:51 pm

Post by memon »

If your lights are in general smooth shapes, then you could easily render to 120x68 texture and then render that on top of your current framebuffer.

I have no experience how the destination alpha is handled when rendering, but if additive works there, then you should be able to handle the lighting using the destination alpha and use sceGuPixelMask to mask write to alpha channel.
__count
Posts: 22
Joined: Thu Mar 23, 2006 8:40 pm

Post by __count »

I'm not 100% sure but I think the framebuffer alpha will be used for the stencil buffer, even if you're rendering to texture since the GE doesn't really differentiate between the two.

Making the lightbuffer smaller is a good call... I could use floats in the vertices to get subpixel precision preventing the 'choppy' problem. With bilinear filtering on the FS quad you shouldn't see much of a difference.

Thanks to both of you for the great input.
__count
Posts: 22
Joined: Thu Mar 23, 2006 8:40 pm

Post by __count »

Yay, it works :)
Image
I use a 256*256 32 bit texture as light buffer which gets stretched to full screen.

By the way: the framebuffer's alpha DOES get filled, provided you use GU_TCC_RGBA with sceGuTexFunc.
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

could you post a zip file containing the source code of your test ? it looks very interesting.
Post Reply