The RenderDragon shift
Older versions of Bedrock allowed creators to write plain-text GLSL and HLSL vertex and fragment shaders directly inside a resource pack's shaders folder. When Minecraft transitioned all platforms to the RenderDragon rendering engine, this pipeline was replaced with pre-compiled binary shaders (.material.bin files) bundled inside the game installation.
Because the game client ignores uncompiled shader text files in standard resource packs, you cannot write custom vertex displacement or post-processing passes from scratch without modifying core game files—which breaks compatibility across updates and cannot be distributed via standard .mcpack files. For add-on creators today, 'shader work' means two things: configuring entity and particle material files that point to built-in compiled shaders, or authoring texture sets and lighting JSONs for the Deferred Technical Preview.
Materials: how packs talk to shaders
Even though you cannot write new shader code, you control how the engine renders your custom entities, items, and particles using .material files located in RP/materials/. A material file is a JSON wrapper that inherits from a built-in engine material (which already has a compiled shader assigned to it) and overrides specific render states, blend modes, or preprocessor defines.
Entity materials sit inside an top-level 'materials' object with a version string of '1.0.0'. You define a custom material key and use the colon syntax to inherit from a base definition like 'entity_alphatest' or 'entity_emissive_alpha'. From there, you can add or remove states—such as disabling back-face culling so thin geometry is visible from both sides, or enabling blending for semi-transparent ghosts.
| Property | What it does | Notes |
|---|---|---|
| +defines / -defines | Toggles shader preprocessor flags compiled into the base material. | Common flags include USE_EMISSIVE, USE_COLOR_MASK, and USE_UV_ANIM. |
| +states / -states | Enables or disables fixed-function GPU render states. | Includes Blending, DisableCulling, DisableDepthWrite, and InvertCulling. |
| vertexFields | Declares which vertex attributes the geometry passes to the shader. | Rarely changed in add-ons; mismatching this with the compiled shader causes invisible models. |
| blendSrc / blendDst | Sets the source and destination blend factors when Blending is active. | Uses values like SourceAlpha, OneMinusSrcAlpha, and One. |
{
"materials": {
"version": "1.0.0",
"custom_ghost:entity_alphablend": {
"+defines": [
"USE_EMISSIVE"
],
"+states": [
"Blending",
"DisableCulling",
"DisableDepthWrite"
]
},
"custom_cutout:entity_alphatest": {
"+states": [
"DisableCulling"
]
}
}
}Binding materials to an entity
Creating an entry in RP/materials/entity.material does not automatically apply it to your mobs. You must register the material inside your client entity definition (in RP/entity/) and then invoke it in a render controller.
In the client entity JSON, map a short alias (such as 'default' or 'ghost_layer') to the exact identifier you wrote in your material file (without the parent suffix after the colon). Inside your render controller, reference that short alias in the 'materials' array, matching it to the target geometry bones using wildcard patterns.
{
"format_version": "1.10.0",
"minecraft:client_entity": {
"description": {
"identifier": "wiki:specter",
"materials": {
"default": "custom_ghost"
},
"textures": {
"default": "textures/entity/specter"
},
"geometry": {
"default": "geometry.specter"
},
"render_controllers": [
"controller.render.default"
]
}
}
}Deferred Technical Preview and PBR texture sets
For creators who want modern shader effects—like dynamic shadows, metallic reflections, surface roughness, and glowing blocks—Bedrock offers the Deferred Technical Preview. Instead of writing shader logic, you feed surface data to the engine's built-in physically based rendering pipeline using Texture Sets.
A texture set is a JSON file placed next to your block, item, or entity texture. It pairs a base color map with a MER map (Metallic in the Red channel, Emissive in the Green channel, Roughness in the Blue channel) and either a pixel heightmap or a normal map for surface depth. When the Deferred graphics mode is active in video settings, the engine reads these channels to calculate real-time lighting.
{
"format_version": "1.16.100",
"minecraft:texture_set": {
"color": "copper_plate",
"metalness_emissive_roughness": "copper_plate_mer",
"heightmap": "copper_plate_height"
}
}Enabling PBR capabilities in manifest.json
A resource pack containing texture sets or deferred lighting configurations will only unlock the Deferred Technical Preview video toggle if the pack declares the 'pbr' capability in its manifest. Without this block, the game treats the pack as a standard resource pack and ignores your MER and heightmap channels outside of RTX worlds.
Add the 'capabilities' array at the root level of your RP/manifest.json alongside the header and modules sections. Note that 'pbr' is distinct from the 'raytraced' capability used specifically for hardware-accelerated RTX packs on Windows.
{
"format_version": 2,
"header": {
"name": "Deferred PBR Sample Pack",
"description": "Enables PBR materials for the Deferred pipeline.",
"uuid": "a1b2c3d4-e5f6-4a5b-8c9d-0e1f2a3b4c5d",
"version": [1, 0, 0],
"min_engine_version": [1, 20, 80]
},
"modules": [
{
"type": "resources",
"uuid": "f6e5d4c3-b2a1-4f5e-9d8c-7b6a5e4d3c2b",
"version": [1, 0, 0]
}
],
"capabilities": [
"pbr"
]
}Which versions this applies to
RenderDragon and .material files apply to all current Bedrock versions (1.18.30+ across all platforms). Texture sets (format_version 1.16.100) are stable, while the Deferred Graphics pipeline requires enabling the 'Deferred Technical Preview' world experiment and changing the in-game Video Graphics Mode to 'Deferred Technical Preview' on supported devices.
When it does not work
| What you see | Why | The fix |
|---|---|---|
| Custom entity renders completely invisible or solid magenta, and the Content Log reports: [Render][error] Failed to find material 'custom_ghost:entity_alphablend' | You included the parent inheritance suffix (':entity_alphablend') inside the client_entity JSON 'materials' block. Inheritance only belongs in the .material file header. | In RP/entity/<name>.entity.json, reference only the left side of the colon (for example, '"default": "custom_ghost"'). |
| Custom .fragment and .vertex files placed in RP/shaders/glsl/ have no effect in-game. | RenderDragon does not load or compile plain-text GLSL/HLSL files from resource packs. | Remove the raw shader files. Use RP/materials/entity.material with built-in '+defines' and '+states' for entity effects, or switch to the Deferred Technical Preview pipeline for environmental lighting. |
| The 'Deferred Technical Preview' option in Video Settings is greyed out even with the resource pack active. | Either the 'Deferred Technical Preview' experimental toggle is turned off in the world settings, or your RP/manifest.json is missing the 'pbr' capability. | Add '"capabilities": [ "pbr" ]' to the root of RP/manifest.json and enable the Deferred Technical Preview toggle in the world's Experiments menu before loading in. |
| Semi-transparent entity parts clip through each other or hide blocks behind them. | The material has the 'Blending' state enabled, but is still writing to the depth buffer, causing the GPU to discard pixels drawn behind transparent areas. | Add '"DisableDepthWrite"' to the '+states' array of your custom material in RP/materials/entity.material. |
Reference, straight from the game files
Read out of the game itself, so the ids match the version you are building for.
