29 Jul 2007

First Render

First Nebula3 screenshot fresh from my notebook (please excuse the jpg artefacts):

It's the Tiger tank from our toolkit examples, loaded through the legacy N2 resource loaders. Visually, it's nothing to write home about of course - it's rendered using the most simple textured shader possible. But nonetheless this is a very important milestone for Nebula3 because all essential building blocks of the Render Layer are now up and running, and a simple render loop is possible. A lot of things still need to be done of course: putting the renderer into its own thread, occlusion culling, realtime lights and shadows, lots of tests and benchmarks, and so on... but once the first triangle is on the screen, the rest is easy ;)

24 Jul 2007

The Nebula3 Render Layer: CoreGraphics

The CoreGraphics subsystem is mainly a compatibility wrapper around the host's 3d rendering API. It's designed to support a Direct3D/OpenGL-style API with programmable shaders without any functionality- or performance-compromises. The general functionality of the CoreGraphics subsystem is roughly the same as the Nebula2 gfx2-subsystem, however CoreGraphics fixes many of the issues that popped up during the lifetime of the Nebula2 graphics system.

At first glance, CoreGraphics looks much more complex then Nebula2 because there are many more classes. The reason for this is simply that CoreGraphics classes are smaller and more specialized. The functionality of most classes can be described in one simple sentence, while Nebula2 had quite a few classes (like nGfxServer2) which were quite big because they tried to do several things.

A typical Nebula3 application won't have to deal very much with the CoreGraphics subsystem, but instead with higher-level subsystems like Graphics (which will be described in a later post).

Some of the more important design goals of CoreGraphics are:
  • allow ports to Direct3D9, Direct3D10 and Xbox360 without ANY compromises:
    • CoreGraphics allows much more freedom when porting to other platforms, instead of Nebula2's porting-through-virtual-functions approach, CoreGraphics uses porting-by-conditional-typedefs (and -subclassing). A port is free do override any single class without any performance compromises (e.g. platform-dependent inline methods are possible)
  • improved resource management:
    • Nebula3 decouples resource usage and resource initialization. Initialization happens through ResourceLoader classes, which keeps the actual resource classes small and tight, and the resource system is much more modular (to see why this is a problem that had to be solved, look at Nebula2's nTexture2 class)
  • less centralized:
    • instead of one big nGfxServer2 class there are now several more specialized singletons:
      • RenderDevice: handles rendering of primitive groups to a render target
      • DisplayDevice: handles display-setup and -management (under Win32: owns the application window, runs the Windows message pump, can be queried about supported fullscreen modes, etc...)
      • TransformDevice: manages the transformation matrices required for rendering, takes View, Projection and Model matrices as input, and provides inverted and concatenated matrices (like ModelViewProjection, InvView, etc...)
      • ShaderServer: the heart of the shader system, see below for details
  • improved offscreen rendering:
    • rendering to an offscreen render target is now treated as the norm, as opposed to Nebula2 which was still designed around the render-to-backbuffer case, with offscreen-rendering being possible but somewhat awkward
  • vastly improved shader system:
    • provides the base to reduce the overhead for switching and updating shaders when rendering typical scenes with many different objects and materials
    • as in Nebula2, a Shader is basically a Direct3D effect (a collection of techniques, which are made of passes, which are collections of render states)
    • ShaderInstances are cloned effects with their own set of shader parameter values
    • setting shader parameters is now much more direct through ShaderVariables (same philosophy as DX10)
    • ShaderVariations and ShaderFeature bits: A shader may offer different specialized variations which are selected through a feature bit mask. For instance a feature may be named "Depth", "Color", "Opaque", "Translucent", "Skinned", "Unlit", "PointLight", and a shader may offer specialized variations for feature combinations like "Depth | Skinned", "Color | Skinned | Unlit", "Color | Skinned | PointLight". The high level rendering code would set feature bits as needed (during the depth pass, the Depth feature would be switched on for instance), and depending on the current feature bit mask, the right specialized shader variation would automatically be selected for rendering. Together with the right asset tools, ShaderVariations and ShaderFeatures should help a lot to fix the various maintenance and runtime problems associated with programmable shaders (think shader-library vs. ├╝ber-shaders and so on...).
A few other smaller improvement of CoreGraphics vs. gfx2 are:
  • handling DeviceLost/Restored and of WinProc mouse and keyboard messages is now handled through general EventHandlers instead of being hardwired into the graphics system
  • VertexBuffer and IndexBuffer are back as public classes
  • vertex components now support compressed formats like Short2, Short4, UByte4N, etc...
  • DisplayDevice offers several convenience methods to get the list of supported display modes or the current desktop display mode, and to get detailed information about the current display (hardware, vendor and driver version info)
  • one can now actually check whether 3d rendering is supported on the current host by calling the static RenderDevice::CanCreate() method before actually opening the application window
That's pretty much all there is to know, next up are Resource, Models and Graphic subsystems...

23 Jul 2007

Nebula3 SDK - Jul 2007

Here's the new July 2007 Nebula3 SDK release. I had to do some restructuring in the directory structure because of the Xbox360 specific stuff (which is not contained of course). Compiling is much faster now because I switched to precompiled headers. Please keep in mind that everything in the Render Layer is still under construction. The next few posts will mainly describe the various Render Layer subsystems.

Have fun!

7 Jul 2007


What a delicious game! It's one of those rare cases where a great idea (evil Pikmins) actually turns into a great game. There are so many odds against such an "old-school" game-design-centric cross-genre game (most importantly finding a publisher which is willing to take the risk, usually your name has to be Miamoto or Wright if you show up at a publisher with a game concept like this...) that it seems like a little wonder to me that this little gem actually saw Gold. There must be 50 similar projects which didn't make it past the prototype stage. Go out and buy this game, something like this only happens once every 3 years or so :)

PS: I'm trying to get a new Nebula3 source release out the door ASAP. Still no 3d rendering though, there are some delays on the rendering code due to the Xbox360 work and I'm also very busy working on Drakensang at the moment.