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:
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.
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.
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.
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!