Monday, July 27, 2015

CSG Unity plugin progress update 6

Just came back from vacation from sunny Turkey and in half a day fixed a bug that I spend a couple of days trying to fix before I left. Funny how that works some time.

The bug had to do with several brushes having a surface that lie on the same plane and where sometimes the wrong surface would be categorized as being visible, such as a surface that should actually not exist anymore because it was removed by another brush.

Now I can finally focus on merging brushes on the edges where they intersect, this should fix all the problems I'm having with gaps between brushes. I already have a good idea on how to do this, so hopefully this shouldn't take too long.

Friday, July 10, 2015

CSG Unity plugin progress update 5

So the last few weeks I've been busy fixing lots of issues here and there, making sure things work like they should etc. I still need to implement a couple of important pieces but I'm making good progress.

Here's a video that shows some of the things that the plugin can already do (one of these days I'm going to show something more interesting than a couple of simple shapes)

Finally, I've been offered a job at Unity! So pretty soon now I'll start working there and do my best to help make Unity even better than it is :)

(and this is one of the reasons why I've had so many distractions lately)

Thursday, June 18, 2015

CSG Unity plugin progress update 4 - C++ / smoothing

The last couple of weeks where really busy, once again I had lots of distractions which made it hard for me to work on the plugin. I probably have something to announce soon!
I've done a couple of things however.

First of all I've moved the actual CSG code from Unity/C# to C++. The reason for this is because the more low level optimizations I did the more it felt like C# was actively resisting me trying to optimize everything.

The more you do low level optimizations, the more it starts to feel like C++ but without all the helpful syntax such as 'inline' and with pointer juggling without all the unsafe nonsense. I was actually already working with lots of big C# arrays + indices so I was effectively already doing memory management. Moving everything to C++ actually made it possible for me to clean up the code and make it MORE readable. Not something you usually hear when you compare C++ to C#!

The whole plugin was always intended as an editor only plugin anyway, so fortunately I won't condemn myself to supporting a gazillion platforms by moving everything to C++!
Other big benefits are that I have a clear separation between the Unity part and the CSG part, I can use good quality low level profilers to find bottlenecks and I have way more low level control over memory and performance now.

While I was moving everything to C++ it also gave me a chance to revisit some parts of the CSG process and fix some issues. One improvement I made, for instance, is normal smoothing, which at the moment can only be used on polygons that share the same texture coordinate surface.

Here you can see the normals in unity's 'normal' debug view.

Another, internal, improvement is that the CSG representation is now an n-tree internally instead of a binary tree. This matches the unity hierarchy better and allows me to have shallower hierarchies which should perform better.

My focus now is to get something out there, so I'm going to fix the remaining bugs and implement only what really needs to implemented for the first version.

Tuesday, June 2, 2015

Unity editor line rendering

I created a new github repository for rendering lines in the Unity editor. It allows you to render dotted lines with different dot sizes & render multiple lines at the same time.
It uses the Unity GL class for line rendering (which is what Unity uses itself when rendering lines in the Unity editor). The dots are created in a shader in screen space, so they'll look good no matter how you turn the camera.

Thursday, May 7, 2015

Subdivision surfaces

Just got back from the states, so I still have a bit of jetlag (man I hate that). But anyway, someone suggested I should take a look at Mesh Fusion, which is a really interesting tool that does approximate CSG with subdivision surfaces.

This made me want to try to see if I can get my CSG algorithm to work with subdivision surfaces, which I never tried out. So here's my first attempt at performing subdivision surfaces on a cube mesh, about half a days work.

Next on my list of things to do is fix some t-junction issues on the final mesh that pops out of the CSG process. I need to get the whole plugin in a shippable status, after that I'll continue my research on subdiv.

Tuesday, April 14, 2015

CSG Unity plugin progress update 3 - Leaking Light

Until now I had a mesh per brush because I figured that would make it easier for the user to do whatever they want with the meshes they generate. They could use individual brushes for navigation, occlusion culling or give individual brushes different physics materials. I figured I would combine the meshes just before the game is played in the editor, or before the game is published to any particular platform.

Finally I hit a situation that clearly shows that I need to combine all meshes somewhere in the editor in real-time. This is unfortunate because I'd have to force the user to create parent objects for brushes that hold the meshes and I'm afraid this could be confusing to users when they create a brush (without a parent object) and nothing shows up.

The problems I bumped up against all have to do with Unity's lighting. 

Unity doesn't seem to like meshes being split into multiple different objects. For some reason, even when vertices of 2 objects align exactly (I checked this in the debugger), it'll cause leaks in the lighting. Maybe Unity introduces some minor floating point errors somewhere, I have no idea. Still, the light leakage is huge for seams that must be incredibly tiny (no matter how I orientate the camera I cannot see any seams, not even tiny flickering pixels). 

It is possible to get the lighting to not have seams by messing around with the light's bias parameters, but that doesn't seem like a long term solution to me. I don't want users to be force the users to spend hours messing around with lighting parameters just to make this work.

Another, much bigger problem, is that light-mapping using individual brushes is problematic to say the least. Technically it might be possible to join all brushes and force a re-bake of all the lighting when the game is published to a platform. It would cause changes in the appearance of the game between the editor and the run-time, and it would be SLOW to publish. So I'm pretty sure all I would accomplish is that I'd receive tons of hate mail and assassination attempts.

So now I'm rewriting some code so that there are these higher level components that capture all the meshes of it's child brushes and combine them in the editor in real-time. One problem is that unity would show this combined mesh as a single mesh in the editor. Select it and you select all the meshes of all the brushes that are combined in it at the same time. 

Fortunately I was already rendering brush outlines with custom code and was forced to implement my own ray-brush intersection / drag & drop code in the editor anyway, so I can actually work around Unity's limitations. It won't be pretty, but it'll work.

The silver lining is that doing things this way means that there won't be a gazillion MeshFilters, MeshColliders and MeshRenderes in the scene anymore. The brush components can also be changed into relatively simple classes that can safely be removed at run-time without side-effects. All that will remain at run-time are the meshes that have been generated by the brushes.

I was wrong! Light leakage had to do with mesh size (not the size of the mesh in world-space). Apparently the shadow bias is calculated in the mesh's object-space, but then applied in world-space? So very large mesh + reasonable bias + downscale of mesh in world space = HUGE shadow bias that causes light leakage.

I (mostly) implemented the part where all CSG generated meshes are joined into one unity mesh and got a nice speed boost as well. I guess in retrospect, uploading all these tiny unity meshes was kind of slow. (which makes sense)

... now to fix a weird bug that causes all the brushes to be re-CSG-ed every frame, non-stop. *sigh*
(good thing it's still fast enough)

Thursday, March 26, 2015

CSG Unity plugin progress update 2 - drag & drop materials

Another CSG update! Now it's possible to drag & drop materials onto the brushes, either on one surface or multiple surfaces at the same time. The video also shows procedural brushes (that can be turned into regular brushes). Meshes are generated in real-time, this is not some rendering trick.