In graphics applications, why do shaders get loaded into the application on runtime?
c++, glsl, opengl, performance, shader
Solution
A few reasons:
- During development it's very convenient to 'hotload' shaders without restarting the application so you can make changes while debugging or performance tuning and instantly see the results. This is simpler when shaders are stored as separate files.
- As mentioned in the comments, depending on your platform it is common to precompile shaders from a high level shading language to an intermediate byte code representation or to actual final GPU code (e.g. in the case of consoles where the GPU hardware is a fixed target). Shader compilation can be quite time consuming so it is better to do it offline rather than at runtime when possible.
- The approach you take is actually not uncommon in small / simple applications, it becomes more painful the bigger your app gets and the more shaders you have to manage. Personally I like to be able to hotload shaders even on small personal projects.
- This is actually a more general question than just for shaders. In any project you have a choice of when to embed resources in the executable (either directly in source code or through a separate build step like Windows Resources) or store them as separate files. There are pros and cons to both approaches but the main advantage of embedding is that all the resources an app might need are embedded right in the executable so you don't have to worry about / deal with potentially missing resources. The downside is that if you cram everything into the executable (especially for a project with many large assets like a game) then you increase build times, make hotloading difficult and can make the problem of asset organization more difficult.
Problem
Shaders written in for example GLSL are typically loaded into a graphics application at runtime. I am wondering why not just compile the application with the shaders so they will not have to be loaded later. Like this: ``` #define glsl(version, glsl) "#version " #version "\n" #glsl namespace glsl { namespace vs { //VERTEX SHADERS //========================= // simple VS //========================= constexpr GLchar * const simple = glsl(450 core, layout(location = 0) in vec3 position; void main() { gl_Position = vec4(position, 1.0f); } ); } namespace fs { //FRAGMENT SHADERS //========================= // simple FS //========================= constexpr GLchar * const simple = glsl(450 core, out vec4 color; void main() { color = vec4(1.0f, 0.0f, 0.0f, 1.0f); } ); } } ``` I don't think this would result in too large of an exe file and it would speed up loading times; unless I'm mistaken about how many shaders are used for a typical graphics application. I realize you may want to update shaders after compile time, but does that really happen? Is there any reason that I should not want to do this?