Quite sometime ago when i started in GI tasks for Mirage, i decided to give a shot to scene voxelization methods, and hence i started in my first attempt to voxelize something in Mirage…in fact, i did not think about voxelization and voxel art before…i’m not the biggest fan, but it’s always good to try.
Anyways, after jumping into the rabbit hole, i ended up writing my own voxelization in compute, GLSL as well as HLSL translation (why i do 2 shaders, i’ll explain in the future when the time comes), anyways, not so long ago, and because C++ & HLSL is universal code that can run almost anywhere with some adaptation, and because why not! i decided to try out to adapt that voxelizer in the available engines in the market, after all, this is what is considered as “industry standards” and i need to familiarize myself to it, and neither personal engines nor in-house engines are considered “standard” nowadays…shame!
…And hence i started.
In summary, what i found about compute in those two fancy engine
– Both engines runs the compute almost at the same speed (compute is not engine related…imho…almost).
– Unreal is a bit slower (1.5 second slower than unity) in sending back compute output to consume by CPU.
– Unity is way faster in terms of performance and in terms of easy-linear-smooth API.
* Send data with 1 line, fetch data with 1 line! Where it’s never the case in Unreal!
* Unity’s mesh writing API make sense, Unreal one’s is not.
* Where Unity can send and get any types or structs, Unreal is really lacking…a lot.
* Kernel name change in Unity will result in strange behaviors, you would think it’s your issue, but naah, you need to “reboot” the engine for changes to take effect!
– Shader is 99% the same in both engine, just tiny thing needed to change in the HLSL file between my engine’s version, unity’s version and unreal’s version.
* The change in Unity’s version made NO sense, it was about a “unique” way/instruction that required by unity in order to initialize a struct in the shader.
– The stall you see is actually the CPU after the compute. Compute takes less than a second to generate the voxels data (to be exact ~4.8 ms) for all 3 meshes at both engine at the same time side-by-side but the poor CPU takes time to read the array, and use the mesh building API interface to submit mesh building for a voxelized version.
* Keep in mind, one of those meshes is super dense (the one in the middle), and as a matter of fact, it’s a 3d printing mesh version (zbrush stl or so)
– Stall is near 5 seconds for that frame where execution happens.
Frame total is 4.8s where the wait for compute task is 4.7ms (+1ms not shown in the screenshot for barrier)
If i would rate the process of making compute runs out of the box, in terms of being fun and smooth experience:
2.Mirage (my engine)
3.Any other engine in the world
4.Some more engines we don’t know about
One side note regarding Unreal, when i started the project i was on UE4.25, and few days later i figured out that 4.27 have some changes in the API that would benefit the experiment i’m working on (to be more specific RWStructuredBuffers support), so i moved to 4.27 and have to fix quite a few issues due to API differences. But with UE5 officially out few days ago, out of the box porting the project from UE4.27 to UE5.0 was a great idea!!!
All in all, it was fun to try out to do that in Unity & Unreal, and see how those engines differ from “my standard”…which is in-house and personal engine. Yet another adventure ended, let’s go back to Mirage…maybe!
The 3d models used for testing were all free, and available at those pages:
Stanford bunny: https://graphics.stanford.edu/~mdfisher/Data/Meshes/bunny.obj
Emma bunny: https://sketchfab.com/3d-models/emma-bunny-print-d2368f0e35434612bc55bf6dcc625bae