Fabric API

Fabric API

106M Downloads

Indigo ItemRenderContext implementation renders models without transforms six times

SigmundGranaas opened this issue ยท 1 comments

commented

How the flaw can be encountered?

I am developing a mod, which enables you to customise most things about your tools. Due to the number of combinations, I have pre-baked models for every individual modification, which is reconstructed from an ItemStack and assembled from a map of FabricBakedModel. Every part of the tool is rendered individually using EmitItemQuads(). Because these models have been constructed from a JsonUnbakedModel it will eventually be passed down to vanilla renderer using the FallbackConsumer in ItemRenderContext. The method which causes this is fallbackConsumer(BakedModel model).

private void fallbackConsumer(BakedModel model) {
		if (hasTransform()) {
			// if there's a transform in effect, convert to mesh-based quads so that we can apply it
			for (int i = 0; i <= ModelHelper.NULL_FACE_ID; i++) {
				random.setSeed(ITEM_RANDOM_SEED);
				final Direction cullFace = ModelHelper.faceFromIndex(i);
				renderFallbackWithTransform(model.getQuads((BlockState) null, cullFace, random), cullFace);
			}
		} else {
			for (int i = 0; i <= ModelHelper.NULL_FACE_ID; i++) {
				vanillaHandler.accept(model, itemStack, lightmap, overlay, matrixStack, modelVertexConsumer);
			}
		}
	}

The problem is the else statement, as the loop does not seem to do anything with the faces of the model, and it just renders the item six times(As ModelHelper.NULL_FACE_ID is 6). I don't understand if this is a simple bug, or if it is supposed to do this. This is normally invisible like in this scenario when rendering normal items without any effects, like this:

Enchanted Netherite pickaxe is here for reference
without_glint_desired

But if we apply a Glint to the item, we can see that the effect is a lot stronger, as it is stacked six times.

Glinted_duplicated_toolpart

We can see all six models being rendered if we apply a translation to the MatrixStack matrices.translate(+0.2, +0.5, 0.0); as a mixin to renderBakedItemModel()@ItemRenderer. This is only done to accentuate the situation.
Glinted_duplicated_transform_toolpart

If we only render one in six of these models using a silly workaround, we can see the desired effect:

Glinted_desired_toolpart

This becomes quite absurd when rendering a tool which consists of several models with the same translations:

tool_transformed

If we apply Glint to the Tool when rendering, it will end up stacking the effect which becomes quite noticeable. Keep in mind, every part of the tool gets its own glint applied, so the effect stacks a lot more when there are more models being rendered from a single tool. Ideally I should only have one model responsible for the glint, but that's on me to fix. However, the glint still stacks because there are six models being rendered where I guess there should only be one.

Glinted_tool_duplicated

When using a hacky workaround to only render 1 out of every six models which is being passed on to renderBakedItemModel() and only applying glint to one of the models on the tool I can get the desired effect.

Glinted_desired_toolpng

Notes

I am quite new to Modding, and very inexperienced with rendering in general, so this might be the intended functionality. I am probably misusing the rendering API in more ways than one, but this seemed like an easy to miss bug, so I am submitting it.

commented

In particular, it seems like #334 introduced the logic for transforms, and #394 did not properly remove the looping when the vanilla handler changed to not require passing quads for each face.