Updates, Updates, Updates!

Oh!

Hello, there…

I… I wasn’t expecting any visitors…

Are you sure you’re not lost?

No?

And you want to know what’s new with Crimild? Really?

You want…

Updates?

Are you sure?

No, no, no. The project is not dead. Far from it. I was just too lazy busy to write about it.

Ok, then.

Let’s find some updates for you…

I’m sure I saw some of them around…

Ah, yes! Here’s something new:

Yes, Crimild has a new editor!

(because the old one sucked, to be honest).

The new editor is still in its earlier stages, of course, but it already includes features like a 3d scene where you can manipulate objects, a simulation panel that can be paused at any time, an inspector for modifying things like node transformations and components, and a hierarchy view where we can organize our scene. And there’s a file system panel too for our project, but it doesn’t do anything special right now… Sorry project panel, better luck next year.

And yes, I’m using ImGui for all of the UI rendering. ImGui made things a lot easier and there are already great extensions for graph-based editors and transformation gizmos, which I’m also taking advantage of.

Speaking of graphs, there’s a Behavior editor too:

Behaviors are stronger than ever with this new tool. But what about scripting, then? Well, I ended up deprecating all Lua scripts in favor of this visual programming-like paradigm, much like other engines are kind of doing too.

The one thing that made all this possible was Crimild’s ability to encode/decode scenes (and other kind of objects) directly into binary format. This was used not only for saving stuff to disk, but also in more subtle ways like when a simulation runs and we need to duplicate scene nodes.

But wait! There’s more!

You’ll be happy to know that, on the rendering side, there’s an improved Vulkan renderer (or renderers), which is much simpler than the first iteration I made last year, completely isolating rendering code from simulation. There are also enhanced shadow mapping techniques, too.

You want more?

I’ve modernized all CMake configurations files. Yes, I finally did it! I know, I know, I should have done this several years ago…

Finally, I’m using Github actions now, compiling the project to several platforms whenever new PRs are created. Now there’s no excuse for failed tests. And I’m also using Github Projects instead of Trello, which integrates better with the whole ecosystem.

Well, that’s it.

That’s all I have…

For now 🙂

Happy New Year!

PD: Did you know that Crimild turned 20 this year?

Hello ImGUI!

I’ve been wanting to add support for ImGUI ever since I started the Vulkan branch about a year ago. To be fair, ImGUI is a pretty easy library to use, yet it depends heavily on dynamic buffers which is something that the new rendering system in Crimild was not providing…

Until now.

Making things more dynamic

ImGUI works by recreating the visual geometries every frame. Which not only means that it depends on dynamic data, but also in the ability to record a new set of rendering commands every frame, which wasn’t supported by the new rendering system at all.

I think I mentioned this before in other posts: the current frame graph implementation in Crimild is static. That is, you create a scene and define which render passes will be used at the beginning of the simulation and then the engine assumes that things won’t change later on. That means nothing can be added to or removed from the scene or frame graph. If something changes, we get an undefined behavior (or more likely, a crash).

A static frame graph might be good enough for demos but it’s definitely not how things are supposed to work in more complex projects (specially games) where new objects are created and destroyed all the time. This has been a known constraint so far, one that made things a lot simpler for me at the beginning. But the time has come to finally remove that limitation for good.

Firstly, Uniform buffers have been dynamic pretty much since the very beginning. Otherwise, no camera will work at all and objects won’t move. They are updated, if needed, just before rendering (there’s still room for optimizations, though). Then, I added support for dynamic vertex buffers when revisiting the particle system a couple of months ago. That should deal with dynamic data, right? (spoiler: no, it doesn’t)

What about command buffers? They are recorded once when creating render passes and then never change. That’s not what we want, so I made some changes here and there and now render buffers have a callback that returns the command buffers every frame. The render pass is completely free to either recreate command buffers or memoize them in order to avoid duplicating the work.

But then, I ran the simulation and the result was not the expected one:

Something else was missing.

It was clear to me that the dynamic buffers were working because the frame counter was being updated as expected. And I was able to add/remove panels, which indicated that command buffers were updated too. What was missing, then? It took me quite a while to find the problem (which is a clear indicator that I need better debugging tools). While uniforms and vertices were being updated, index buffers were not. I assumed that was already supported but it turned out it wasn’t.

Once I figure out the problem, fixing it was pretty easy and then I finally got the correct result.

Handling events

Rendering was fixed, so the next step was to forward mouse events to ImGUI. And that was really, really easy. A few minutes later I had a fully working UI:

Closing Comments

As expected, working with ImGUI was really easy since it’s a very well made library. The problems I have along the way were due lack of support of some the requirements. it’s worth mentioning that ImGUI does provide bindings for Vulkan (and other graphics libraries like OpenGL) but I couldn’t use those since they were not compatible with Crimild. Otherwise, the process would have end up even easier.

See you next time!

A More Correct Raytracing Implementation

Happy 2021!!

I decided to start this new year continuing experimenting with compute shaders, specially raytracing. I actually managed to fix the issues I was facing in my previous posts and added some new material properties, like reflection and refraction.

My implementation uses an iterative approach to sampling, computing only one sample per frame and accumulating the result in the resulting image. If the camera moves, the image is reset (set to black, basically) and the process starts again.

Here’s a video of the image sampling process in action:

You might have noticed that the glass sphere in the center is black whenever the camera moves. That is because, if the camera moves, number of bounces for each ray is limited to one in order to provide a smoother experience when repositioning the view. Once the camera is no longer moving, bounces are set to ten or more and the glass sphere is computed correctly, showing proper reflections and refractions.

Here’s another example:

In the example above, you also see the depth of field effect in action, which is another property for the camera that can be tuned in real-time:

In this case, the image is reset whenever the camera’s focus changes.

I’m really happy with this little experiment. I don’t think that it’s good enough for production yet, since it’s still too slow for any interactive project. But it’s definitely something that I’m going to keep improving whenever I have the chance.