Shader types: choosing and assigning
Where six shader types belong, Shader versus ShaderMaterial and shared default textures.
Start with the object that will consume the result. shader_type determines available stages and built-ins; the same COLOR name across shader types does not imply the same contract.
Choose a type by task
| Task | shader_type | Assign ShaderMaterial to | Stages and reference |
|---|---|---|---|
| A 3D mesh surface | spatial | Mesh surface material or MeshInstance3D.MaterialOverride | vertex / fragment / light |
| A 2D sprite or UI | canvas_item | CanvasItem.Material, such as Sprite2D or ColorRect | vertex / fragment / light |
| GPU-particle simulation | particles | GpuParticles2D/GpuParticles3D.ProcessMaterial | start / process |
| Sky and environment lighting radiance | sky | Sky.SkyMaterial; assign Sky to Environment | sky |
| FogVolume volumetric contribution | fog | FogVolume.Material; requires Forward+ and VolumetricFogEnabled | fog |
| An explicit DrawableTexture2D write | texture_blit | BlitRect/BlitRectMulti operation material argument | blit |
You do not have to implement every listed stage; use the ones your effect needs. A particle material simulates data while a separate mesh/sprite material draws it. Texture blits run when requested rather than becoming a permanent display effect. Material assignment does not automatically enable lights, an environment, volumetric fog or particle emission.
Shader type and ShaderMaterial values
Shader stores code/graph and shared settings. ShaderMaterial references the Shader and stores material parameter values. Two separate materials can share one Shader; assigning one ShaderMaterial to two objects shares that material's values.
A text Shader declares its type with shader_type. GetMode reads the type from preprocessed text. It proves neither successful compilation nor correct assignment: even an empty resource defaults to Spatial. After connecting a shader, inspect output in the intended pass and compiler errors.
Save the complete ShaderRoute.cs helper to check type before creating a material:
using System;
using Reckfell;
public static class ShaderRoute
{
public static ShaderMaterial Material(Shader shader, Shader.Mode expected)
{
ArgumentNullException.ThrowIfNull(shader);
if (shader.GetMode() != expected)
throw new ArgumentException("Shader type does not match the intended consumer.", nameof(shader));
return new ShaderMaterial { Shader = shader };
}
public static void DefaultSource(Shader shader, Texture? texture)
{
shader.SetDefaultTextureParameter("source_texture", texture!, 0);
}
}Load the intended Shader, for example ResourceLoader.Load<Shader>("asset://DefaultSource.reckfellshader"). For the example below, call ShaderRoute.Material(shader, Shader.Mode.CanvasItem) and assign the result to a visible ColorRect.Material. The guard checks type agreement, not GPU-code correctness.
Defaults and overrides
The complete example shader samples a texture and gain parameter:
shader_type canvas_item;
uniform sampler2D source_texture : source_color, hint_default_white;
uniform float gain = 1.0;
void fragment() {
COLOR = texture(source_texture, UV) * gain;
}ShaderRoute.DefaultSource(shader, texture) assigns a shared source_texture default on Shader. Materials without their own value use it; material.SetShaderParameter("source_texture", otherTexture) overrides it only for that material. Use exact uniform names without the shader_parameter/ prefix for ordinary parameter calls.
Passing null to DefaultSource removes the shared texture. This example then uses hint_default_white; material overrides remain. Passing default(Variant) to SetShaderParameter removes the material override instead. These are separate setting levels.
GetDefaultTextureParameter(name, index) returns an assigned shared texture or null. For sampler arrays, index selects an element; removing one leaves the others. If any default texture is assigned for a uniform, current GetShaderUniformList hides that entire uniform. The declaration and ability to set a material value still exist. Removing the last assignment restores the list entry.
GetCode returns original text including directives, not expanded driver code. InspectNativeShaderCode requests a separate editor view when its viewer is available; it does not return compiled shader text.
Find the next answer
| Question | Section |
|---|---|
| Types, uniforms, varyings, functions and parameter scopes | Shader language |
| #include, #define and conditional compilation | Preprocessor |
| Built-in math and texture functions | Built-in functions |
| A graph instead of text code | VisualShader |
| Screen texture, depth or chained effects | Screen-reading shaders |
Windows Forward+/Vulkan checks cover six declaration types, the C# guard and actual CanvasItem pixels for shared/material textures, removal and array indices. This single test does not accept all-type rendering: detailed guides retain separate pass-specific checks. The native-code editor window, other platforms/renderers and performance are not separately exercised here.