Until recently, K-3D loaded the set of all available shaders at startup, maintaining a cache of shaders and their arguments. This had a number of negative side effects:
- Increased startup times while shader metadata is loaded. Most of this was wasted effort since most documents never use more than a small subset of the available shaders.
- Couldn't change the set of shaders, or the set of arguments for a given shader, at runtime. This was a problem for shader authors, who might want to iteratively make modifications to a shader without restarting K-3D.
- Sharing documents was difficult, since shaders effectively existed in a flat namespace - if the recipient of a document had a different set of shaders than the sender, or had the same shaders with different implementations, the document output was incorrect.
- Changes to K-3D setup or installation paths could radically alter shader behavior.
To resolve these issues, we replaced "shader name" in the K-3D shader objects with a "shader path" argument, which stores the path to the *.sl source file. The *.slmeta file is loaded whenever the file path changes. This way, shaders become an external resource just like a bitmap, and users can manage them to suit, including inlining shader sources in their document. Shader developers can create new shaders, and alter existing shaders, including making changes to a shader's arguments, without having to restart K-3D.
- A useful feature for troubleshooting and network rendering would be to put a copy of the shader source and (optionally) cached binary in the frame directory with the RIB file. This would allow the source to be recompiled to a hypothetical platform-specific binary in a network rendering environment, and would facilitate sharing bug reports with render engine developers.
- One major drawback from allowing the user to use shaders by arbitrary path is the potential for using two different shaders (different filepaths) that have the same name. In theory, it would be possible to transparently rename the shaders and recompile them, using the new names in the resulting RIB file, to eliminate the name clash.