« first day (4808 days earlier)      last day (348 days later) » 

12:15 AM
@user16217248 In OpenGL? You cannot. That's a feature exclusive to newer graphics APIs like Vulkan/DirectX12/Metal, so far as I understand.
Even that bytecode is just an intermediate representation - it still gets compiled at runtime by the driver to match the user's hardware - it's just a cheaper compilation because the string processing has been done in advance.
You might be able to pre-digest an OpenGL shader to a shorter/simpler version, similar to the way web developers "minify" JavaScript - replacing all identifiers with single letters and such. A quick search turns up some tools designed to do this, but I don't have personal experience to endorse any.
1:13 AM
@DMGregory I assume I would use Vulkan for Linux, Metal for Mac of course, and DirectX for Windows. Though the only one I have worked with to any significant degree is Metal. OpenGL is no longer cross-platform since Mac kind of dropped support.
Well you're in luck, since all three of those support pre-compilation. You can use a transpiler to write in one shader language and cross-compile to the others (that's what e.g. Unity does).
Cool
@DMGregory So I've been wondering. If the actual compilation depends on the user's hardware, is there any way to cache the fully compiled shader code, so it will only have to be compiled the first time the user opens the app, instead of every time?
I think that would be a bad idea. Here's a scenario: your game releases. Players on NVIDIA hardware complain the characters have no eyeballs, just empty sockets. NVIDIA releases a driver patch that fixes it. All players who first compiled the shader on the old, buggy driver keep seeing empty eye sockets forever, unless they uninstall and reinstall your game. They blame you for this, and drop negative reviews/refund the game.
Are you finding shader compilation is taking a massive amount of time in states where you can't disguise behind other gameplay / animations / menu navigation? This is a somewhat unusual problem to have.
It's just, I find long loading screens annoying, and strive to get rid of them in my games. And I heard that a lot of that time is shaders compilation.
Do not design games by hearsay. Measure if it's actually a problem in your use case.
You can also fix this through design. You can find some minimal number of shaders needed for the initial interactive state of your game, and compile those first, to shorten the critical path on boot-up. Then you can prioritize the next most needed shaders, and compile them in the background while the player is already in and navigating menus/playing, so they're not adding to visible loading screen time at all.
1:30 AM
And probably the shaders for the menu screen won't be as complicated as the shaders for the 3D world. So that should keep the loading screen to a minimum.
You can also look at ubershader approaches that let you get multiple versions of a shader from a single compilation, rather than compiling each variant separately. This was used to remove hitches in some GameCube/Wii emulators.
Remember too that compiling from bytecode is faster than from raw text, so you might find it's not adding significant time to your loads at all, unless you're loading thousands of shaders all at once.
@DMGregory Is that kind of like the constantValues in a Metal shader?
Not exactly. That looks like it's still compiling variants for each one. The GC emulator solution was runtime branching in the shader (so, more expensive per pixel, but no recompilation needed when you introduce a new shader material mid-frame)
So it's a minor, but continuous performance cost, rather than a larger, initial overhead.
Bingo.
Here's an article about that issue. Note though that here we're talking about emulating hardware from the turn of the millennium on hardware from the mid-twenty-teens. The problems they were solving then may not be the problems you need to solve today.

« first day (4808 days earlier)      last day (348 days later) »