Scripting

Things are moving fast these days.

Nebula3 has a nice and generic scripting system that allows to register commands into the scripting system via a declaration in a nidl file. The only thing required to use it to write small code stubs for exposing functionality to the underlying scripting engine (Lua in our case).
A lot of the the desired functionality is contained in the application layer, and even better, accessible with Messaging::Messages, also defined in a nidl file.
Instead of wrapping all the functions and messages by hand I decided to wrap messages into scripting commands.
The compiler for the nidl files has been extended to automatically create scripting commands for selected messages and everything works nice and smoothly. Obviously it does not make sense to wrap all messages (the scripting system cannot work with complex types from the C++ side anyway), so messages that want to be wrapped are explicit tagged as such.

Additionally a new ScriptingFeature as been added that integrates this into the application layer as well and includes a quick&dirty property that allows to register a script with some functions that are to be called on specific occasion (like onFrame, onCollision, etc)

New tech!

While I’ve been hard at work with the Content Browser, I’ve also done tons of work on the rendering side. The first and probably coolest feature I’ve added is instancing, which basically lets us add model entities to the brim without giving an all to big loss of FPS. The bottle neck right now seems to be the visibility system. I have tested rendering 4000 1134 polygon models with varying results, from 30 FPS on my home computer to a solid 60 on a newer one. It seems that the rendering itself isn’t causing the bottle neck, but instead the CPU is bottle necked by the visibility system.

I’ve chosen not to use a texture nor a vertex stream to send the instancing transforms to the shader. Instead I render batches of 256 instances at a time, which basically divides the number of draw calls by 256. The reason why the upper limit is 256 is because the biggest  size an array can have in HLSL. No matter, it’s not really a problem seeing as cutting the number of draw calls by 256 for large amounts of objects takes the FPS from unplayable to fluent. I have plans to investigate the other methods in the future, but I’m holding off for the moment. The thing is that texture fetching would require 4 * 3 textures fetches per vertex in the shader, because the sampler only takes 4 pixel components per fetch, and a matrix consists of 4 rows, and each vertex needs ModelViewProjection, ModelView and Model. Vertex streaming seems to be the other viable option, and I will look into that if it’s necessary.

Oh, and if you’ve ever wondered how 4000 trucks would look like in real time in a boring grid, here is a picture:

nebulainstanced

 

But that’s not all, nono, far from it! Every shader previously written in Nody has been converted into the old .fx format. This might seem counterproductive, but it turns out that working with shaders using Nody was far from optimal, and we made the decision to just code the shaders instead of designing them. In the future I will look into how we can use Nody to accomplish this, but with another approach.

As a result, I’ve re-implemented the old tessellation shader, and we’ve also tried it using a ‘real’ model with a ‘real’ displacement map generated from a high-poly sculpt. I don’t have any images to show it, but I can assure you that it works. There is a problem though, we must use soft edges, because otherwise we get cracks in our tessellated mesh.

nebulanotessellation nebulatessellation

In the image above we have a large cuboid which is very thin. The mesh was solid and intact before tessellation, but because the normals at the edges point in different directions because of the hard edge, the tessellated result gets cracked because the normals at both sides of the edge point in different directions. As such, one cannot use tessellation with hard edges unless the level of tessellation is zero over the seam. The tessellation shader also tessellates based on eye distance, so the further away you are the lower the tessellation factor will be. Oh and before I forget, the tessellation shader also works for skinned meshes.

Not only can we do directly in Nebula, and get a feel of how the result will look, but we can also render everything in a wireframe mode, giving artists a hum of how fine the tessellation is. This, we hope, will prove useful when working with tessellated meshes. Here’s a picture of the very old eagle mesh, tessellated and rendered in wireframe for your debugging pleasure.

nebulaeagletess nebulatexprev

 

As you can see, I’ve redesigned how variables are handled and displayed. On the right you can see what variables are available for the current material. Textures can also be previewed by hovering over the icon. The thumbnail picture can be clicked on, and it opens up a file browser which lets you select textures from the file system.

I’ve also taken the liberty to add a shader which lets you animate UVs. It doesn’t work with keyframes, but instead using timing and angles. The shader has a set of parameters, linear direction which animates the UVs in a specified direction, angle which rotates the UVs around the UV shell center point, linear speed which determines the speed of the linear animation, and angular speed which determines the speed of the angular animation. With all these parameters, we can achieve rather good looking animations. It can also tile the texture in X and Y depending on the variables.

nebulauvanimated1 nebulauvanimated2

Above you can see the same object with different settings for the UV animations. You can see the tile count which is dependent on the NumXTiles and NumYTiles variables.

As you probably can see, the browser also allows you to change the light color, and also allows you to lock the global light to always point in the direction of the camera. Well, I guess that’s all for now!

 

 

Progress on the pipeline and everything else

We have been a bit slow on the progress reporting, mostly because we have been fairly busy recently. In the last few weeks/months we have been working towards our goal to create a new content pipeline that is both easier to use, more stable, and easier to maintain and extend. The first big component, the new content browser/importer is gearing towards its completion and supports importing of FBX files with both previewing, live updating, configuring of texturing, materials and physics properties.
Textures can be easily added to a project by just opening them from the importer or even just drag and dropping them into the application. Textures can be previewed, the conversion parameters can be configured and they can be easily applied to objects.

Apart from the work on the content browser, things have been happening behind the scenes, we started on a unix/OpenGL4 port and have made quite some progress there. The main showstopper at the moment is the shader system, requiring all shaders to be written in GLSL and nody to be adapted to creating GLSL shaders. Since this was more of a fun sidetrack and our game project draws closer we chose to put it on hold and focus on more pressing things instead.
The physics integration has been rewritten from scratch, this time properly wrapping the underlying physics engine (in this case bullet), making it easier to integrate other physics engine and also cleaning up the first version that was a fairly quick hack. Apart from being an overall nicer and cleaner implementation it has been integrated into the render component, making it a first class citizen of nebula and also tying it close to the graphics system. All physics objects are using the resource subsystem, properly loaded and reused/instanced. The use of bullet files as a resource has been scrapped since it cause more problems than it was able to solve, mostly due to the fairly inconsistent manner tools and plugins create the files, apart from that it locked us to the use of bullet which we wanted to avoid as well. Physics meshes are stored using native nebula mesh formats and binary nebula files, making them independent of the physics engine used.

On a positive side note, we have acquired more workforce and have a person working full time on a new leveleditor (that will combine all the old tools into one application) and will be tightly coupled to the content browser, as well as add more extensive scripting abilities.

Since our version of Nebula3 is not really compatible with the last open source version any more we figured we should probably change its name. We have some tentative working names but haven’t really decided on something final yet.