Help home · Beginner · Intermediate · Advanced authoring · Command reference · Samples
Using Shaders: Intermediate
This guide is for using built-in, downloaded, or team-authored shader assets without needing to understand their HLSL implementation. It explains how shader instances fit into a real project, how attachments are resolved, and how assets are built and deployed.
If terms such as material shader and post effect are still unfamiliar, start with Shaders for Beginners. To create or change the shader code itself, continue to the Advanced Shader Authoring Guide.
1. Programs, assets, and instances
A file-backed shader is loaded from a .b3shader descriptor:
water=LoadShader("fx/water.b3shader")
The descriptor tells Blitz3D whether it is a surface, raw, or post shader, where its compiled code comes from, and which named parameters are public. Treat the descriptor and its accompanying files as one asset.
Blitz3D caches the compiled GPU program, but every call to
LoadShader returns a fresh instance. Instances share the
expensive compiled code while keeping independent parameter values and texture
bindings. The same is true of builtin: aliases.
calm=LoadShader("fx/water.b3shader") stormy=LoadShader("fx/water.b3shader") ShaderFloat calm,"WaveHeight",.05 ShaderFloat stormy,"WaveHeight",.4
A failed load raises a descriptive runtime error. ShaderError
returns any diagnostic retained by a valid instance.
2. Working with named parameters
A shader asset declares the names, types, and defaults which form its public interface. Names are matched without regard to case. Use the spelling supplied by the asset so your program remains easy to compare with its documentation.
| Declared type | Blitz command | Example |
|---|---|---|
float | ShaderFloat | ShaderFloat shader,"Roughness",.8 |
int | ShaderInt | ShaderInt shader,"Mode",1 |
vector | ShaderVector | ShaderVector shader,"Wind",1,0,.2,0 |
color | ShaderColor | ShaderColor shader,"Tint",80,160,255 |
texture | ShaderTexture | ShaderTexture shader,"NormalMap",map,frame |
Colours use familiar 0 to 255 components. Vectors use numeric components directly. A texture parameter accepts an ordinary Blitz texture and optional animation frame; the shader retains the resource while it is bound.
Asking for a missing name, using the wrong setter type, or choosing an invalid texture frame is a runtime error. This strictness catches mistakes close to the line which caused them.
3. Entity and brush precedence
EntityShader applies one material shader to every rendered
surface on an entity. BrushShader stores a material shader in a
brush; surfaces painted from the brush retain it. At draw time the choice is:
- Use the entity's
EntityShader, if present. - Otherwise use the surface brush's
BrushShader, if present. - Otherwise use the brush's Standard or classic appearance.
shader=LoadShader("builtin:rim-light") ; One shader for the whole model. EntityShader character,shader ; Or place it on a reusable brush. BrushShader specialBrush,shader surface=GetSurface(machine,2) PaintSurface surface,specialBrush
Pass zero to EntityShader or BrushShader to remove the
override. Entity colour, alpha, textures, blending, FX flags, fog, and lighting
remain engine state. Whether a custom shader uses all of that state depends on
how its author wrote it.
4. Managing camera-effect stacks
CameraEffect appends a post shader to a camera. Effects retain
attachment order within their declared stage, with each result feeding the next:
bloom=LoadShader("builtin:bloom") grade=LoadShader("builtin:color-adjust") CameraEffect camera,bloom CameraEffect camera,grade
Here bloom runs first and colour adjustment runs second. Use the same shader handle to control its attachment:
CameraEffectEnabled camera,bloom,False CameraEffectEnabled camera,bloom,True RemoveCameraEffect camera,grade
Bypassing retains the effect's position and settings. Removing it does not
free your script handle. Effects are restricted to the owning camera's
viewport. Attaching the same shader handle to two cameras shares its settings;
use CopyShader before attaching when each camera needs independent
values.
Post processing occurs after that camera's 3D render. 2D drawing performed
later is unaffected. Post shaders cannot be assigned through
EntityShader or BrushShader.
Format-2 effects declare scene-linear, display-linear,
or presentation. The renderer always runs those stages in that order,
inserting its one tone-map/output pass between scene and display work. Consequently,
a presentation vignette attached before bloom still executes after scene-linear bloom.
Quality and optional resources
Expensive effects use the shared integer Quality convention: 0 low,
1 balanced, 2 high. Depth, normal/roughness, velocity, object-mask, opaque-colour,
blue-noise, and history resources are created only if an enabled attachment or
material declares them. Bypassing the last consumer releases persistent optional
targets after the renderer's bounded lifetime. Use DrawRenderStats 8,8,1023
to see actual pass count, optional-buffer mask, target memory, and history state.
Render scale, viewports, and history
Pass scales are relative to the current internal render size and remain confined to the camera viewport. Multiple presentation targets own independent scene, capture, transient, and temporal resources. TAA/history resets on camera cuts, resize, render-scale and AA changes, retain/discard changes, and device rebuild.
5. Copying and lifetime
CopyShader copies all current values and texture bindings while
sharing the compiled program. Later changes affect only the selected copy:
blue=LoadShader("builtin:rim-light") orange=CopyShader(blue) ShaderColor blue,"RimColor",40,140,255 ShaderColor orange,"RimColor",255,100,20
Prefer this over loading the same asset again when a new instance should begin with an existing instance's settings.
Entities, brushes, and cameras retain the instance when it is attached.
Changes made through the original handle remain visible on those attachments.
FreeShader releases only the supplied script handle; it does not
leave an attached object dangling. Do not use a handle after freeing it. Free
textures only after accounting for any other code which still needs them;
shader texture bindings retain their underlying resources.
6. Source assets, the IDE, and deployment
A supplied shader may contain compiled bytecode, or it may be source-backed. The IDE discovers literal loads such as:
shader=LoadShader("fx/glow.b3shader")
Check and Run compile a discovered source asset, report HLSL errors with file and line information, and package its descriptor, bytecode, and dependencies beside the program. Save all shader source and include files before running.
Keep the asset's relative directory structure intact when distributing a program. If a shader filename is assembled at runtime, the IDE cannot discover it statically:
shader=LoadShader("fx/"+effectName$+".b3shader")
In that case, add every possible descriptor and its dependencies to the distribution yourself. Built-in aliases require none of these nearby files.
During debug development, source-backed shaders follow a last-known-good rule. A successfully changed source is rebuilt; if the new source fails, the previous valid shader remains active and diagnostics report the failure.
7. Troubleshooting and performance
- Start from the asset's complete working sample, then change one value at a time.
- Read the first compiler or runtime error first; later messages may only be consequences.
- Check the parameter spelling and setter type against the asset documentation.
- If a brush shader appears ignored, check for an entity shader override.
- If a shader loads in the IDE but not after copying the executable, check its packaged files and relative paths.
- Use
ShaderErrorto inspect retained diagnostic text on a valid instance. - Prefer
CopyShaderfor variants and update parameters only when they change. - Camera effects require intermediate colour and depth targets. Bypass or remove effects which are not visible, especially on secondary cameras.
8. Command map
| Task | Commands |
|---|---|
| Load, copy, free, or inspect | LoadShader, CopyShader, FreeShader, ShaderError |
| Set named values | ShaderFloat, ShaderInt, ShaderVector, ShaderColor, ShaderTexture |
| Apply material shaders | EntityShader, BrushShader |
| Manage post effects | CameraEffect, CameraEffectEnabled, RemoveCameraEffect |
Each command has a runnable example in the Shader group of the command reference.
9. Next: authoring
The Advanced Shader Authoring Guide explains the descriptor format, HLSL includes, surface and post callbacks, raw shaders, vertex displacement, shadow policies, layout 3 bindings, compilation, and authoring diagnostics.
Shader instances · asset use · deployment · Extended mode