Quick answer: Use material.set_shader_parameter("my_tex", my_texture) at runtime, or assign in the material inspector. Declare with hints (source_color, repeat_enable, filter_linear) for correct color and sampling behavior.
Here is how to fix Godot 4 shader sampler2D uniforms that sample black, sample the wrong texture, or produce inverted colors. Texture uniforms have specific hints that affect color space and sampling; missing hints produce subtle bugs.
The Symptom
Shader uses a custom texture uniform. Output is solid black or shows the wrong texture. Inspector shows the texture assigned correctly.
What Causes This
Uniform not bound. Default sampler is a black/white fallback. Without a binding, that fallback samples.
Color space mismatch. Color textures need source_color hint for proper sRGB-linear conversion. Without it, colors look washed out or incorrect.
Wrong filter/repeat hint. Texture appears tiled when you wanted clamp, or pixelated when you wanted bilinear.
The Fix
Step 1: Declare uniforms with proper hints.
shader_type canvas_item;
uniform sampler2D tint_tex : source_color, repeat_enable, filter_linear;
uniform sampler2D mask_tex : hint_default_white, repeat_disable, filter_linear;
uniform sampler2D normal_tex : hint_normal, repeat_enable, filter_linear;
source_color for albedo; hint_normal for normal maps; hint_default_white for fallback.
Step 2: Bind from script.
extends Sprite2D
@export var palette: Texture2D
func _ready():
material.set_shader_parameter("tint_tex", palette)
Or assign in the material inspector and skip the script call.
Step 3: Sample correctly in fragment.
void fragment() {
vec4 tint = texture(tint_tex, UV);
COLOR.rgb *= tint.rgb;
}
Step 4: For RenderTextures, use viewport_path.
uniform sampler2D screen_tex : hint_screen_texture;
// or
uniform sampler2D depth_tex : hint_depth_texture;
Built-in screen and depth hints provide automatic binding.
Step 5: Debug with a known color.
// Temporarily output the texture directly
void fragment() {
COLOR = texture(tint_tex, UV);
}
If that shows the texture correctly, your math elsewhere is the issue. If still black, the binding or hint is wrong.
“source_color for color, hint_normal for normals, hint_default_white for fallback. Bind with set_shader_parameter.”
Related Issues
For shader color banding, see Color Banding in Export. For RichText effects, see RichText Effect.
Right hint for the texture type. set_shader_parameter at runtime. Samples come through correctly.