1
\$\begingroup\$

In shader model 5 is a feature called dynamic linking which separates hlsl fragments by using interfaces and their methods implemented in classes.

I don't have any experience with this technique, my program uses about 10 shaders (10 separated files *.hlsl) and there are some identical parts in different shaders. So it will be good for me to separate a common logic (light for example) to its own file and just use it from other shaders.

I was always fascinated by modern game engines and their development kits capable of composing these shader fragments together by simple clicking in some internal editor. So a developer can create very complex scenes this way - choose materials, lights, particles, animations, etc. and it's very cool and productive I guess. If I omit some graphical editor and a sophisticated logic behind it, it is pretty what I want to achieve, isn't it? Just on a code level.

So with hlsl's dynamic linking in shader model 5 I have some idea how it can be done, but what about older shader models? When there was no shader model 5, what technique did engines use?

\$\endgroup\$
1
\$\begingroup\$

I believe very few game developers actually use the dynamic linking feature in HLSL, as it's a fairly limited, awkward form of abstraction and isn't as general as one might like it to be. Also, developers have needed to maintain backward compatibility with earlier APIs; there haven't been very many D3D11-only games to date.

In practice, you can get all the same benefits in terms of code reuse, and greater flexibility, by simply using header files that define common functions and data structures, then writing (or automatically generating from a tool) shaders that #include those headers and call functions out of them.

You can imagine implementing an Unreal-style node-based shader system by writing a function to represent each type of node in the graph, then writing code to generate a main() function for the shader that calls the functions for all the nodes, wiring up the parameters and returns according to the user-specified connections and values. The generated shader would then be passed to the usual shader compiler, which optimizes away any code that isn't used by that particular shader.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.