Skip to content

ShaderInjector

Error-mdl edited this page Nov 16, 2022 · 1 revision

DISCLAIMER

ShaderInjector was slapped together to make maintaining the several different versions of LitMAS manageable. It is not robust, has not been tested thoroughly, and has only basic functionality. Additionally, as the tool is continues to be developed there may be breaking changes that require old ShaderInjector files to be updated. Use at your own risk!

This tool is provided primarily for making variations of LitMAS. If you want something to make maintaining your own shader's variants easier, I'd recommend instead checking out Modular Shader System as it has way more polish and provides similar functionality.

Installation

ShaderInjector is a part of the "SLZ Bonelab Shaders" sample inside the SLZ Universal RP package, and can be installed from the unity package manager window.

Using ShaderInjector

ShaderInjector is a simple tool that creates shader include files by copy/pasting blocks of code from a set of files ("injections") into a specially formatted include file (the "basis"). The injection process is handled by an Injected Include asset, which can be created from the create assets menu (Create/Shader/Injected Include).

The Injected include asset has 3 properties. The first is the output shader include file which the injector will write to. The second is the basis file. This is an otherwise normal shader include file which has a number of specially-prefixed commands that indicate where code blocks from the injections will be copied. The third property is an array of injections, specially formatted shader include files which contain named blocks of code that will get copy-pasted into the basis file at the locations specified by the basis.

The injection process happens when the "Inject and Create Output" button is pressed. Multiple injected include files can be selected to update all at once. Modifying the basis or injection files will not automatically update the output file.

Syntax

The injection process is controlled by a handful of simple commands inside the basis and injection files. Every command begins with //#!, followed by the command name and 0 or more parameters separated by whitespace. The commands must be on a new line, and can be preceded by any amount of whitespace. Some commands are valid only in the basis file, others only in the injections, and some in both.

The Basis file

//#!INJECT_POINT <name>
Defines a line where blocks with name from the injection files will be copied. <name> is a string with no whitespaces.

//#!INJECT_DEFAULT
Begins a block of code that gets deleted unless there is no block in any of the injection files that matches the name of the previous INJECT_POINT. Must be preceded by an INJECT_POINT, and must have an INJECT_END command to end the block. Useful for defining default behavior that can be overwritten by injections.

Injection Files

//#!INJECT_BEGIN <name> <order>
Defines the beginning of a block of code that will get copy-pasted into the basis file at the location of the INJECT_POINT with the same name parameter. The block must be terminated with the INJECT_END command. If there are multiple blocks of the same name in other injections, the blocks are sorted according the <order> parameter (a signed int) from smallest to largest before being copied. Note that if multiple blocks have the same order number, they will be copied in the order their injection files appear in the injected include's array of injections.

Common

//#!INJECT_END
Defines the end of injection blocks

//#!TEXCOORD <type> <name> <counter>
Creates an automatically numbered TEXCOORD semantic for a variable of type <type> and name <name>. The numbering is defined by the order in which the //#!TEXCOORD commands appear in the output after all blocks have been injected. The <counter> parameter is an int which puts the //#!TEXCOORD commands into separate groups that are numbered individually. So each struct should have a different counter number for its //#!TEXCOORD commands so the TEXCOORD semantics always begin at 0 within each struct. Note if you use this command, every TEXCOORD semantic must be created with the command as the ShaderInjector does not attempt to parse structs to avoid numbering collisions.

Examples

For examples, check out the LitMAS files included with the SDK.

Clone this wiki locally