Give the shader a signal it can actually see.
Core shaders do not get a nice item name or model ID to inspect. This tiny pack shows the practical workaround: carry an identifying value in render data, detect it in item.fsh, then branch into a different result.
What the example proves
The custom item uses a solid teal texture: RGB(19, 211, 173). The item fragment shader samples that texture normally. When it sees that exact RGB value, it writes white instead.
Everything else stays on the normal path. That makes this a clean first test: the special case is obvious, and the vanilla path still exists right next to it.
This is not model-name lookup. The shader is reacting to a visible signal in render data. If another texture reaches the same pipeline with the same color, those pixels can match too.
What the shader actually sees
By the time item.fsh runs, Minecraft has already picked the item model and turned it into render inputs. The shader gets UVs, vertex color, distance values and textures. It does not get a string like example:shader_block.
That is why a signal matters. The hard part is often not writing the effect itself. The hard part is giving the shared shader a reliable clue that one render should be treated differently.
The marker signal
This sample uses the most obvious version possible: the whole texture is the marker. It is visually blunt, but great for learning, because it makes the branch impossible to miss.
vec4 color = texture(Sampler0, texCoord0);
ivec3 rgb = ivec3(round(color.rgb * 255.0));
if (all(equal(rgb, ivec3(19, 211, 173)))) {
fragColor = vec4(1.0, 1.0, 1.0, color.a);
return;
}
Texture samples arrive as normalized floats. Multiplying by 255.0 and rounding turns them back into easy integer RGB values for comparison.
In a real pack, you usually hide the signal on a reserved UV patch, a hidden face, a vertex-color pattern or another channel that ordinary textures are unlikely to hit by accident.
Pack structure
The sample namespace is deliberately example so the files stay generic and easy to reuse.
Item definition
{
"model": {
"type": "minecraft:model",
"model": "example:item/shader_block"
}
}
Model
{
"parent": "minecraft:block/cube_all",
"textures": {
"all": "example:item/shader_block"
}
}
Pack metadata
{
"pack": {
"min_format": [
84,
0
],
"max_format": [
84,
0
],
"description": "shader test"
}
}
The whole shader
The special branch lives near the top. Matching pixels return early. Everything else keeps the ordinary cutout, tint and fog path.
#version 330
#moj_import <minecraft:fog.glsl>
#moj_import <minecraft:dynamictransforms.glsl>
uniform sampler2D Sampler0;
in float sphericalVertexDistance;
in float cylindricalVertexDistance;
in vec4 vertexColor;
in vec2 texCoord0;
out vec4 fragColor;
void main() {
vec4 color = texture(Sampler0, texCoord0);
ivec3 rgb = ivec3(round(color.rgb * 255.0));
if (all(equal(rgb, ivec3(19, 211, 173)))) {
fragColor = vec4(1.0, 1.0, 1.0, color.a);
return;
}
#ifdef ALPHA_CUTOUT
if (color.a < ALPHA_CUTOUT) {
discard;
}
#endif
color *= vertexColor * ColorModulator;
fragColor = apply_fog(color, sphericalVertexDistance, cylindricalVertexDistance, FogEnvironmentalStart, FogEnvironmentalEnd, FogRenderDistanceStart, FogRenderDistanceEnd, FogColor);
}
Once this version makes sense, replacing the white output with a real effect is the easy part.
Run the example
- Put example.zip in your resource-pack folder and enable it.
- Join a world where you can use commands.
- Give yourself the custom item using the command below.
- If the shader branch is working, the cube renders white.
/give @s minecraft:stone[minecraft:item_model='example:shader_block']
Take it further
Change the output first
Leave the marker condition alone and change only the special output. That confirms your edit is reaching the correct branch.
fragColor = vec4(0.45, 0.9, 1.0, color.a);
Hide the signal
The next real step is moving the marker off the visible surface. Use hidden geometry, a reserved UV patch or another channel the player does not see.
Add more identities
Once one signal is reliable, several values can select several effects. At that point you are building a small protocol between the model data and the core shader.
item.fsh is shared. Conditions that are too broad can affect ordinary items as well.
Troubleshooting
The cube is teal
The model and texture are probably loading, but the branch is not producing white. Recheck the RGB values and make sure the correct item.fsh loaded.
The item is still normal stone
Debug the model before the shader. Check the item model component, namespace, item definition and model path.
Other items change too
Another texture matched your condition. Move toward a more deliberate marker pattern as soon as the idea clicks.
An edit breaks rendering
Return to the last working shader and change one thing at a time. Keep identification, math and output edits separate while debugging.