Typically when writing shaders, you'd have some code like this: ```cs public void CreateShader() { string fragmentShader = @" uniform vec4 uColour; out vec4 outColour; void main() { outColour = uColour; } "; // Create the shader Gl.ShaderSource(ID, fragmentShader); ... // Get the uniform location int location = Gl.GetUniformLocation(Handle, "uColour"); // Set the uniform Gl.Uniform4(location, 1.0f, 0.0f ,0.0f, 1.0f); } ``` For a simple shader like this, it's not too bad. But when you have dozens of uniforms with different types, it's a lot to keep track of. To reduce the amount of code you need to write, and to ensure you're setting the right data types on each uniform, create a new class that overrides [[ShaderUniformGroup]]: ```cs public class ExampleUniforms : ShaderUniformGroup { public ExampleUniforms() : base("") { colour = AddVec4("uColour"); } public ShaderUniformVec4 colour; } ``` Define your uniforms in the constructor using the `Add*()` functions, and they'll be automatically inserted into the fragment and vertex shader strings. To use these uniforms in your shader, pass them to the `AddUniforms` function: ```cs public class ExampleShader : ScreenShader { protected override void Initialise() { AddUniforms(ref uniforms); } public ExampleUniforms uniforms; protected override string FragmentOuter => "out vec4 oColor;"; protected override string FragmentInner => "oColor = uColour;"; } ``` > The uniforms are passed as `ref` variables so that they can be hot-reloaded (see below) To set a value on the uniform, you can call the `Set()` function: ```cs ExampleShader shader; public void RenderStuff() { shader.UseProgram(); shader.uniforms.colour.Set(Color.Green); // Render a model ... } ``` ## Hot Reloading If any part of the shader code changes (uniforms, fragment shader, vertex shader), the shader will be recompiled when [[Hot Reload|hot reloading]]. If there's a syntax error in the shader code, it will log the error and revert back to the previous working version of the shader.