Render Types and Queue
Most mods can use PulseLib's renderers without touching the render queue directly. This page exists for the cases where you need to understand why PulseLib does not use vanilla RenderType values and where custom rendering should be inserted.
PulseLib models are triangle meshes loaded from glTF/GLB or another model loader. Vanilla baked block models are mostly quad-based, so PulseLib provides its own triangle render types, shaders, vertex format, and instanced queue. That is why examples use PRenderTypes instead of RenderType.entityCutout or block render types.
Which render type should I choose?¶
Use the simplest type that matches the visual result:
trianglesSolidfor opaque models.trianglesCutoutfor hard alpha cutouts, like holes or masked pixels.trianglesTranslucentfor glass-like transparency.trianglesGuifor direct GUI drawing.trianglesEmissiveCutoutandtrianglesEmissiveTranslucentfor explicit emissive custom rendering.trianglesInstantCutoutandtrianglesInstantTranslucentfor immediate baked-bone drawing.
In a renderer constructor this usually looks like:
If a texture is marked as emissive, the default renderers automatically switch the mesh to the matching emissive variant with PRenderTypes.RenderTypeProvider.emissiveVariant(...). You normally do not need to choose an emissive render type yourself unless you are writing custom draw code.
Emissive texture metadata is described on Textures and Emissive.
Why vanilla RenderType is not enough¶
PulseLib's baked meshes use PRenderTypes.VertexFormatProvider.POSITION_TEX_NORMAL. The shaders also expect per-instance data: transform matrix, color, light, and overlay. A vanilla render type may compile and still render incorrectly because its shader and vertex format do not match the data PulseLib sends.
If you create a custom render type, keep these requirements:
VertexFormat.Mode.TRIANGLESPRenderTypes.VertexFormatProvider.POSITION_TEX_NORMAL- a shader that understands PulseLib's uniforms and instance attributes
- a transparency state that matches how the queue should sort the mesh
For most mods, it is safer to start from PulseLib's existing render types and only add a new one when you need a genuinely different shader state.
What the queue does¶
PRenderQueue batches identical meshes together and renders many instances with one instanced draw call. That is important for animated block entities and entities: every object can have its own transform and animation pose, but the GPU can still draw repeated mesh buffers efficiently.
The queue has a few stages:
SOLID_BLOCKSfor solid block entity meshes.TRANSLUCENT_BLOCKSfor transparent block/entity-adjacent meshes.ENTITIESfor entity and hand-held item rendering.GUIfor GUI rendering.
Normal renderers submit into these stages for you. PRenderStagesHandler handles flushing them at the right time.
When to submit manually¶
Manual queue submission is an advanced escape hatch. Use it when you already have a baked PulseLib mesh and want to draw extra geometry in the same pipeline.
PRenderQueue.submit(
PRenderQueue.RenderStage.ENTITIES,
renderType,
bakedMesh,
new PRenderQueue.InstanceData(matrix, 0xFFFFFFFF, packedLight, packedOverlay));
If you only need to draw a vanilla item, text, a beam, or a simple effect, add your own submit node from preSubmit or postSubmit with the supplied SubmitNodeCollector. That keeps vanilla rendering in vanilla's pipeline and PulseLib mesh rendering in PulseLib's pipeline.
Renderer hooks¶
Every PulseLib renderer has the same three-stage flow:
preSubmitruns before the model is submitted.trueSubmitis the normal PulseLib model submission.postSubmitruns after the model is submitted.
A typical customization is small:
@Override
public void postSubmit(PoseStack poseStack,
PEntityRenderState.LivingImpl<RobotEntity> renderState,
CameraRenderState cameraRenderState,
SubmitNodeCollector submitNodeCollector) {
// Add custom submit nodes here, or submit extra PulseLib-compatible meshes.
}
Classes used: