Showing posts with label lighting. Show all posts
Showing posts with label lighting. Show all posts

Thursday, December 30, 2010

Colored light

It would be nice to have colored light. For example, you could set the sunlight to something yellowish, and the sky light to a light blue.



Broville never looked sunnier.

Not only does this mean we can have green glowing radioactive ooze, and caves basking in the deep red glow of magma. The system already supports semi-transparent materials, so we can also have cathedrals with stained glass windows casting colorful light patterns onto the floor, trees with a greenish shadow,....

The downside... it costs yet more memory. It's using 74 KB per chunk at the moment, just for the light map. And there are hundreds of chunks in a scene. Once occlusion culling works properly, it will become difficult to predict just how taxing a given scene will be. I guess I'll have to dynamically change the view distance based on the current frame rate and the memory load.

Sunday, December 19, 2010

Done!

I've made the changes I talked about in the previous post.


It looks so much better than the old, per-voxel light model:




Next week: server-side Lua scripting, and maybe a first glance at the user interface.

Saturday, December 18, 2010

Minecraft level reader

Most of the framework consists of modules that can be chained together. One example is the part that reads and writes the game world to some kind of persistent storage. The default module is something that sits on top of the face-meltingly fast sqlite. (Bonus: save games are just one single file, not thousands.) And of course there's the binvox reader. But yesterday I wrote a module that can read Minecraft files, just to have some cool pre-made worlds to test with.

This module reads a Minecraft chunk, slices and dices it in 8 cubes, roughly translates the block types (far from perfect), and passes it to the server. Everything higher than 64 blocks is air, everything below -64 is rock. If the requested chunk is outside the map, it falls through to the "null" module, which does nothing. This triggers the terrain generator, which right now is a simple, infinitely large flat plain.

Today we're going to have a look around the Broville map. It is legen... wait for it... dary:






One of the problems I've encountered here is that windows don't let much light through:



The room is rather dark for several reasons.  One, the walls are 1m thick, so the sides occlude a good part of the sky outside.  Two, there's no radiosity: the light doesn't bounce around the room like it usually does.  I was planning to add a radiosity pass after I've implemented point light sources, and it should be interesting to see how much of a difference this makes.

Even the church with its big windows looks gloomy... (The trees right in front of all the windows don't help either...)



If the radiosity solution doesn't work, I guess people will have to build huge sun-facing windows and place plenty of lanterns. :P

(Minecraft doesn't have this problem; the light is always spread out across 15 blocks in a diamond pattern.)

The next step would be to convert the light map back to the Minecraft files. It would look odd once MC's own light model takes over again, but perhaps it'd be a cool addition for the static parts of a multiplayer map.


Also, check out this blog entry. Very interesting techniques! I've been toying with the idea of using geometry shaders to build the meshes, and this is an excellent demonstration of how to do that.

Tuesday, December 7, 2010

Terrain generation and lighting

The terrain generator is quite simple at the moment. It starts with 2-D Perlin noise to generate a height map. In some places, it adds 3-D noise around the surface, up to a certain vertical distance above and below (right now set to 30 meters).  The amount of extra noise that gets mixed in tapers off at the edges. The result is a world with bits of rolling hills, and bits with weird rock formations. And the occasional floating boulder.


Now something didn't go quite right, the transition between the two terrain types isn't as smooth as I had hoped.  It's easy to fix, but on the other hand, now you get all these cool faults and fissures. Hmm, I think I'll keep this glitch, but make it rare.  Keeps the game world fun to explore.

The lighting is calculated per block. From the center of each block, a bunch of rays are shot out, to see if the sky is visible in that direction.  The total number of rays that don't intersect with another block determine how much light reaches that particular block.

For the ambient occlusion, the rays are distributed in a hemisphere, to model an overcast sky that evenly lights everything. But if you add a couple of extra rays, very close together like a narrow beam, one part of the sky starts acting like a very bright disc.  So in the same algorithm, we can get ambient light, sunlight, and soft shadows. Here's the Stanford dragon again, but this time you can see how his head casts a shadow on the neck:


Ergh, that would have looked much better without the distance fog...

The first results looked promising, but had a lot of artifacts in it. A block on a hillside that has three blocks around it (say, north, east, and down) would already be almost halfway occluded. This leads to a lot of dark spots in an otherwise sunny hillside. To prevent this, there's a blur filter applied to the light map as a second step.  (It doesn't yet work perfectly at the edges of a chunk, so you will still see some dark specks:)


You might be wondering if it doesn't take ages to calculate the lighting. The first version was indeed incredibly slow. But there are some ways to speed this up tremendously. For example, you only need to calculate the light voxels that are close to the surface of the terrain. Right now, with 56 sampling rays, it runs at about 300 chunks (=16x16x16) per second on my 3 Ghz AMD64, but there's still some really dumb code in there that should be optimized. Using the other 3 cores would be an easy speed boost, too.

The speed isn't much of an issue though. It has to be done only once. And the client also generates a preliminary light map using a much faster method. Only when the server is done number-crunching it replaces it with the awesomer version. Remember that new terrain is only generated as the player explores new areas. The new chunks are far away, so the switch is not very noticeable.


Next time, water and trees. Now that the world isn't 64 blocks high anymore, we can skip the little 6-block fruit trees and plant mighty oaks and sequoias, and more importantly, build a proper tree house. There's still a limit in the current code that prevents me from generating a Na'vi home tree, but I hope to have that part redesigned next week.

Tuesday, November 30, 2010

Hey, all the cool kids are doing it

"I'm doing a (free) voxel game framework (just a hobby, won't be big and professional like Minecraft) for 386(486) AT clones." ;)

Oh you have to be kidding me, another Minecraft clone?? Well... sorta. :P  Right now the focus is to create a framework first, and use that for some games later on. I have several ideas, and a good foundation will make it much easier to explore them all. And who knows, maybe this will also be useful to someone else, so it will be open source. (Not yet, but coming soon. I really need to clean up the code a bit first.)

Most importantly, however, it's a learning experience. I have never done any 3-D programming before, and an Infiniminer-esque game is a great way to get your feet wet. :)

It's written in C++, and uses Irrlicht.  The project is still in a very early stage, but there are already a few fun things I can show you. One of my test cases is the famous Stanford dragon:



I've used binvox to generate a 512x512x512 voxel model from the .ply file.  The shadows are computed using ambient occlusion. This is much slower than Minecraft's sunlight algorithm, but I think it looks nicer. (In theory, it is possible to import a Minecraft world, recalculate the light voxels, and export it again. However, MC and Hexahedra are two different beasts, and this is probably easier said than done.)

To be honest, I am amazed at how fast it runs. Sure, I have a nice graphics card (GTX 260), but such an unholy amount of texture mapped cubes in 60 fps? Probably more if I turn off vsync? I'm sure this is old news to everybody else, but this makes me all giddy.

Next time: more about lighting, and showing off the terrain generator.