Octree-based voxel lighting system

Started by
14 comments, last by dougbinks 10 years, 4 months ago

Hi!
I'm creating a voxel terrain engine for my game in Unity, but I don't know, what's the best way to implement lighting. I wanted to write it as it is in Minecraft - CPU calculating light for each vertex and then shader multiplying output color by this value, but I've got octrees implemented, which means that one faces are big and other ones are small, which is a major issue when creating per-vertex lighting. I wouldn't like to have to divide bigger faces to get the lighting resolution I want, because then octree rendering optimizations lose their sense. Is there a way to overcome it? Using unity lighting would mean that I have to buy Unity Pro (which is too expensive for me) to make shadows and deffered rendering and I wouldn't be able to tell how dark it is in a certain place on the map. And of course real-time lighting would mean a major performance drop, which I cannot afford. Please help if you can. confused.png

Advertisement

Instead of applying the light to each face of a object you should apply the light to the pixels of the textures by using a per pixel shader.

Unity uses DirectX so you will need to use HLSL.

Is there a way to do this once and not every frame? (I don't know, a lightmap or sth.)

Is there a way to do this once and not every frame? (I don't know, a lightmap or sth.)


How come? Per-pixel lighting is ran on the graphics card and the graphics card is a parallel device which means it's fast at it.

*EDIT* Oh wow, didn't read the follow up post. *EDIT*

Don't pre-optimize things like lighting, make a demo for it and see how good your implementation is first.

I tried directional light, but it makes a lot of consrast between a top and a side face of a block, when I set ambient lighting to light-gray it's okay, but then caves are not dark. I use shadows to darken caves otherwise the top faces in the cave are exacly the same light as ones on the surface. So, how to make surface well lit and caves dark?

HEY, PLEASE! CAN ANYONE HELP ME?

It's one of those "if you have to ask ...", but...

I'm creating such an engine right now, there are a few options for you:

1. use shadow maps - probably ok - some minecraft mods use this, and it's neither good nor bad

unfortunately shadow maps requires you to run a "shadow" rendering scene pass, which means you halve your fps for nothing at all

when you could instead be using the second pass to render water reflections for which there is no alternative but to actually render everything at plane reflected position/angle

(this one is most likely the easiest way for you to get shadows, so if you just want to get from A to B fast - consider shadow maps)

2. use "vertex lighting," meaning you append data to your vertex struct (im assuming you at least have this)

and using this additional data you can add shadows, brightness & lighting to each vertex on the field

the good part is that you can use each individual channel as part of a composite light value, let's say R = shadow, G = brightness, B = corner shadow / fake ao

then you can make up simple rules to achieve realtime daylight and blabla, and since corner shadow is its own parameter you can ramp it so that its a very thin black line

3. deferred lighting - won't scale at all, takes time to implement, and means you have to spend lots of time isolating chunks of your world just to keep the light count down

in a voxel world you with actual players you typically have a few thousand lights, sometimes all visible

i should know, i have testers who routinely push the boundries (and being the yes man that i am, routinely work out ways to make things ever faster)

yes, im probably telling you directly to use vertex lighting

but maybe not.. its up to you what kind of scale you want to achieve.. i dont even know what kind of game you are making :S

its hard to tell you for sure what you should do

is your world 3D? as in not a glorified plane like every other game in existence

Yes, my world is 3D! :-)

It's a voxel terrain engine (as for now, later i'm gonna create a game using it). It uses octrees instead of clearly homogenous space to conserve memory and remove unseen vertices. Well, vertex lighting is what I intended to do, but the problem is that some faces are bigger and other ones are smaller, so there's no consistent vertex count per any map resolution level, so if we place a light, say, above a 8x8 meters surface, there's no way I can spread lighting across the face with only 4 vertices! :-) I thought about it for a while and found possible solution: the light can be calculated when building chunks per smallest possible voxel (vertex lighting like in Minecraft) and then, instead of subdividing bigger faces (which makes octree optimizations a non-sense), let's programatically create a lightmap texture, using per-smallest-voxel calculated values and map it to bigger faces as TEXCOORD1.

Crazy idea, isn't it? smile.pngsmile.pngsmile.png

Is this solution possible or there's sth. I did not think about?

i dont know, it does sound kind of ridicolous to create 3d lightmaps? maybe it works out.. i dont know

honestly, why dont you just subdivide faces where the lighting changes?

just because your actual world data is an octtree doesnt mean your mesh is :P or does it?

i thought about it once, i think, but i didnt try it.. and i dont know much about how minecraft does things :P

i hope it works out for you

This topic is closed to new replies.

Advertisement