Render Types
Render Types
Section titled “Render Types”Render types are the cornerstone of Minecraft 26.1’s rendering system, defining complete rendering configurations including shaders, textures, blend modes, and other OpenGL state. This guide covers how to understand and create custom render types.
Overview
Section titled “Overview”A Render Type encapsulates:
- Shader configuration and uniforms
- Texture bindings and samplers
- Blend modes and transparency settings
- Depth testing and culling behavior
- Output targets and framebuffer operations
Core Structure
Section titled “Core Structure”RenderType Class
Section titled “RenderType Class”The RenderType class represents a complete rendering configuration:
public class RenderType { private final String name; private final VertexFormat format; private final VertexFormat.Mode mode; private final int expectedBufferSize; private final boolean affectsCrumbling; private final boolean sortOnUpload; private final CompositeState state;
public static RenderType create(String name, VertexFormat format, VertexFormat.Mode mode, int expectedBufferSize, CompositeState state) { return new RenderType(name, format, mode, expectedBufferSize, false, false, state); }}Composite State
Section titled “Composite State”The CompositeState combines individual rendering state components:
// Excerpt: net.minecraft.client.renderer.RenderType$CompositeStatepublic static class CompositeState { private final Optional<ShaderStateShard> shaderState; private final Optional<TextureStateShard> textureState; private final Optional<TransparencyStateShard> transparencyState; private final Optional<DepthTestStateShard> depthTestState; private final Optional<CullStateShard> cullState; private final Optional<WriteMaskStateShard> writeMaskState; private final Optional<LayeringStateShard> layeringState; private final Optional<OutputStateShard> outputState; private final Optional<Boolean> sortOnUpload; private final Optional<Shader> shader;
public static Builder builder() { return new Builder(); }}Built-in Render Types
Section titled “Built-in Render Types”Common Render Types
Section titled “Common Render Types”Minecraft provides many built-in render types for common use cases:
// Example: Common built-in render typespublic class RenderTypes { // Solid opaque rendering public static final RenderType SOLID = RenderType.create( "solid", DefaultVertexFormat.BLOCK, VertexFormat.Mode.QUADS, 2097152, RenderType.CompositeState.builder() .setShaderState(RenderStateShards.NEW_ENTITY_SHADER) .setTextureState(RenderStateShards.BLOCK_SHEET_MIPPED_TEXTURE) .setTransparencyState(RenderStateShards.NO_TRANSPARENCY) .setOutputState(RenderStateShards.ITEM_ENTITY_TARGET) .createCompositeState(false) );
// Transparent rendering public static final RenderType TRANSLUCENT = RenderType.create( "translucent", DefaultVertexFormat.BLOCK, VertexFormat.Mode.QUADS, 2097152, RenderType.CompositeState.builder() .setShaderState(RenderStateShards.NEW_ENTITY_SHADER) .setTextureState(RenderStateShards.BLOCK_SHEET_MIPPED_TEXTURE) .setTransparencyState(RenderStateShards.TRANSLUCENT_TRANSPARENCY) .setOutputState(RenderStateShards.TRANSLUCENT_TARGET) .createCompositeState(true) // sortOnUpload );
// Cutout rendering (alpha test) public static final RenderType CUTOUT = RenderType.create( "cutout", DefaultVertexFormat.BLOCK, VertexFormat.Mode.QUADS, 2097152, RenderType.CompositeState.builder() .setShaderState(RenderStateShards.NEW_ENTITY_SHADER) .setTextureState(RenderStateShards.BLOCK_SHEET_MIPPED_TEXTURE) .setTransparencyState(RenderStateShards.CUTOUT_TRANSPARENCY) .setOutputState(RenderStateShards.ITEM_ENTITY_TARGET) .createCompositeState(false) );}Entity-Specific Render Types
Section titled “Entity-Specific Render Types”// Example: Entity render typespublic static final RenderType ENTITY_SOLID = RenderType.create( "entity_solid", DefaultVertexFormat.NEW_ENTITY, VertexFormat.Mode.QUADS, 256, RenderType.CompositeState.builder() .setShaderState(RenderStateShards.RENDERTYPE_ENTITY_SOLID_SHADER) .setTextureState(RenderStateShards.ENTITY_SHEET_TEXTURE) .setTransparencyState(RenderStateShards.NO_TRANSPARENCY) .setLightmapState(RenderStateShards.LIGHTMAP) .setOverlayState(RenderStateShards.OVERLAY) .createCompositeState(false));
public static final RenderType ENTITY_TRANSLUCENT = RenderType.create( "entity_translucent", DefaultVertexFormat.NEW_ENTITY, VertexFormat.Mode.QUADS, 256, RenderType.CompositeState.builder() .setShaderState(RenderStateShards.RENDERTYPE_ENTITY_TRANSLUCENT_SHADER) .setTextureState(RenderStateShards.ENTITY_SHEET_TEXTURE) .setTransparencyState(RenderStateShards.TRANSLUCENT_TRANSPARENCY) .setLightmapState(RenderStateShards.LIGHTMAP) .setOverlayState(RenderStateShards.OVERLAY) .createCompositeState(true) // sortOnUpload);Creating Custom Render Types
Section titled “Creating Custom Render Types”Basic Custom Render Type
Section titled “Basic Custom Render Type”// Example: Creating a custom render typepublic class CustomRenderTypes { public static final RenderType CUSTOM_GLOW;
static { CUSTOM_GLOW = RenderType.create( "custom_glow", DefaultVertexFormat.POSITION_COLOR_TEX, VertexFormat.Mode.QUADS, 256, RenderType.CompositeState.builder() .setShaderState(RenderStateShards.NEW_ENTITY_SHADER) .setTextureState(RenderStateShards.BLOCK_SHEET_MIPPED_TEXTURE) .setTransparencyState(RenderStateShards.ADDITIVE_TRANSPARENCY) .setCullState(RenderStateShards.NO_CULL) .setLightmapState(RenderStateShards.LIGHTMAP) .setWriteMaskState(RenderStateShards.COLOR_WRITE) .createCompositeState(true) ); }}Custom Shader State
Section titled “Custom Shader State”Create custom shader states for specialized rendering:
// Example: Custom shader statepublic class CustomShaderStates { public static final RenderStateShard.ShaderStateShard CUSTOM_WAVE_SHADER = new RenderStateShard.ShaderStateShard() { @Override public ShaderStateShard.Supplier createSupplier() { return () -> Minecraft.getInstance().getShaderManager() .getShader("my_mod:wave_shader"); } };
public static final RenderStateShard.ShaderStateShard CUSTOM_RAINBOW_SHADER = new RenderStateShard.ShaderStateShard() { @Override public ShaderStateShard.Supplier createSupplier() { return () -> Minecraft.getInstance().getShaderManager() .getShader("my_mod:rainbow_shader"); } };}Custom Transparency States
Section titled “Custom Transparency States”// Example: Custom transparency statespublic class CustomTransparencyStates { public static final RenderStateShard.TransparencyStateShard SCREEN_TRANSPARENCY = RenderStateShard.TransparencyStateShard.of( RenderStateShard.SourceFactor.ONE, RenderStateShard.DestFactor.ONE_MINUS_SRC_COLOR );
public static final RenderStateShard.TransparencyStateShard MULTIPLY_TRANSPARENCY = RenderStateShard.TransparencyStateShard.of( RenderStateShard.SourceFactor.DST_COLOR, RenderStateShard.DestFactor.ZERO );}Advanced Custom Render Type
Section titled “Advanced Custom Render Type”// Example: Advanced custom render type with multiple configurationspublic class AdvancedRenderTypes { public static final RenderType ENERGY_FIELD; public static final RenderType HOLOGRAM; public static final RenderType FORCE_FIELD;
static { // Energy field with additive blending ENERGY_FIELD = RenderType.create( "energy_field", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP, VertexFormat.Mode.QUADS, 512, RenderType.CompositeState.builder() .setShaderState(CustomShaderStates.CUSTOM_WAVE_SHADER) .setTextureState(RenderStateShards.BLOCK_SHEET_MIPPED_TEXTURE) .setTransparencyState(CustomTransparencyStates.SCREEN_TRANSPARENCY) .setCullState(RenderStateShards.NO_CULL) .setDepthTestState(RenderStateShard.DepthTestStateShard.LEQUAL) .setLightmapState(RenderStateShards.LIGHTMAP) .setWriteMaskState(RenderStateShard.COLOR_WRITE) .setLayeringState(RenderStateShard.VIEW_OFFSET_Z_LAYERING) .createCompositeState(true) );
// Hologram with special output target HOLOGRAM = RenderType.create( "hologram", DefaultVertexFormat.NEW_ENTITY, VertexFormat.Mode.QUADS, 256, RenderType.CompositeState.builder() .setShaderState(CustomShaderStates.CUSTOM_RAINBOW_SHADER) .setTextureState(RenderStateShards.ENTITY_SHEET_TEXTURE) .setTransparencyState(RenderStateShards.TRANSLUCENT_TRANSPARENCY) .setCullState(RenderStateShards.NO_CULL) .setOutputState(RenderStateShards.OUTLINE_TARGET) .setLightmapState(RenderStateShards.LIGHTMAP) .setOverlayState(RenderStateShards.OVERLAY) .createCompositeState(true) );
// Force field with special layering FORCE_FIELD = RenderType.create( "force_field", DefaultVertexFormat.POSITION_COLOR_TEX, VertexFormat.Mode.QUADS, 1024, RenderType.CompositeState.builder() .setShaderState(RenderStateShards.RENDERTYPE_BEACON_BEAM_SHADER) .setTextureState(RenderStateShards.BEACON_TRANSPARENCY_TEXTURE) .setTransparencyState(RenderStateShards.ADDITIVE_TRANSPARENCY) .setCullState(RenderStateShards.NO_CULL) .setDepthTestState(RenderStateShard.DepthTestStateShard.EQUAL) .setWriteMaskState(RenderStateShards.COLOR_DEPTH_WRITE) .setLayeringState(RenderStateShard.POLYGON_OFFSET_LAYERING) .createCompositeState(true) ); }}State Components
Section titled “State Components”Transparency States
Section titled “Transparency States”Control how colors blend with existing pixels:
// Example: Different transparency modespublic class TransparencyExamples { // Standard alpha blending public static final RenderType ALPHA_BLEND = RenderType.create( "alpha_blend", format, mode, size, RenderType.CompositeState.builder() .setTransparencyState(RenderStateShards.TRANSLUCENT_TRANSPARENCY) .createCompositeState(false) );
// Additive blending (good for glows) public static final RenderType ADDITIVE = RenderType.create( "additive", format, mode, size, RenderType.CompositeState.builder() .setTransparencyState(RenderStateShards.ADDITIVE_TRANSPARENCY) .createCompositeState(false) );
// Alpha test (hard edges) public static final RenderType CUTOUT = RenderType.create( "cutout", format, mode, size, RenderType.CompositeState.builder() .setTransparencyState(RenderStateShards.CUTOUT_TRANSPARENCY) .createCompositeState(false) );}Depth Testing
Section titled “Depth Testing”Control how depth testing is performed:
// Example: Depth test configurationspublic class DepthTestExamples { // Standard depth testing public static final RenderType STANDARD_DEPTH = RenderType.create( "standard_depth", format, mode, size, RenderType.CompositeState.builder() .setDepthTestState(RenderStateShard.DepthTestStateShard.LEQUAL) .createCompositeState(false) );
// No depth testing (always draws) public static final RenderType NO_DEPTH_TEST = RenderType.create( "no_depth_test", format, mode, size, RenderType.CompositeState.builder() .setDepthTestState(RenderStateShard.DepthTestStateShard.ALWAYS) .createCompositeState(false) );
// Equal depth test (only at exact depth) public static final RenderType EQUAL_DEPTH = RenderType.create( "equal_depth", format, mode, size, RenderType.CompositeState.builder() .setDepthTestState(RenderStateShard.DepthTestStateShard.EQUAL) .createCompositeState(false) );}Culling Control
Section titled “Culling Control”Control which faces are rendered:
// Example: Culling configurationspublic class CullingExamples { // Standard backface culling public static final RenderType BACKFACE_CULLING = RenderType.create( "backface_culling", format, mode, size, RenderType.CompositeState.builder() .setCullState(RenderStateShards.CULL) .createCompositeState(false) );
// No culling (all faces rendered) public static final RenderType NO_CULLING = RenderType.create( "no_culling", format, mode, size, RenderType.CompositeState.builder() .setCullState(RenderStateShards.NO_CULL) .createCompositeState(false) );}Using Custom Render Types
Section titled “Using Custom Render Types”In Entity Rendering
Section titled “In Entity Rendering”// Example: Using custom render type in entity rendererpublic class EnergyEntityRenderer extends EntityRenderer<EnergyEntity> { private static final RenderType ENERGY_RENDER_TYPE = CustomRenderTypes.ENERGY_FIELD;
@Override public void render(EnergyEntity entity, float partialTicks, PoseStack poseStack, MultiBufferSource bufferSource, int packedLight) { VertexConsumer vertexConsumer = bufferSource.getBuffer(ENERGY_RENDER_TYPE);
poseStack.push(); poseStack.translate(entity.getX(), entity.getY(), entity.getZ());
renderEnergyField(poseStack, vertexConsumer, packedLight);
poseStack.pop(); }
private void renderEnergyField(PoseStack poseStack, VertexConsumer vertexConsumer, int packedLight) { Matrix4f poseMatrix = poseStack.last().pose();
// Add vertices for energy field effect for (int i = 0; i < 8; i++) { float angle = (float) (i * Math.PI / 4.0); float x = (float) Math.cos(angle); float z = (float) Math.sin(angle);
vertexConsumer.vertex(poseMatrix, x, -0.5f, z) .color(1.0f, 0.5f, 1.0f, 0.7f) .uv(0.0f, 0.0f) .overlayCoords(OverlayTexture.NO_OVERLAY) .uv2(packedLight) .endVertex(); } }}In World Rendering
Section titled “In World Rendering”// Example: Using custom render type in world renderingpublic class CustomWorldRenderer { public void renderCustomBlocks(LevelRenderEvent event) { if (event.getStage() != RenderLevelStageEvent.Stage.AFTER_TRANSLUCENT_BLOCKS) { return; }
PoseStack poseStack = event.getPoseStack(); MultiBufferSource bufferSource = event.getVertexConsumers();
// Get all custom blocks in view List<CustomBlock> blocks = getCustomBlocksInView(event.getCamera());
// Group by render type for batching Map<RenderType, List<CustomBlock>> grouped = blocks.stream() .collect(Collectors.groupingBy(CustomBlock::getRenderType));
// Render each group for (Map.Entry<RenderType, List<CustomBlock>> entry : grouped.entrySet()) { RenderType renderType = entry.getKey(); List<CustomBlock> blockGroup = entry.getValue();
VertexConsumer vertexConsumer = bufferSource.getBuffer(renderType);
for (CustomBlock block : blockGroup) { renderCustomBlock(block, poseStack, vertexConsumer); } } }}Performance Considerations
Section titled “Performance Considerations”Render Type Sorting
Section titled “Render Type Sorting”Sort objects by render type to minimize state changes:
// Example: Efficient render type sortingpublic class OptimizedRenderer { public void renderObjectsEfficiently(List<RenderableObject> objects, PoseStack poseStack, MultiBufferSource bufferSource) { // Group objects by render type Map<RenderType, List<RenderableObject>> grouped = objects.stream() .collect(Collectors.groupingBy(RenderableObject::getRenderType));
// Render each group for (Map.Entry<RenderType, List<RenderableObject>> entry : grouped.entrySet()) { RenderType renderType = entry.getKey(); List<RenderableObject> group = entry.getValue();
VertexConsumer vertexConsumer = bufferSource.getBuffer(renderType);
// Render all objects with this render type for (RenderableObject obj : group) { obj.render(poseStack, vertexConsumer); } } }}Buffer Size Optimization
Section titled “Buffer Size Optimization”Choose appropriate buffer sizes for your render types:
// Example: Buffer size optimizationpublic class BufferSizeExamples { // Small buffers for simple objects public static final RenderType SMALL_PARTICLE = RenderType.create( "small_particle", DefaultVertexFormat.POSITION_COLOR, VertexFormat.Mode.QUADS, 64, // Small buffer for particle effects smallParticleState );
// Large buffers for complex geometry public static final RenderType COMPLEX_MODEL = RenderType.create( "complex_model", DefaultVertexFormat.NEW_ENTITY, VertexFormat.Mode.TRIANGLES, 8192, // Large buffer for detailed models complexModelState );
// Dynamic sizing based on expected content public static RenderType createDynamicRenderType(String name, VertexFormat format, int expectedVertices) { return RenderType.create( name, format, VertexFormat.Mode.QUADS, expectedVertices * format.getVertexSize(), defaultState ); }}Common Issues and Solutions
Section titled “Common Issues and Solutions”Render Type Not Found
Section titled “Render Type Not Found”Problem: Custom render type not registered Solution: Ensure render types are created in static initialization before use
Blend Mode Issues
Section titled “Blend Mode Issues”Problem: Unexpected blending behavior Solution: Check transparency state configuration and blend function parameters
Depth Testing Problems
Section titled “Depth Testing Problems”Problem: Objects rendering in wrong order Solution: Verify depth test state and sortOnUpload settings
Best Practices
Section titled “Best Practices”- Reuse render types instead of creating new ones
- Group by render type to minimize state changes
- Choose appropriate buffer sizes for expected content
- Use sorting for transparent objects
- Profile performance to identify bottlenecks
Next Steps
Section titled “Next Steps”- Custom Entity Renderers - Advanced entity rendering
- Performance Optimization - Advanced optimization techniques
- Shader Integration Examples - Complete shader implementations