3 ms·
I'm in kind of the same boat. I grew very disatisfied with Unity earlier this year and began looking for alternatives. I explored writing my own rendering engin
by moron4hire 6y ago
I'm in kind of the same boat. I grew very disatisfied with Unity earlier this year and began looking for alternatives. I explored writing my own rendering engine, given that my requirements aren't very high.
Back in January, I discovered this really cool .NET Standard 2.0 library for abstracting Direct3D 11, Vulkan, Metal, OpenGL 3, and OpenGL ES 3 called Veldrid: https://github.com/mellinoe/veldrid https://github.com/mellinoe/veldrid
The documentation is pretty good, for its own parts, and it has a fair number of examples for setting up things like different windowing libraries. I was able to put together a set of code for a single demo running in Windows Forms, WPF, and Xamarin Forms fairly easily. It also has support for SDL2.
Currently, I'm going through a Codevember exercise where I teach myself WebGL from scratch.
From what I've learned so far, most of the graphics APIs these days work in very similar ways. And Veldrid polishes over the few differences (esp. in the case of OpenGL). WebGL does, too, in that they present an OpenGL front-end, but the back-end can be implemented in different graphics APIs (for example, on Windows it's actually implemented in D3D 11 through ANGLE).
In general, you need to create a Shader Program--which is a combination of multipe Shaders of different types, e.g. Vertex, Compute, and Fragment--construct one or more Buffers to which you will load data (generally in a big, ol' smash of data), and configure how ranges within those Buffers will map to pointer locations within your Shader Program.
However, I've generally found that there is little documentation anywhere on how to architect a data pipeline to use all of the various GPU resources efficiently. Everyone talks about "use as few draw calls as possible". But they don't really tell you how to achieve that.
My feeling is that a Shader Program is loosely analogous to a Material in something like Three.js or Unity. I'm guessing that the ideal approach is to take all of the Meshes in Three.js, or all of the Renderers in Unity, that have all of the same Materials, and then combining their Geometries into a single block of memory. And that's where Uber Shaders come in, as an attempt to also combine all of the different ways in which you'd want to render different Materials into a single Shader Program.
- midnightclubbed 6y agoCombining meshes will reduce the cpu usage hugely (assuming you are talking about hundreds of meshes) but you may end up sending lots of offscreen geometry to the Gpu. Depending on your scene this may or may not be an issue. Some engines will do this behind the scenes or use indirect rendering (which gives the speed benefit of combining meshes without you manually combining). You should also be careful of monolithic Uber shaders especially if they branch as shader divergence can really kill gpu performance on some hardware. There is no one solution, just the one that best fits your usecase, hardware and coding time budget.
- moron4hire 6y agoThanks. My requirements are pretty low, but I need to run on some pretty low-spec hardware, with VR multiview. Right now, everything is in WebXR, so perf is about half of native. And if I'm on a non-Oculus standalone headset, the only browser that is available is Firefox Reality, which has some perf issues of its own. There should be enough perf to run everything I need in this setup, especially of I can get some of my loading and texture transform ops running in Workers (again, with Firefox being the pain point here). But with dynamic content loading over the 'net and teleconferencing and corporate authentication and general Unity update fuckery, it just got to be too much to manage. A lot of my users can't have Facebook accounts, so I need to support as many other headsets as possible, and Unity's tooling for that is way too constantly-in-an-ever-shifting-landscape-of-broken. With OpenXR starting to really take off, and upcoming .NET 5 promising much more robust multiplatform support, I might be able to go back to .NET with Veldrid. Though I'd still have the teleconferencing and authentication bits being a lot harder to pull off outside of the browser, and having a native app would mean we would have to deploy through the Oculus store, which I definitely don't want to do.