Saturday, November 29, 2008

Entity List, and Lightmaps in Ogre

I'm going to make an effort to update this blog at least once a week, as I believe constant updates are good for showing people what's going on with the project, as a 'history' of the course of development, and also as a way for me to think out loud.

Ok, steady progress on all fronts. A few more bugs fixed/features added, including a much needed entity list (well, tree really):


This is useful because in a large map you can forget where entities are. Clicking on an entity in the list focus you on it, letting you edit its details without finding it in the world. It also faces you in its direction, so if you want to get to it, you just need to press 'forward' until you are as close as you want.

The tree uses CEGUI's Tree class, which required a few workarounds, in particular a patch to the Lua scripting module to support TreeEventArgs (submitted to CEGUI). Taking into account a previous patch to CEGUI, this means we really should start bundling CEGUI, at least until upstream releases a version containing the patches. If anyone can volunteer to help with this on Windows that would be greatly appreciated.

Also, there is progress on the experimental Ogre branch. We now have both the normal ('diffuse') textures combined with the lightmaps, giving us the correct appearance for scenery, pretty much how it looks in Sauerbraten in fact:


The current method for doing this is to generate three sets of texture coordinates, for each of the 6 orientations of a cube (opposing orientations are combined), and storing them in the buffer object. We then blend the lightmap and diffuse textures using appropriate Ogre texture units. This should probably be done using a custom shader, as eihrul explained Sauerbraten does, as the diffuse coordinates are trivial to calculate in 'realtime', in a shader.

In fact writing a custom shader might be unavoidable. As you can see in the screenshot, we have a shadow that looks different, cast by the floating white object in the center of the screen. This is a dynamic shadow generated by Ogre. While it has the same orientation as the lightmap shadows, it combines poorly with them, as the two shadow types combine (that is, by walking into a scenery shadow, you cast a shadow inside that area). The solution is to combine the shadows in a non-linear manner; a 'minimum' operation seems right, so that if either type of shadow is present, or both, you get the same shadow result (of course it isn't that simple, but that's the general idea, I think). It appears that this requires a custom shader, as standard Ogre texture units don't support this sort of thing. This is somewhat regrettable as it means either using Cg or writing separate GLSL and HLSL shaders, both approaches of which have their drawbacks. I'll do some testing to see which is better.

Wednesday, November 26, 2008

Ogre Progress

So far all high-priority bugs have been fixed for the 0.2 release. That leaves a few medium-priority bugs, and the creation of a more fun example game, which I hope to do in a week or so.

Alongside that, I find myself spending an equal amount of time on Ogre rendering, as it's more challenging. The latest issue I've been working on is shadows. One nice thing about Ogre is that, as a general-purpose 3D engine, it has various shadow techniques that you can apply with a single command. Here is an example of stencil shadows:


However, this approach would almost certainly lead to significant slowdowns, for more complex maps. So a better idea would be to use the already-existing Sauerbraten method of baked shadows, which are pre-calculated using ray-tracing techniques. After some helpful explanations on IRC by the one and only eihrul about Sauerbraten's rendering pipeline (thanks again!), I managed to get the brightness part of the Sauerbraten lightmaps to render in Ogre:


The next stage would be to set up materials that combine the underlying ('diffuse') textures with the lightmaps, giving the correct final appearance. This is not trivial as it requires processing two sets of texture coordinates at the same time, one for the diffuse texture and one for the lightmap (which should multiply the diffuse texture, thus either darkening or lightening it), but hopefully it won't be too hard to do.

The next tricky bit would be to combine these shadows with dynamic shadows for moving objects. They all need to look well together, even though they are generated by entirely different procedures. So the angles, intensities, etc. must match.

Sunday, November 23, 2008

Ogre Rendering?

Following the release of 0.1, I've spent my time doing a few fun things besides straightforward coding. One of them is that I've been looking into moving to rendering using Ogre. The main downside to this is that Ogre wouldn't be as optimized for the Sauerbraten geometry and so forth, so there would be a significant performance hit. It would also in all likelihood lead to larger executables and RAM usages.

Still, the benefits are interesting enough for me to spend a few days playing around with the code:
  • The main benefit is that Ogre is developer-friendly and extensible; adding new effects and so forth in that framework is much easier than in the Sauerbraten one.
  • A further benefit is that Ogre abstracts the underlying rendering API (OpenGL, DirectX, etc.), and includes plugins for both OpenGL and DirectX; this is of interest to me mainly because DirectX drivers are at times of higher quality on Windows. (More effort put into them by Microsoft, perhaps?) It also opens up far more feasible opportunities to port to other rendering methods (OpenGL ES for mobile devices, and so forth) - this would be quite cumbersome with Sauerbraten itself, as OpenGL code is interleaved with application code all around.
  • A final benefit, but of lower importance, is that feature-wise Ogre has several attractive capabilities, like various shadowing algorithms, multiple poses for meshes, and also that Ogre has a larger developer community around it.

In the end, it'll come down to how complicated it is to do, and how much of a performance hit it incurs. So, I set out to estimate both things. So far I have a very initial demonstration of rendering cube geometry using Ogre instead of the Sauerbraten rendering system - basically, I take the output (vertexes, triangles, etc.) of the Sauerbraten pipeline and convert it into an Ogre-appropriate form. Here is a screenshot:


It's not much to look at, in fact it is downright offensive to the eyes :) But it shows this can be done.

This was not too complicated, but not easy either. However, I am of the opinion that further integration with Ogre - lighting, models, particle effects, etc. - will be somewhat easier with this framework in place, and given that I will be using almost 100% Ogre for them (whereas here I still utilize almost all of the world geometry processing code from Sauer).

Performance-wise, this wasn't much of a test - just a simple map with a few thousand polygons. Still, it didn't reveal any immediate performance problems, so it's good enough to continue forward with.

My thinking at this point is that I'll continue to hack on the branch dedicated to Ogre, while continuing forward with the main branch alongside that. The only thing I might do differently is take care not to do any work in the main branch that might conflict with merging the Ogre branch later on (so, e.g., I won't work on a nice interface for Sauerbraten particle effects, since I might end up using the Ogre system for that anyhow).

My current goal is for a 0.2 release in about a month, which would include bugfixes and several minor but important features. I'll probably make a decision regarding Ogre around that time, and assuming I do decide to go with Ogre, then the 0.3 release might be dedicated to that purpose.

Friday, November 14, 2008

Introduction

This blog will contain news regarding the Intensity Engine, an open source platform for immersive, distributed 3D worlds.

The Intensity Engine is the product of 6 months of intensive coding, starting from a solid base of proven open source projects (Sauerbraten, CEGUI, Python, Storm, and others). We are now at the point of releasing version 0.1 and opening a public website, so people can start evaluating the project. As a 0.1 release, there are plenty of rough edges, of course, but hopefully the overall direction of the project should be fairly clear.

For more details, go the the main website, where you can see screenshots and videos, download the source or pre-compiled binaries, read tutorials and sample code, etc.

Here is a demonstration of the Intensity Engine in action:



3D models of squirrel and ram: (C) Blender Foundation; part of the the Yo Frankie! game.
Music: (C) Zero Project, "Gothic"