mojira.dev

Pepper_Bell

Assigned

No issues.

Reported

MC-275355 Block models of magma blocks and active sculk sensors do not use light_emission Invalid MC-260323 BootstapContext Typo Invalid MC-245474 Enchantment foil on oppositely facing quads z-fights Awaiting Response MC-225170 Normal matrix scaling broken in some situations Fixed

Comments

Quads from block and item models always go through VertexConsumer#putBulkData. However, light_emission is only applied right after flat lighting and smooth lighting during block model buffering and ignored during item model buffering. Considering that this feature would have been easier to implement by applying the light value inside of VertexConsumer#putBulkData instead, the fact that items do not support light_emission seems intentional to me. However, I agree that items should support it.

I was able to create a Fabric mod that fixes this issue by changing Minecraft's code. Hopefully the way I resolved this issue and the following insights will be useful.

The issue was mostly fixed after the following change in com.mojang.blaze3d.vertex.PoseStack.

public void scale(float f, float g, float h) {
	PoseStack.Pose pose = (PoseStack.Pose)this.poseStack.getLast();
	pose.pose.scale(f, g, h);
	if (f == g && g == h) {
		if (f > 0.0F) {
			return;
		}

		pose.normal.scale(-1.0F);
	}

	float i = 1.0F / f;
	float j = 1.0F / g;
	float k = 1.0F / h;
	// Commented vanilla code
//	float l = Mth.fastInvCubeRoot(i * j * k);
//	pose.normal.scale(l * i, l * j, l * k);
	// New code
	pose.normal.scale(i, j, k);
}

However, after this change, the top of nose got darker the more the nose was scaled up. This is because Minecraft does not normalize the normal vector after it is transformed by the normal matrix. When the fragment shader uses the vertex normal vector to calculate lighting, it is not unit length, which results in dark lighting. Normalizing the vector after it is transformed in net.minecraft.client.model.geom.ModelPart$Cube#compile fixes this issue, and thus completely resolves the initial issue.

public void compile(PoseStack.Pose pose, VertexConsumer vertexConsumer, int i, int j, float f, float g, float h, float k) {
	Matrix4f matrix4f = pose.pose();
	Matrix3f matrix3f = pose.normal();

	for (ModelPart.Polygon polygon : this.polygons) {
		Vector3f vector3f = matrix3f.transform(new Vector3f((Vector3fc)polygon.normal));
		// Added code: normalize the vector
		vector3f.normalize();
		float l = vector3f.x();
		float m = vector3f.y();
		float n = vector3f.z();

		for (ModelPart.Vertex vertex : polygon.vertices) {
			float o = vertex.pos.x() / 16.0F;
			float p = vertex.pos.y() / 16.0F;
			float q = vertex.pos.z() / 16.0F;
			Vector4f vector4f = matrix4f.transform(new Vector4f(o, p, q, 1.0F));
			vertexConsumer.vertex(vector4f.x(), vector4f.y(), vector4f.z(), f, g, h, k, vertex.u, vertex.v, j, i, l, m, n);
		}
	}
}

MC-176864 is caused by a series of model matrix transformations reversing the vertex order for all item model quads. Minecraft renders items (that are not translucent block items) with culling enabled, meaning that quads only render on the side from which the vertex order is counter-clockwise. Since the order is reversed in the opposite hand, all quads render from the wrong side.

From my testing, however, it does seem like the lighting bugs described in that issue are directly related to this issue. The lighting was fixed once my suggested changes were applied.

In vanilla, the conditions for invalid values are usually met only when the model view PoseStack is scaled, but this stack's normal matrix does not matter since it is not uploaded to the shader or used in any other way.

The only places where the invalid values are actually used are in SignEditScreen#render, LoomScreen#renderBg, LoomScreen#renderPattern, and GameRenderer#renderItemActivationAnimation. GameRenderer#renderItemActivationAnimation is the only one that produces a visual effect. Right after being revived by a totem of undying, the totem in the activation animation will have lighting that does not transition smoothly as it spins. Applying my suggested changes fixes this.