1
\$\begingroup\$

I'm building a C++ based game engine, and I have my ECS complete as well as some basic components for stuff like graphics & audio. However, I'm currently using a custom interface on top of SFML with GLSL based shaders and OpenGL based graphics. I'd like to switch to a graphics solution where I can switch between OpenGL, Vulkan, DirectX3D, and Metal without rewriting large portioins of my code. The graphics API itself isn't a problem, since I can easily build an interface on top of it and reimplement it for each desired platform. My issue, however, is with the shaders.

I'm currently writing my test shaders in GLSL targeting OpenGL. I know I can use the SPIR-V translator to generate HLSL/MSL/Vulkan-Style GLSL from my OpenGL source code, but I'm not sure how that will work when I start having to set uniforms, handle shader buffers, and the like.

The big solution I've heard of is generating shaders at runtime, which is what Godot does. However, my engine is very performance-oriented, so I'd like to precompile all my shaders if possible. I've also seen that Unity uses HLSL2GLSL translator and SPIR-V cross is very common. However, I'm worried about how these will interact with setting uniforms and whatnot, and I'm very concerned about their impact on performance.

\$\endgroup\$
6
  • \$\begingroup\$ Unity precompiles every possible shader needed by your project when you make a build (there's a cache, so it won't recompile them every time you make a build if nothing's changed). \$\endgroup\$
    – Kevin
    Commented May 4 at 19:47
  • \$\begingroup\$ @Kevin That makes sense. I'll remove that from the post. \$\endgroup\$ Commented May 4 at 20:05
  • 1
    \$\begingroup\$ Why would using a shader transpiled with SPIR-V Cross (or similar) have a negative performance impact, or make it difficult to set uniforms? Can you explain the specific problem you've observed here? The more precisely you identify the issue, the better we can help you address it. \$\endgroup\$
    – DMGregory
    Commented May 7 at 15:22
  • \$\begingroup\$ @DMGregory To be clear, I was worried about whether or not they'd impact performance, since I couldn't find any info online. With further research, it seems that isn't an issue. My biggest issue is, if I have a .setUniform function for my GLSL code, when I compile that to SPIR-V all the identifiers melt away, and I don't see a way for SPIR-V Cross to "remember" those identifiers, thereby breaking my set uniforms on other platforms. That's kind of a noob question, since I'm sure a standard answer exists. However, I wasn't able to find one. \$\endgroup\$ Commented May 10 at 0:52
  • \$\begingroup\$ "However, my engine is very performance-oriented, so I'd like to precompile all my shaders if possible" Why do you think that impacts performance? Shaders will be compiled on app startup according to the config set by the user. That has no performance impact on the game during runtime, whatsoever. \$\endgroup\$
    – Engineer
    Commented May 11 at 0:02

2 Answers 2

1
\$\begingroup\$

I'm writing my current project entirely in WebGPU and WebAssembly. WebGPU knowledge and code is portable to C, C++, Rust etc via lib wgpu. I prototype code in JS, using it for things like UI and assembling shaders dynamically. As project gets heavier, I replace performance-critical sections with C, Rust or AssemblyScript compiled to WASM modules, or push that load off to WebGPU compute. With Websockets, WebRTC for multiplay, one can go further.

If you want desktop support, compile to standalone executable using Electron or similar. Besides desktop platforms, WebGPU is also slated for Android and iOS (indeed there have already been some early releases). Arguably the most cross-platform non-propietary tech stack in existence.

To me it's a modernised, pleasant GL environment that is a huge step up, organisationally and performance-wise, from WebGL. Not saying without it's issues, WebGPU's still a work in progress.

\$\endgroup\$
1
  • \$\begingroup\$ Thank you for the answer! WASM/WebGL isn't going to work for my project, but this is a great solution in general--especially if you're using Rust (which has wonderful web support). \$\endgroup\$ Commented May 12 at 21:02
-2
\$\begingroup\$

The best option for this is DiligentEngine. DiligentEngine is a cross-platform, high-performance graphics API that's as low level as something like OpenGL, Direct3D, Vulkan, OSXMetal, iOSMetal, or GLES. However, it's compatible with all of those and, with the fully open source core library, possible to re-implement with PlayStation & XBox SDKs without rewriting all your graphics code. It handles uniforms & shader pre-compilation and cross-compilation for you. It works with C++ & .NET out of the box, and .NET bindings are available with NuGet. Unfortunately, it's very difficult to set up with C++ (but the results are worth it).

\$\endgroup\$
2
  • 1
    \$\begingroup\$ This answer is written like an advertisement. Note that their GitHub repo says you need a commercial license to use the Metal APIs. \$\endgroup\$
    – Kevin
    Commented May 10 at 18:40
  • \$\begingroup\$ @Kevin You can use MoltenVK or the like on MacOSX as well, to circumvent that. It's not an ad, it's just the solution I came to. I'm 100% unaffiliated with DiligentEngine. \$\endgroup\$ Commented May 12 at 21:01

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .