Wednesday, October 31, 2012

90 – Pipeline and churches

I was not in the mood for terrain streaming, so I worked on something different. There are tons of tings to implement, so I doubt I'll ever have a shortage of things to do. But I did implement a new global height interrogation API, but only with integer coordinates. When you have one single heightmap in memory, querying a height is easy. When the map is chunked into small pieces that can reside on disk or in memory, this becomes a lot harder.

I continued working on procedural buildings. The idea is to have a few randomly generated master parameters, like global shape, number of rooms, number of floors, etc. and then run a piece of code that  fully generates a new building. This works fine for simple buildings, but in order to get a really unique look for each building I need to work a lot on the generator, probably years.

So I am investigating two alternatives. One is just modeled buildings. How will a city look with traditional buildings modeled in some 3D program?

This is too easy. And I lack modelers to do the job. And all other resources. The other alternative, that I am actually investigating is taking these modeled building, breaking them into larger standalone building blocks and trying to see if I can assemble buildings like a form of LEGO.

So I started with a simple but full of personality church model I found free on the web. Here is the mesh rendered with a mix of spherical harmonics and Blinn-Phong shading, without textures: 

This is a single mesh that even has some not that great texture mapping. Her is the church rendered with a single wrapped brick texture:

It is not a very high-poly model, but I looks quite good and has a cartoony feel. Still, it has a lot of detail, so making it modular will be quite a challenge:

The first thing I did is to break the model into pieces, using Blender. I only did some elementary breaking in order to have different materials. The final breaking will have to take into account the way pieces are meant to go together. This is not done yet.

Then, in a process that took me hours, I upgraded my mesh importer/exporter to handle meshes with multiple sub-meshes. This was quite difficult  because the Model class from XNA, while apparently having a very simple and intuitive VertexBuffer layout, actually seems to be quite deceptivelly complex and counter-intuitive.

The final problem was how to make the game understand what piece what material should use. This is a pipeline issue. Pipeline is one of the most important parts of any 3D project, and my content pipeline sucks. So for now I assigned each part some random texture that is loaded:

And now from behind:

Parts of the church are under the terrain? Why is this? Remember the counter-intuitive VertexBuffer layout I mentioned? Well I am not the only one who fell into that trap. A small piece of code that I copied that only computed bounding boxes for an input mesh also had the "wrong" interpretation of the layout, generating faulty bounding boxes. This is a very weird issue. Need to investigate further.

Here is a shot after the fix:

Looks pretty good! Textures are stretched  but the general quality of the renderer is satisfactory, having all previous details. Her are two comparison shots of the side of the building with and without specular highlights:

So the next step is to break up optimally the building into parts, edit them to make sure they fit together good, and finally assign good textures, maybe even with some prebaked AO to each part and see how that looks.

After I need to test other configurations of mixing the blocks together to see if they look good.

And finally, see if the blocks can be included into gameplay. My cities won't only be procedural, but the player will be able to create though gameplay new buildings in the city.

Tuesday, October 30, 2012

So I probably need streaming

Hey, this is technically a screens/journal post, but since I managed to break terrain lighting there is no screenshot I currently wish to put out there :P. Still I have some data that I want to record for posterity.

Starting with the mention that sometimes I am stupid! My current terrain is not 2 square kilometers like I said two posts back! It is 2 kilometers wide. So that's 4 square kilometers, with 1-2 kilometers view distance. The speed calculation is still correct though.

So in my quest to reach that 10 square kilometers terrain (or maybe even limitless) I started profiling memory allocation and enhancing terrain load/save.

Now terrain is created by a new component that only has this responsibility and what it creates it always saves on disk, then it does some preparation for an eventual load of said data, then it clears up all resources.

My application starts with consuming 32 MiB of RAM. I don't know what eats up so much, ask XNA. Terrain generation for a heighmap of 2048x2048 takes this up to 65 MiB. After the save and cleanup phase,  I am left again with 32 MiB consumed RAM and a 16 MiB map on the disk. Because the maps are saved pre-chunked and I don't want to deal with non-square chunks while still keeping the game running under the XNA reach profile, a little bit from the map is always lost and the actual saved size is 2032x2032.

The saved data contains the height information, together with other useful information, like global min/max height, grid spacing, chunk bounding box, etc. After a load of the map memory consumption grows by about 16 MiB and before using the data, one can change some properties, like grid spacing, without any actual performance hit or need to process the data again.

So after loading the data, we are now ready to create the vertex data for the map in memory. This is when memory consumption jumps up to 199 MiB. Then we create the vertex and index buffer objects, raising memory to 690. 

Interestingly, BEPU is very smart about heighmap handling, and as long as the data loaded from disk is in a format it likes, it will not use any significant amount of extra RAM besides the actual height data.

Then finally after everything is loaded and prepared I am left with 777 MiB total memory consumption. Sometimes even over 800. It's over 800!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! OK, not funny  unless it is over 9000.

I did some ugly hacks, getting rid of some data and breaking device loss recovery in the process, but I did manage to get the RAM down to 620 MiB.

So this won't work.

I'll try a few things. The first solution will be to keep only basic heighmap in memory. Taking my current 4 square kilometers map and adding 3 more equal sized chunks for a total of 16 square kilometers would only eat up 64 MiB. Then I'll try to only load initially the terrain around the character, up until the fog limit. Then as I move around, I'll dynamically add and remove chunks from memory.

My guess is that this will be far too slow. So I'll probably have to add multithreading.

Monday, October 29, 2012

89 – Spherical harmonics, bitch!

Spherical harmonics was not the main thing I worked on since last time, but I have some results and I have great hopes for anything that promises to solve at least partially my lighting issues, so I'll start with it first.

Let me reiterate on the problem. Here is a barrel illuminated by one directional light from the front:

There is something funky going on with the cap and the normal map is not great, but it works. Things break apart when viewing the barrel from the back:

The diffuse contribution gets close to zero and you are left only with ambient lighting, which is dark and flat. You can make it less dark by increasing it coefficient, but it will still be completely flat. The worst part is that that normal mapping is not visible at all. Normal mapping just creates the illusion of complex geometry. Without it the object seems a lot simpler.

I tried a hacked together solution of my own, partially some light factor combination, partially some hacks, partially some trial and error. I have already shown the results of this method:

This method is pretty good, but it produces some artifacts and strangeness, especially when objects are on the move.

Now, let's take a look at our spherical harmonics based ambient lighting form the front:

Better? I think so! And now from behind:

Holly shit! Normal mapping everywhere! This techniques also allows the ambient light to be influenced by a cube map, like a skybox. When I'll have a skybox, and after I implement it, lighting should look a lot less uniform.

Right now I like the effect even better than the results of the directional light!

I owe a lot to the XNA FINAL ENGINE and the helpful people around there. Without drawing some help who knows what I might have implemented? Spherical harmonics? No way! More like cubical dingle berries harmonics!

Here are a few more objects with this rendering technique:

And a ton of barrels,a gain from two angles:

What is interesting is the ambient occlusion like effects that you can see near the bottom of the stool. I hesitate to call these artifacts.

Let's take a closer look, from the behind, where the effect is fully visible:

I think I need to have another go at the meshes, to make sure that everything is set up as it should regarding face smoothing and that those settings play nice with the rendering technique.

As said before, I did not fully implement this method and the coefficients are probably far from optimal. I can play around with them, like accentuating the lighting:

Just now I am realizing that I did all these screenshot without specular highlights. I'm not going in again and redoing them, but here is one screenshot with specularity:

So that's about it for today about ambient lighting. I need to test it, bugfix it and benchmark it to make sure it is feasible to render a whole scene like this.

The other thing I worked on is the terrain. My goal is to finish the terrain for good in about 1-2 weeks. The main problems are performance, memory consumption and terrain size.

In order to try to resolve these, I am phasing out a singular heightmap for the terrain. The terrain now gets generated, then chunked into 128x128 vertex pieces (do the math why this is the max size for the Reach profile) and saved/loaded from disk. The chunked heightmap operates slower than one full map, but it is my hope to keep the whole map in memory, but only generate geometry on the go based on what chunks are in view. There are tons to talk about here describing what I did, but since I spent so much time describing lighting, I'll skip it. I broke the terrain with the new chunker and I had to fix it:

Memory consumption is down from about 1 GiB to 700+ MiBs. A good start, hopefully I can get it down to around 512.

The terrain saving/loading is actually prototype level loading  so soon I will be able to have multiple maps and quicksave/quicklaod.

Then I improved terrain view distance while keeping performance. The view distance/fog is at its worst on high points, so let me show you a before shot from a high point on the map:

And after:

Friday, October 26, 2012

88 – Winter is coming

Hey hey! Dropbox was down for a while so I thought that I wouldn't be able to post today. No such luck! :)

Let me give you the cliff-notes of the recent developments. Lately I've been using a Twitter a lot, even though the Twitter widget broke on the blog. I need to fix it somehow.

I continued working on the world scale. This is a lot harder than it seems. I guess I need to implement a more flexible system, probably by defining a customizeable value for a meter and making the engine take that into consideration at runtime.

I also did a lot of cleanup, worked on physics and made the terrain a lot larger. The terrain is now 2 square kilometers. Unfortunately  this takes up more that 1 GiB RAM. I need to pull off some crazy magic tricks and get this way down. A 10 square kilometer max map size would be just great.

I also added fog support for a few shaders. The view distance is not that great, I'm hoping to improve on it.

But the big new feature is skiing! Have you ever played Tribes Ascend? It is similar to skiing in that game. Basically you are able to reach very high speed and use natural or artificial ramps to launch yourself in the air. Currently the maximum speed I was able to reach is 168 km/h (this may not be accurate because the world scale is not that accurate yet).

But how can you reach such ludicrous speeds? Back in the Dwarves & Holes days I wanted to write a few fluff posts, detailing every single playable race. I never gotten around to it, and I'm not sure I want this for the new concept, but if I do, I will be bringing back one of the races as the single playable race: the Mages. These extraordinarily powerful creatures from another world (that have an extensive backstory in my head) will be the star of a sandbox/RPG building game. Their almost limitless power is balanced by their huge physical frailty and long cast time for most spells. Some spells might take days to cast, but here is where time compression will come in! Obviously, in combat you won't be able tot do time compression, so you'll have to stick to spell you can cast in real time.

And this is how an mortal creature will be able to reach high speeds and ski all over the landscape: magic! To make thing interesting I'll make skiing governed by a quick-to-regenerate resources. You will also need to have skiing turned on when landing in order to prevent a gruesome death. I'm hoping to achieve a balance where you ski on the ground and look for ramps to propel you into the air, where you can regenerate your resource and reactivate skiing prior to reaching an obstacle. Add a nice rhythm to it.

Another possible power is a gravity defying stop in mid-air that also creates a shockwave. Skilled skiers might be able to land near their target and moments before hitting ground trigger the spell and throwing everything at the point of impact in the opposite direction. In my head this has a very anime feel, hopefully it will work out in game.

Why do you need a shockwave spell? Can't you just ram things? Well skiing has a gliding and force neutralizing effect. So if you ram something with skiing on, the impact will be minor. If you ram it without, you may be able to kill your target, but you will also kill yourself. Hitting something with 100+ km/h will probably explode you and your target.

A third spell that I'll add is a blink:  a short range stealthy teleport. With upgradable backstabbing. Yup, stole that idea from Dishonored! Except for the backstab.

I find skiing interesting and even at this early stage quite fun! This raises a few interesting questions because skiing is very rarelly encountered in games and I think never in a RPG. One of these questions is: do you need fast travel? For now I'm thinking that there will be fast travel for money between larger settlements and a mark & recall spell, but otherwise you'll rely solely on reaching high speeds with skiing. So no point-on-the-map quick travel.

So here is a short video with the first incarnation of skiing and some live terrain manipulation. It is a little bit jenky, hopefully I will be able to improve upon it:

Thursday, October 18, 2012

Screens of the day 28 - Someupdates

Yet again I find myself working on so many things at once, that I couldn't get a new stable and finished build. So new features/changelog:
  • Implemented basic INI file settings. C# uses XMLs more and I might migrate to XML, but now there is an INI file in the game folder that holds a lot of common settings. A lot of the in game variables are now loaded from the INI so I can tweak the game settings without recompiling the game. Also, the INI is hot-loadable, so you can edit it and the game can pick up the changes without reload.
  • Light and material information are now stored in more advanced classes, that know how to talk with the shaders and get their parameters from INI files.
  • Worked on world scale in order to give the world its final and consistent scale.
  • Implemented ray-casting picking. Using it I created an experimental system for placing items in world without having to drop them from heights. You want to have item placement as smooth as possible  Imagine that you are decorating a shelf and placing a bowl on it an this causes everything to be blown away, like sometimes they do in Oblivion/Skyrim. Not cool :). The placement algorithm also tries to place items only on relatively smooth and horizontal surfaces, so you don't end up with placements that immediately get changed by gravity. So you can't place a barrel vertically on a wall. The system is far too finicky at the moment of writing, sometimes refusing apparently smooth surfaces, other times placing items on a much too highly inclined surface. There is also now an extraordinarily ugly cross-hair for better spacial awareness when placing objects.
  • Take a look at this terrain:

Hmm, it seem to be using a single texture. Which is actually quite a good result. There are no obviously repeating patterns thanks to the shader I talked about a while ago. But why is it only using a single texture? Well I updated terrain to support custom texturing, so the texture of a zone is no longer tied to its height. Sure, I'll use this setup for initial terrain, but then you can change it. Using the cross-hair, I wrote hello on the terrain with grass:

The resolution of the terrain is not that great and texturing is tied to the resolution, so here is how the "H" looks from close up:

I think I did these screen shots without normal mapping, but normal mapping still works.
  • Terrain editing. Because of the low resolution of the terrain, I am yet to find a good algorithm to smoothly edit the terrain, but it is still doable:

You can also reduce the height of it:

Monday, October 15, 2012

Screens of the day 27 - Someupdates

Hey, been working on a lot of things all at once so I couldn't manage to get a stable build yet, so today I'll do a short preview of thing to come. Did not have time to investigate the Meteor engine this weekend, but I do have my monitor back and working.

First, I optimized a little the rendering pipeline. There is now one less CPU matrix multiplication per object and shaders are starting to get optimized for pre-shaders. Considering that for single render target shadow mapping you are rendering things at lest two times, that can mean two CPU matrix multiplications per object. I also optimized the shadow mapping part of the rendering pipeline and it uses even less multiplications than normally are needed for rendering.

What I forgot to mention last time is that there is now support for fine tuned control of render targets. You can render normally, into a new render target, into multiple, etc.

I also optimized the load order of the texture streaming system to first load all diffuse maps, the all bump maps, the all specular maps. This way even if the load time is exactly the same, loading seems faster because the more important maps are brought in with less delay.

Then I started working on model import/export. As said, loading 7 models with a total size of a few hundred KiBs takes 3.2 seconds. Unacceptable! By my calculations, a busy scene might take over 20 seconds just to load the meshes. I really did not want to resort to a custom binary format for storing meshes, but in the end I had to. I wrote a fairly lengthy mesh importer/export specially for static meshes (no bones/no animations). In the future I might add support for bone animations to the format. Here I had the opportunity to get rid of another bone multiplication. See, the exported mesh is exported weirdly and you need to take into account the first bone transformation, and also the standard loading process that I want to bypass computes normals and tangents, but again based on this bone information and... I have no idea what I'm doing! So the bone information is stored into my custom format (but animations are not) and still used because I couldn't convert the normal and tangent information into something that makes the rendered output look the same.

Anyway, loading time is now 10 milliseconds. Let's compare the two values: before it was 3200 milliseconds, now it is 10. 320 times faster. Even if I load 10 times as many meshes, it will still take only 100 ms, so I think we're done here.

And now the great advantage of my system becomes apparent. You can modify a mesh/texture and by pressing a hot key in game the assets are reloaded on the fly, without having to exit the game or reload the level. Currently everything is reloaded,  but adding support for the file modification time-stamp is trivial so I won't bother with it :).

I also further enhanced the procedural building generator, but it is still at least a week away from its first underwhelming version.

Then I tried to do something about the horrible back sides of objects that are facing away the light. I think some form of global illumination is needed, but that exceeds my current level of knowledge, so I hacked together a shader that is not particularly convincing, but still looks better and performs OK. There is just one particular graphics bug with it and currently I am not sure if the technique is flawed or it has to do something with my custom mesh import. Once I figure it out and decide if the technique is good or not, I'll list all the advantages and disadvantages.

Finally, I tried integrating XNA Procedural LTrees.

But enough word-thingies. Let's bring out the screen! First, we have a normal scene with traditional one directional light = sun lighting:

The backsides are too dark and you can't see the bump mapping. Now the after shot, with the new shader:

Better, but still not great. I need to investigate that visual bug and decide if this method is a keeper or not.

Finally, let me show you a closeup of the procedural tree:

It uses the same technique to keep the backsides from going dark, but it is not normal mapped (yet). Also, the leaves are billboards, so going close to the tree and spinning the camera around causes the typical billboard display bug.

The system comes with a few tree species out of the box but currently only one can be loaded at a time. On the other hand, every single tree is unique. It is not the same mesh repeated over and over and... I made a few tests, and generating 400 trees (not pictured) takes a few minutes and eats up over 600 MiBs of RAM, so clearly each tree can't be unique, not even on small maps.

Thursday, October 11, 2012

87 – Not slacking

While I did not manage to find time and update the blog, work continued on as normal and I uploaded two YouTube videos.

I continued enhancing the content management system and also added some content to it. All textures are now loaded by it except for grass. I could make it be aware of grass, but currently the grass system is a little bit hacky, so I'll postpone adding this until I clean up the grass system. Grass textures are still loaded with multithreading, but the content management system is not aware of them. In the first video you are about to see, terrain textures are not loaded asynchronously  but since I added this, and like I said, only grass remains to be added to the system.

Model loading with the standard XNA method is really out of control. Still experiencing the massive bottleneck, and now it needs 3.2 second to load all the meshes. A few kilobytes of them! That is absolutely bonkers. Let me check the texture folders: 86.4 MiBs. That are loaded faster than the meshes! WTF?????? I am preparing to say bye-bye to XNA's content manager and go with solutions that are blazing fast, but I am yet undecided in what format to store the meshes that is fast, flexible, un-obtuse, artist-friendly and hot-swapable. There isn't one quality OBJ loader for C# out there and I don't want to write my own.

In the next video I try to break physics by creating a ton of objects in the same place. I also show off some features of the engine, like placing objects anywhere with physics, new terrain and object shaders, mass, etc. The video is annotated, so you can follow along with the explanations:

Please excuse a few hasty textured objects. Most of the objects that I modeled using Blender are not textured. But since I am using normal mapping, all objects must have valid normals and at least semi-reasonable UV mapping or they will not render correctly. It is not about looking good: I could use completely wrong and ugly (which I did) textures. A reasonable UV mapping is needed for lighting to not freak out!

Another thing you'll notice that the sides of objects that are on the opposite side of the light are very dark. A long time ago I was but a teenager and I picked up a 3D modeling book for 3D Studio Max. That's why I am not helpless at 3D modelling and can create some low res but passable objects. But ever since the day I created my first light in 3D Studio Max, I had this problem with the back sides of objects being dark. I now believe that for outdoor scenes traditional lighting schemes don't work. I don't know about you, but I do go outside and things outside are never dark during the day. There is global illumination, light reflecting and illuminating objects from all sides and shadows are not too dark. I don't think this can be reproduced with lights. I'll try and do some experiments with some form of environment mapping based SSAO. The problem is that without any form of shading 3D objects look flat. So I need to shade them and I also make sure that the shading scheme works with normal mapping. I can't remember the last time I saw a game having this problem, so there must be a way to do it.

But back to lighting. I implemented shadow mapping. Simple shadow mapping. It look ugly as fuck. I won't even show it to you. I am too embarrassed by it. Sure, there where two problems. One was that I did not stabilize the light position to make it snap to texel coordinates, so every time you moved the mouse to look around or moved shadows would flicker like crazy. And I did not move the frustums back, so things that were behind the player or above, like roofs, did not always cast correct shadows because they moved out of the frustum. While these two are big problems, they are also fixable. What is not fixable is the main problem with shadow mapping and large scenes: aliasing. There is just not enough shadow map to go around and a texel from the shadow map was about 1/4 the size of a barrel.

This is where techniques like Cascaded Shadow Maps or Parallel Split Shadow Maps or whatever come in. I read a few research/tech papers on them and they are more complicated than SSM, so I decided to not implement them from scratch. Actually, while I plan to finish and selectively use my super duper forward rendering shaders, I am actually looking for a ready to be used solution for all my lighting needs, free or commercial.

What I am looking for must follow at least this set of requirements:
  • It must play nicely with the standard XNA environment, making code interoperability easy.
  • It must not play too nice with XNA, as in being 100% married to XNA's content manager since I am phasing it out.
  • It must be light weight.
  • It must be simple enough that I eventually can reach 100% understanding of it so I can fix bugs and add new effects and tweak shaders.
  • It must tolerate procedural generation. I do not open a visual editor and place items manually. I write code.
  • And finally, it must be fast. A low tech XNA Reach backend would also be great, but I'll write my own if needed, no problem.
Finding something like this will be hard, so I'll try everything I can find. In no particular order (OK, I am lying, this is the order I would like to try them out, but this may change): J. Coluna's LPP implementation, the Meteor engine, Ploobs engine, Sunburn engine, QuickStart engine. And maybe others. Probably I'll exclude the QuickStart engine from the list  because I started testing it and it has comparable lighting to my shaders and only SSM, plus it uses a different physics system.

So after a few hours of hacking the engine and plugging in my content management system and physics, this was the result:

This was done using J.Coluna's Light Pre-Pass implementation (J.Coluna | Game development) as a rendering engine. Shadows are still a little bit aliased, but the texel size is a lot smaller than my SSM. I did not like the SSAO effect, so I turned it off. I need to update my terrain texturing and grass animation shaders for LPP, so this is why you can't see them, but otherwise everything works fine, looks good and performs great. As a bonus, skinned animations are also implemented. So I must thank J. Coluna for making this available.  It is a very good implementation, where I just need to increase then number of cascades and find a new SSAO implementation. Even if I eventually don't end up using it, I already learned a ton from it and by screwing around with his CSM implementation, I'll surely further enhance my own knowledge.

But even here you can see the problem with the back sides of objects being too dark.

For this weekend I have a second engine lined up for testing: the Meteor Engine. This has some advantages, like more flexible shadows implementation, a SSAO that from videos seems more to my liking and even the ability to switch on the fly from LPP to Deferred Rendering. I still don't want Deferred Rendering because it is still as complicated as ever, but LPP is fine.

Unfortunately, my monitor on the machine I wanted to use is no longer working. It is in service right now and it may get fixed by the weekend, but repairing it costs about as much as half from a new monitor, so I might end up buying a new one. I might be able to set up a development environment on my laptop and try out the Meteor engine still.

The thing I've been working on the last few days is procedural buildings. There is no way I will realistically have a lot of building models for my cities. At most I'll manage to get my hands on 1 3D "tileset" that can be combined to form various buildings.

So what am I to do? Even if I do eventually get more buildings than I need, until then I am stuck with my current ugly placeholders. So I decided to invest a week or two into procedural buildings, maybe I can get an implementation going that can generate a lot of unique buildings.

Literature on this subject is scarce and lacking detail, so I came up with my own system. The idea is to take a small grid that represents the maximum size of you building. You start off with 4 points representing a rectangle (but all angles must not be square) and from here you determine 4 segments  This is the main room. Then you can further select one or more from this segments and glue to it another square, updating segment sizes and marking data on the grid. Finally, you assign meaning to each segment and try to create a mesh for it. 

First I ended up with a coordinate based system that was very flexible, but only worked in one direction, so I had to replicate it for additional directions. Then I rewrote it to use vectors and now it works for any direction.

The system is in its very early stages and I am not ready to show a video yet, but let's see some pictures:

Here you can see hundreds of procedural one room building, right now with only one doorway each. Size of building, door position and size is all random, and I plan to add windows of different sizes and shapes and then add furniture inside. Also wall patterns. Then add multiple rooms. And here you can see my biggest concern for this system: I might end up with a system that while is capable of producing each time a theoretically unique room, these rooms might end up being so similar that the human mind perceives them as identical. Too early to tell. anyway, still better than a single building copy pasted 10000 times.

Above you can see the insides of the building. There is no floor yet. Once this is done and I have enough furniture variety, a single such room should have a similar setup and item density to one of the single room shacks form Skyrim. Only 10 bazillion times more ugly.

And now let's get to the problem:

From inside, some walls are facing away from the light. You can also see the back side of building. Both are dark and lacking detail in shadow mapping. And they blend together, lacking 3D detail and looking flat. I could place a point light in each building, but I can't place on on the backside of each building.

Or could I? Maybe if I place a selective light, that only illuminates the two walls that are facing away from the light, without affecting any item near it, the terrain of the player? Lighting is so hard :(!

Tuesday, October 2, 2012

86 – Bumpy ride

Hey, I'm back from my two week long (including travel) USA business trip! I've been back for a few days and I am suffering from massive jet lag. Last night was the first night I managed to sleep. But I'll talk about my trip some other time. After such a prolonged absence I don't want my first post to be off-topic  So it is not going to be about America or my Guild Wars impressions, but about development.

This will be basically the same post (plus some recent developments) I would have written two weeks ago if my trip didn't have prevented it, but since so much time has passed I am not going to structure it a journal as I wanted, but instead go for a feature list. This has the added bonus of creating the illusion than I worked more :).

Bump mapping & specular mapping

Ah yes, the ever so elusive first half of an unified lighting system, my true goal vis-a-vis shader lighting. I finished bump mapping, but results where not that great. As you saw in the last screenshots, the bump effect was visible and seemed correct, but the end result was not that pretty. I attributed this to my poor quality normal maps. And parallax mapping seemed to work again, but I couldn't get rid of swirly artifacts. So I decided not to use parallax mapping.

This would have been my status two weeks ago.

But yesterday I got the idea to create some new normal maps using some better tools. I downloaded CrazyBump. Using the demo version I created some normal and height maps, and these did behave a lot better. The problem was that the stool at least did not look as good as back in the day when I attempted deferred rendering. That was a long time ago, long before I abandoned the Dwarf Fortress concept. Deferred rendering is such a relativity new and complicated technique that last time, while I did manage to put together a working implementation of it based on scarce resources and documentation available on the net and I did understand the principles of it, I did not truly understand a lot of the full implementation. When I tried to modify it, fix bugs and add specular mapping to it, I failed. Maybe one day I will be successfully rolling with deferred rendering, once all the kinks have been ironed out, like antialiasing, transparency, multiple materials, etc., but for now I am sticking with forward rendering. But my stool with CrazyBump generated maps was not looking as good as it did with deferred rendering.

So I came up with the idea not to generate the maps based on the textures I have, but on the height map that was specially created for the deferred renderer. And the stool now looks great! Maybe not quite as good, but very close. It is hard to tell because last time I had a lot of small lights illuminating the stool, but this time it is only one. Anyway, the shader is working and all I need now is professional height maps & CrazyBump or just professional normal maps!

But this was not enough. The main reason I stopped using deferred rendering was that I couldn't get specular mapping to work. But yesterday I added specular maps to the bump mapping shader in about 5 minutes and it looks great!

Even parallax mapping has less swirly artifacts, but they are still present. I might figure out a correct bias value, but I won't bother. I won't be using parallax mapping right now. Probably by the time DirectX 11 tessellation is common, I'll probably be rolling with parallax mapping.

Content management system

Game engines, except for rendering, are largely logistical problem resolvers, They make sure that out of a very large pool of data, larger than what can fit in memory, the right resources are available at the right time, are drawn only when needed and interact with other resources when needed, while maintaining interactive  framerates. One part of this is locating and loading the resources.

XNA uses content projects in order to locate and load all the resources. It even "compiles" the resources that are listed there, converting formats and packaging them. But for my needs this is not ideal. I want to be able to pass around the executable so that anyone can add new resources. This game will have a highly procedural nature, so I want it to even be able to create a completely new object type without having to restart the application or reload the level. Having content projects that must be compiled by artists is anyway a huge no no.

So I am creating a system that keeps track of resource locations and their use, allowing very flexible control on what is used and what isn't. With this system I can add a new object type to the engine with only one line of code or dynamically by reading some information from the disk or due to user input.

I am doing this in two stages. In the first stage textures and meshes are still part of the content project, but my content management system does not care about this. For the second stage I'll make the system loads textures from external files. XNA 4.0 removed the possibility to load a bitmap from a random file from the disk, so I've been searching around the net for alternatives. I found one and once I make sure it works, I'll tell you which one it is. For the third stage I'll make the system load also meshes from external resources.

There is an interesting situation right here. I like systems that react promptly. I hate waiting for stuff to happen. And start up time for the game is getting quite long. So I did some benchmarking, and I found that loading meshes and textures takes 2.6 second. Add to this procedural terrain generation, building and grass placement and you get to quite a few seconds. Eliminating texture loading, I got to 1.6 seconds. Loading meshes is a massive bottleneck and I do not know why. I need to figure out why this bottleneck exists.

How did I eliminate texture loading time?  Using the next feature!

Multithreaded texture streamer

Right now when the game loads up all textures are blanks. If I press a button, a new thread is launched that queries the content management system on the current status of objects, find out that the textures are missing, and proceeds to stream in all the missing texture. It is very fast, so in order to make the streaming more aparent I added a 250 ms delay after each texture load. Needless to say, the final version won't have this delay. Nor will you need to press a button to trigger texture load  These are pure development features, because I can test a lot without waiting for textures to load. Currently, the system does not require synchronization  The thread runs and gladly stomps all over the data it needs without having to use mutexes. This was intentional, but if the streamer grows in complexity, I will probably need to add mutexes and figure out a solution so that the streaming thread and the rendering thread only keep each other locked for the minimum time possible.

The game picks up the loaded textures and renders the whole scene with minimal state changes to maximize performance. I really need to add frustum culling.

New terrain texturing shader

Remember the problem I was having with terrain texture tilling? Low tiling value meant good looking distant terrain but very blurry and stretched out near terrain. Setting it to high results in good close terrain, but in distant lands there is a very apparent and disturbing tilling effect visible.

I fixed this by sampling textures twice, one time with low tiling factor and one time with high and using both values to texture the terrain. This is a compromise but pretty much solves the problem. I am currently torn between two settings for tilling, both giving good results.

I came up with this idea reading some UDK terrain texturing tutorials. They mention this problem and give a lot of solutions for it. In UDK you do everything visually, adding elements to and editor and configuring the relations between these elements, but that didn't stop me from implementing a similar idea in a traditional HLSL shader.

I'm still not done with terrain texturing. Currently  the texture is given by the height of a point. This is good for an initial setup of the map, but I want to give full control over texturing, so I'll have to expand upon the system in the future.

Diffuse wrap

Diffuse wrap lighting is a strange system, where the light given by a directional light wraps around an object. It is mainly used for (very poorly) approximating subsurface scattering. I probably won't end up using it a lot, but I did implement it and I might have a few objects that will behave this way.

With all these visually centered features, the game engine now looks a lot better. So how come I didn't show any pictures? This is because after such an absence I want to show something more impressive, and while it looks better, you'll end up still seeing the same objects. Barrels are boring  Give me a couple of days to add back all the objects I have, including trees, and I'll create a new video.