3D engine real-time lighting. How would you do it?

Miscellaneous Forums/General Discussion/3D engine real-time lighting. How would you do it?

I've been beavering away at an FPS engine for the past 3 days and I've created a sort of mesh LOD system mainly for the real-time lighting.

The whole point of my LOD system was originally for real-time lighting (plus the fact that a LOD system is bloody handy anyways for the polys).

So, to explain - I increase the polys on the meshes as you get closer to them with a dynamic light-source and reduce them as you walk away. If the player is not using a dynamic light-source (or has one switched off) then there is no need to do anything until they suddenly turn the dynamic light-source on (if they have one).

I did this as it was clear (well to me it is) that I only need higher poly-counts when close to a mesh where a light source is hitting it. I found that as the distance of the camera increases, I could drop the poly-count of the mesh with no really noticeable visual effect to the observer. In a nutshell, a mesh that is not lit and is flat (ie a wall, floor, ceiling, etc) can be low-poly as hell because it is flat.

It should be noted that my level geometry is created on-the-fly - I'm not loading geometry, I'm constructing the level, via coded data, as the player moves through it.

Anyway, just as I was basking in my glory (about 10 minutes ago) - I was taking a look at some of the Leadworks engine tests that "halo" has posted in the past and noticed he had very low polys on his walls. However, the Leadworks engine features 'dynamic volumetric lights' - I assume this would mean something like a torch, etc.

So, is he lighting the textures in some way?

My problem is that I thought I had been quite clever in realising you don't need constant high-polys to do decent lighting and overcame this with the LOD system. However, am I barking up the wrong tree here? "halo" is clearly not using high poly counts in the walls of his test level (the warehouse one with the double steps up to the windows).

Am I way behind here in my thinking - is it the norm to do the lighting to a texture?

Has anyone got any thoughts here? There must be a fair few Blitzers who have started an FPS.

How hard is it to implement a system to light textures rather than geometry? It's a concept that I don't really grasp.

I'm assuming that is what "halo" is doing as his walls are very low-poly, however, I've not seen any of his levels to see his 'dynamic volumetric lights' in use. Any Leadworks users who can check its real-time lighting on walls and also check the polys on those walls?

I don't mind carrying on with my system, but I now feel a bit 'out-of-the-loop' if I am the only person that would create a mesh LOD system for lighting when there is no need to.

I hope this post makes sense.

I would ( do ) use per-pixel lighting, so the whole question of polys is irrelevant to the way I do things. I also combine a static and dynamic lighting system in a pixel shader to get the best of both worlds.

But I have absolutely no idea what you're writing your engine in, so I'm not going to explain any further unless I know any of what I might say would be useful or relevant.

I'm using Blitz3D.


so the whole question of polys is irrelevant to the way I do things

That does lead me to believe I might be barking up the wrong tree here.

Mmm, whatever method you use, or "halo" etc uses, might be too much for me to grasp.

I purely applied a 'bullish' "puki" approach to achieve what I wanted based on the fact that so many people (in general) say that you need high-polys for decent lighting. I purely came up with my idea to overcome such a necessity.

You could explain further, however, there is a high chance I won't grasp it.

How hard is it to implement a system to light textures rather than geometry? It's a concept that I don't really grasp.

It sounds like you're trying to achieve an effect close to per-pixel lighting with only fixed-function rendering. With Blitz3D, there's not much else you can do as far as I know.

I'm not sure how the lighting in the Leadwerks Engine works, but chances are it supports some sort of per-pixel lighting technique (this means that even if your wall is a simple quad, the lighting can be as detailed as you want). As you put it, this technique lights the texture (pixels), rather than the geometry (vertices).

In other words, for per-pixel lighting, you need to use pixel shaders. AFAIK Blitz3D doesn't really support per-pixel lighting, so the only way to get around this is to just add extra vertices as you are now, or maybe a decal approach. Either way, you're never going to get the amount of realism that comes with per-pixel lighting.

Edit:
so many people (in general) say that you need high-polys for decent lighting

This only applies to per-vertex lighting techniques obviously (which Blitz3D is limited to, since you can't use pixel shaders)

This only applies to per-vertex lighting techniques obviously (which Blitz3D is limited to, since you can't use pixel shaders)

That's good news to me though, coz my system bypasses the high-polys - which is basically what the other methods are doing.

It's all new to me and I am not sure if anything I am doing is remotely standard, so I might just carry on the route I am going. My geometry is being decoded from internal data - ie:

mesh_piece=Int(chunk/10000)
chunk_calc=mesh_piece*10000
new_chunk=chunk-chunk_calc
chunk_calc=new_chunk+1000
new_chunk=chunk_calc/100
mesh_length=new_chunk-10
mesh_height=chunk_calc-(new_chunk*100)

That is basically creating a wall/floor/ceiling - I'm using what I call a 'chunk' system - the geometry is basically chunks that I encode as data and then decode on-the-fly - Well there is a bit more to the code - that is initilisation before it flies off to be constructed.

Regradless how you do it, keep in mind that pixel exact lightning also eats up quite some performance depending on the users card, even with culling. Therefore you normally just use them for important stuff. So in cases where the triangle count isn't the bottleneck you can go into the direction by increasing the resolution of the mesh instead...

The other thing about my 'chunk' system is it would appear it facilitate occlusion.

Take a basic room:

000000101613100199109901000000
120603000000000000000000130603
120603000000000000000000130603
120603000000000000000000130603
000000110603110603110603000000

This example chunk is purely storing the mesh ID's, plus the length and height of the meshes.

I'm assuming most people would use some kind of LinePick for occlusion. Well, I can dynamically alter CameraRange inside a room - ie it stays between the camera position and the wall it is facing because it knows the boundary of the room on-the-fly.

You surely could not do this with a loaded level?


EDIT:
I realise this example is not *packed* - I've posted it that way to demonstrate the idea.

Well if you're using Blitz3d then you're pretty much stuck with per-vertex lighting unless you want a purely static lighting solution ( lightmaps ) which you clearly don't.

When Halo refers to "dynamic volumetric lights" I'm not sure if he's talking about the lighting of meshes or just the appearance of beams of light through the air.

As JohnJ says, you're doing pretty much all you can do because per-vertex lighting is all Blitz3D properly supports natively. There are some libraries which add per-pixel lighting, I think, but they all seem to have compatibility issues or bugs to a lesser or greater extent. With B3D's inbuilt dynamic lighting system, the only way to increase lighting quality is to increase vertex density, and if you're going to increase vertex density it indeed makes sense to reduce it elsewhere in the scene with some kind of LOD system.

I was planning on making massive use of dynamic vertex lighting via LightMesh. However, this proved to be too limited for me - in terms of actually dynamically lighting with them seems to involve a lot of complex math to light multiple meshes as though there was one light-source.

I soon realised that creating a dynamic light with LightMesh is sort of in the realms of being equipped with a degree in math. It seemed mathmatically logical to, instead of casting light, to merely create its final product. I looked at Quake's lighting system and it is clear that the dynamic lighting, in fact, is highly inaccurate - it's just you'd never notice unless you actually take a close look.