diff --git a/src/main/java/net/coderbot/iris/gl/shader/ProgramCreator.java b/src/main/java/net/coderbot/iris/gl/shader/ProgramCreator.java index 54d06fc1ae..9a76e5a631 100644 --- a/src/main/java/net/coderbot/iris/gl/shader/ProgramCreator.java +++ b/src/main/java/net/coderbot/iris/gl/shader/ProgramCreator.java @@ -23,6 +23,7 @@ public static int create(String name, GlShader... shaders) { GlStateManager._glBindAttribLocation(program, 12, "mc_midTexCoord"); GlStateManager._glBindAttribLocation(program, 13, "at_tangent"); GlStateManager._glBindAttribLocation(program, 14, "at_midBlock"); + GlStateManager._glBindAttribLocation(program, 14, "at_velocity"); // TODO: more hardcoding for 1.17 GlStateManager._glBindAttribLocation(program, 0, "Position"); diff --git a/src/main/java/net/coderbot/iris/mixin/entity_render_context/MixinEntityRenderDispatcher.java b/src/main/java/net/coderbot/iris/mixin/entity_render_context/MixinEntityRenderDispatcher.java index c71a0d5c98..2efc7bc3b3 100644 --- a/src/main/java/net/coderbot/iris/mixin/entity_render_context/MixinEntityRenderDispatcher.java +++ b/src/main/java/net/coderbot/iris/mixin/entity_render_context/MixinEntityRenderDispatcher.java @@ -57,6 +57,7 @@ public class MixinEntityRenderDispatcher { } CapturedRenderingState.INSTANCE.setCurrentEntity(intId); + CapturedRenderingState.INSTANCE.setUniqueEntityId(entity.getId()); return type -> bufferSource.getBuffer(OuterWrappedRenderType.wrapExactlyOnce("iris:is_entity", type, EntityRenderStateShard.INSTANCE)); @@ -69,5 +70,6 @@ public class MixinEntityRenderDispatcher { PoseStack poseStack, MultiBufferSource bufferSource, int light, CallbackInfo ci) { CapturedRenderingState.INSTANCE.setCurrentEntity(0); + CapturedRenderingState.INSTANCE.setUniqueEntityId(0); } } diff --git a/src/main/java/net/coderbot/iris/mixin/vertices/MixinBufferBuilder.java b/src/main/java/net/coderbot/iris/mixin/vertices/MixinBufferBuilder.java index 15af5c7313..357c6d5940 100644 --- a/src/main/java/net/coderbot/iris/mixin/vertices/MixinBufferBuilder.java +++ b/src/main/java/net/coderbot/iris/mixin/vertices/MixinBufferBuilder.java @@ -103,6 +103,8 @@ public abstract class MixinBufferBuilder extends DefaultedVertexConsumer impleme @Shadow public abstract void nextElement(); + @Shadow public abstract void putFloat(int pBufferBuilder0, float pFloat1); + @Override public void iris$beginWithoutExtending(VertexFormat.Mode drawMode, VertexFormat vertexFormat) { iris$shouldNotExtend = true; @@ -204,20 +206,26 @@ public abstract class MixinBufferBuilder extends DefaultedVertexConsumer impleme this.nextElement(); // MID_TEXTURE_ELEMENT - this.putFloat(0, 0); - this.putFloat(4, 0); + this.putShort(0, (short) 0); + this.putShort(2, (short) 0); this.nextElement(); // TANGENT_ELEMENT this.putInt(0, 0); this.nextElement(); if (iris$isTerrain) { // MID_BLOCK_ELEMENT - int posIndex = this.nextElementByte - 48; + int posIndex = this.nextElementByte - 44; float x = buffer.getFloat(posIndex); float y = buffer.getFloat(posIndex + 4); float z = buffer.getFloat(posIndex + 8); this.putInt(0, ExtendedDataHelper.computeMidBlock(x, y, z, currentLocalPosX, currentLocalPosY, currentLocalPosZ)); this.nextElement(); + } else { + // VELOCITY_ELEMENT + this.putFloat(0, 0); + this.putFloat(4, 0); + this.putFloat(8, 0); + this.nextElement(); } vertexCount++; @@ -227,6 +235,11 @@ public abstract class MixinBufferBuilder extends DefaultedVertexConsumer impleme } } + @Unique + private static short encodeTexture(float value) { + return (short) (Math.min(0.99999997F, value) * 65536); + } + @Unique private void fillExtendedData(int vertexAmount) { vertexCount = 0; @@ -251,17 +264,20 @@ private void fillExtendedData(int vertexAmount) { int normalOffset; int tangentOffset; if (iris$isTerrain) { - midUOffset = 16; - midVOffset = 12; - normalOffset = 24; + midUOffset = 12; + midVOffset = 10; + normalOffset = 20; tangentOffset = 8; } else { - midUOffset = 14; - midVOffset = 10; - normalOffset = 24; - tangentOffset = 6; + midUOffset = 20; + midVOffset = 18; + normalOffset = 28; + tangentOffset = 16; } + short midUFinal = encodeTexture(midU); + short midVFinal = encodeTexture(midV); + if (vertexAmount == 3) { // NormalHelper.computeFaceNormalTri(normal, polygon); // Removed to enable smooth shaded triangles. Mods rendering triangles with bad normals need to recalculate their normals manually or otherwise shading might be inconsistent. @@ -270,8 +286,8 @@ private void fillExtendedData(int vertexAmount) { int tangent = NormalHelper.computeTangentSmooth(NormI8.unpackX(packedNormal), NormI8.unpackY(packedNormal), NormI8.unpackZ(packedNormal), polygon); - buffer.putFloat(nextElementByte - midUOffset - stride * vertex, midU); - buffer.putFloat(nextElementByte - midVOffset - stride * vertex, midV); + buffer.putShort(nextElementByte - midUOffset - stride * vertex, midUFinal); + buffer.putShort(nextElementByte - midVOffset - stride * vertex, midVFinal); buffer.putInt(nextElementByte - tangentOffset - stride * vertex, tangent); } } else { @@ -280,8 +296,8 @@ private void fillExtendedData(int vertexAmount) { int tangent = NormalHelper.computeTangent(normal.x, normal.y, normal.z, polygon); for (int vertex = 0; vertex < vertexAmount; vertex++) { - buffer.putFloat(nextElementByte - midUOffset - stride * vertex, midU); - buffer.putFloat(nextElementByte - midVOffset - stride * vertex, midV); + buffer.putShort(nextElementByte - midUOffset - stride * vertex, midUFinal); + buffer.putShort(nextElementByte - midVOffset - stride * vertex, midVFinal); buffer.putInt(nextElementByte - normalOffset - stride * vertex, packedNormal); buffer.putInt(nextElementByte - tangentOffset - stride * vertex, tangent); } diff --git a/src/main/java/net/coderbot/iris/pipeline/HandRenderer.java b/src/main/java/net/coderbot/iris/pipeline/HandRenderer.java index adfda3b805..d9c78d28b5 100644 --- a/src/main/java/net/coderbot/iris/pipeline/HandRenderer.java +++ b/src/main/java/net/coderbot/iris/pipeline/HandRenderer.java @@ -87,6 +87,8 @@ public void renderSolid(PoseStack poseStack, float tickDelta, Camera camera, Gam renderingSolid = true; + CapturedRenderingState.INSTANCE.setUniqueEntityId(Minecraft.getInstance().player.getId()); + gameRenderer.itemInHandRenderer.renderHandsWithItems(tickDelta, poseStack, bufferSource.getUnflushableWrapper(), Minecraft.getInstance().player, Minecraft.getInstance().getEntityRenderDispatcher().getPackedLightCoords(camera.getEntity(), tickDelta)); Minecraft.getInstance().getProfiler().pop(); @@ -102,6 +104,8 @@ public void renderSolid(PoseStack poseStack, float tickDelta, Camera camera, Gam pipeline.setPhase(WorldRenderingPhase.NONE); + CapturedRenderingState.INSTANCE.setUniqueEntityId(0); + ACTIVE = false; } @@ -120,6 +124,8 @@ public void renderTranslucent(PoseStack poseStack, float tickDelta, Camera camer setupGlState(gameRenderer, camera, poseStack, tickDelta); + CapturedRenderingState.INSTANCE.setUniqueEntityId(Minecraft.getInstance().player.getId()); + gameRenderer.itemInHandRenderer.renderHandsWithItems(tickDelta, poseStack, bufferSource, Minecraft.getInstance().player, Minecraft.getInstance().getEntityRenderDispatcher().getPackedLightCoords(camera.getEntity(), tickDelta)); poseStack.popPose(); @@ -132,6 +138,8 @@ public void renderTranslucent(PoseStack poseStack, float tickDelta, Camera camer pipeline.setPhase(WorldRenderingPhase.NONE); + CapturedRenderingState.INSTANCE.setUniqueEntityId(0); + ACTIVE = false; } diff --git a/src/main/java/net/coderbot/iris/pipeline/transform/transformer/VanillaTransformer.java b/src/main/java/net/coderbot/iris/pipeline/transform/transformer/VanillaTransformer.java index 78279d4100..5962e57ab7 100644 --- a/src/main/java/net/coderbot/iris/pipeline/transform/transformer/VanillaTransformer.java +++ b/src/main/java/net/coderbot/iris/pipeline/transform/transformer/VanillaTransformer.java @@ -26,6 +26,8 @@ public static void transform( CommonTransformer.transform(t, tree, root, parameters, false); + SodiumTransformer.replaceMidTexCoord(t, tree, root, (1.0f / 65536)); + if (parameters.type.glShaderType == ShaderType.VERTEX) { // Alias of gl_MultiTexCoord1 on 1.15+ for OptiFine // See https://github.com/IrisShaders/Iris/issues/1149 diff --git a/src/main/java/net/coderbot/iris/uniforms/CapturedRenderingState.java b/src/main/java/net/coderbot/iris/uniforms/CapturedRenderingState.java index 40e0301ea7..dd3e537ec5 100644 --- a/src/main/java/net/coderbot/iris/uniforms/CapturedRenderingState.java +++ b/src/main/java/net/coderbot/iris/uniforms/CapturedRenderingState.java @@ -19,6 +19,7 @@ public class CapturedRenderingState { private int currentRenderedBlockEntity; private int currentRenderedEntity = -1; + private int uniqueEntityId = -1; private int currentRenderedItem = -1; private float currentAlphaTest; @@ -118,4 +119,12 @@ public float getCloudTime() { public void setCloudTime(float cloudTime) { this.cloudTime = cloudTime; } + + public int getUniqueEntityId() { + return uniqueEntityId; + } + + public void setUniqueEntityId(int id) { + uniqueEntityId = id; + } } diff --git a/src/main/java/net/coderbot/iris/vertices/IrisVertexFormats.java b/src/main/java/net/coderbot/iris/vertices/IrisVertexFormats.java index ce6f711a8f..d18baf2ac9 100644 --- a/src/main/java/net/coderbot/iris/vertices/IrisVertexFormats.java +++ b/src/main/java/net/coderbot/iris/vertices/IrisVertexFormats.java @@ -13,6 +13,7 @@ public class IrisVertexFormats { public static final VertexFormatElement TANGENT_ELEMENT; public static final VertexFormatElement MID_BLOCK_ELEMENT; public static final VertexFormatElement PADDING_SHORT; + public static final VertexFormatElement VELOCITY_FLOAT; public static final VertexFormat TERRAIN; public static final VertexFormat ENTITY; @@ -21,10 +22,11 @@ public class IrisVertexFormats { static { ENTITY_ELEMENT = new VertexFormatElement(11, VertexFormatElement.Type.SHORT, VertexFormatElement.Usage.GENERIC, 2); ENTITY_ID_ELEMENT = new VertexFormatElement(11, VertexFormatElement.Type.USHORT, VertexFormatElement.Usage.UV, 3); - MID_TEXTURE_ELEMENT = new VertexFormatElement(12, VertexFormatElement.Type.FLOAT, VertexFormatElement.Usage.GENERIC, 2); + MID_TEXTURE_ELEMENT = new VertexFormatElement(12, VertexFormatElement.Type.USHORT, VertexFormatElement.Usage.GENERIC, 2); TANGENT_ELEMENT = new VertexFormatElement(13, VertexFormatElement.Type.BYTE, VertexFormatElement.Usage.GENERIC, 4); MID_BLOCK_ELEMENT = new VertexFormatElement(14, VertexFormatElement.Type.BYTE, VertexFormatElement.Usage.GENERIC, 3); PADDING_SHORT = new VertexFormatElement(1, VertexFormatElement.Type.SHORT, VertexFormatElement.Usage.PADDING, 1); + VELOCITY_FLOAT = new VertexFormatElement(14, VertexFormatElement.Type.FLOAT, VertexFormatElement.Usage.GENERIC, 3); ImmutableMap.Builder terrainElements = ImmutableMap.builder(); ImmutableMap.Builder entityElements = ImmutableMap.builder(); @@ -37,10 +39,10 @@ public class IrisVertexFormats { terrainElements.put("Normal", DefaultVertexFormat.ELEMENT_NORMAL); // 31 terrainElements.put("Padding", DefaultVertexFormat.ELEMENT_PADDING); // 32 terrainElements.put("mc_Entity", ENTITY_ELEMENT); // 36 - terrainElements.put("mc_midTexCoord", MID_TEXTURE_ELEMENT); // 44 - terrainElements.put("at_tangent", TANGENT_ELEMENT); // 48 - terrainElements.put("at_midBlock", MID_BLOCK_ELEMENT); // 51 - terrainElements.put("Padding2", DefaultVertexFormat.ELEMENT_PADDING); // 52 + terrainElements.put("mc_midTexCoord", MID_TEXTURE_ELEMENT); // 40 + terrainElements.put("at_tangent", TANGENT_ELEMENT); // 44 + terrainElements.put("at_midBlock", MID_BLOCK_ELEMENT); // 47 + terrainElements.put("Padding2", DefaultVertexFormat.ELEMENT_PADDING); // 48 entityElements.put("Position", DefaultVertexFormat.ELEMENT_POSITION); // 12 entityElements.put("Color", DefaultVertexFormat.ELEMENT_COLOR); // 16 @@ -50,9 +52,9 @@ public class IrisVertexFormats { entityElements.put("Normal", DefaultVertexFormat.ELEMENT_NORMAL); // 35 entityElements.put("Padding", DefaultVertexFormat.ELEMENT_PADDING); // 36 entityElements.put("iris_Entity", ENTITY_ID_ELEMENT); // 40 - entityElements.put("mc_midTexCoord", MID_TEXTURE_ELEMENT); // 48 - entityElements.put("at_tangent", TANGENT_ELEMENT); // 52 - entityElements.put("Padding2", PADDING_SHORT); // 52 + entityElements.put("mc_midTexCoord", MID_TEXTURE_ELEMENT); // 44 + entityElements.put("at_tangent", TANGENT_ELEMENT); // 48 + entityElements.put("at_velocity", VELOCITY_FLOAT); // 60 cloudsElements.put("Position", DefaultVertexFormat.ELEMENT_POSITION); // 12 cloudsElements.put("Color", DefaultVertexFormat.ELEMENT_COLOR); // 16 @@ -62,6 +64,8 @@ public class IrisVertexFormats { TERRAIN = new VertexFormat(terrainElements.build()); ENTITY = new VertexFormat(entityElements.build()); CLOUDS = new VertexFormat(cloudsElements.build()); + + debug(ENTITY); } private static void debug(VertexFormat format) { diff --git a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/impl/entities/IrisModelCuboid.java b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/impl/entities/IrisModelCuboid.java new file mode 100644 index 0000000000..75605a1aa4 --- /dev/null +++ b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/impl/entities/IrisModelCuboid.java @@ -0,0 +1,165 @@ +package net.coderbot.iris.compat.sodium.impl.entities; + +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import net.caffeinemc.mods.sodium.api.math.MatrixHelper; +import net.coderbot.iris.Iris; +import net.coderbot.iris.shadows.ShadowRenderingState; +import net.coderbot.iris.uniforms.CapturedRenderingState; +import net.minecraft.core.Direction; +import org.joml.*; + +import java.util.Set; + +public class IrisModelCuboid { + public final Quad[] quads; + + private final Vector3f[] vertices; + private final Vector3f[] shared; + private final Vector3f[] previous; + private final Int2ObjectOpenHashMap idToHistory = new Int2ObjectOpenHashMap<>(); + + public IrisModelCuboid(int u, int v, float x1, float y1, float z1, float sizeX, float sizeY, float sizeZ, float extraX, float extraY, float extraZ, boolean mirror, float textureWidth, float textureHeight, Set renderDirections) { + float x2 = x1 + sizeX; + float y2 = y1 + sizeY; + float z2 = z1 + sizeZ; + + x1 -= extraX; + y1 -= extraY; + z1 -= extraZ; + + x2 += extraX; + y2 += extraY; + z2 += extraZ; + + if (mirror) { + float i = x2; + x2 = x1; + x1 = i; + } + + Vector3f[] vertices = new Vector3f[8]; + vertices[0] = new Vector3f(x1, y1, z1); + vertices[1] = new Vector3f(x2, y1, z1); + vertices[2] = new Vector3f(x2, y2, z1); + vertices[3] = new Vector3f(x1, y2, z1); + vertices[4] = new Vector3f(x1, y1, z2); + vertices[5] = new Vector3f(x2, y1, z2); + vertices[6] = new Vector3f(x2, y2, z2); + vertices[7] = new Vector3f(x1, y2, z2); + + Vector3f[] shared = new Vector3f[8]; + Vector3f[] previous = new Vector3f[8]; + + for (int i = 0; i < 8; i++) { + vertices[i].div(16.0f); + shared[i] = new Vector3f(Float.NaN); + previous[i] = new Vector3f(Float.NaN); + } + + float u0 = (float) u; + float u1 = (float) u + sizeZ; + float u2 = (float) u + sizeZ + sizeX; + float u3 = (float) u + sizeZ + sizeX + sizeX; + float u4 = (float) u + sizeZ + sizeX + sizeZ; + float u5 = (float) u + sizeZ + sizeX + sizeZ + sizeX; + + float v0 = (float) v; + float v1 = (float) v + sizeZ; + float v2 = (float) v + sizeZ + sizeY; + + var sides = new Quad[6]; + + if (renderDirections.contains(Direction.DOWN)) { + sides[2] = new Quad(new Vector3f[] { shared[5], shared[4], shared[0], shared[1] }, new Vector3f[] { previous[5], previous[4], previous[0], previous[1] }, u1, v0, u2, v1, textureWidth, textureHeight, mirror, Direction.DOWN); + } + + if (renderDirections.contains(Direction.UP)) { + sides[3] = new Quad(new Vector3f[] { shared[2], shared[3], shared[7], shared[6] }, new Vector3f[] { previous[2], previous[3], previous[7], previous[6] }, u2, v1, u3, v0, textureWidth, textureHeight, mirror, Direction.UP); + } + + if (renderDirections.contains(Direction.WEST)) { + sides[1] = new Quad(new Vector3f[] { shared[0], shared[4], shared[7], shared[3] }, new Vector3f[] { previous[0], previous[4], previous[7], previous[3] }, u0, v1, u1, v2, textureWidth, textureHeight, mirror, Direction.WEST); + } + + if (renderDirections.contains(Direction.NORTH)) { + sides[4] = new Quad(new Vector3f[] { shared[1], shared[0], shared[3], shared[2] }, new Vector3f[] { previous[1], previous[0], previous[3], previous[2] }, u1, v1, u2, v2, textureWidth, textureHeight, mirror, Direction.NORTH); + } + + if (renderDirections.contains(Direction.EAST)) { + sides[0] = new Quad(new Vector3f[] { shared[5], shared[1], shared[2], shared[6] }, new Vector3f[] { previous[5], previous[1], previous[2], previous[6] }, u2, v1, u4, v2, textureWidth, textureHeight, mirror, Direction.EAST); + } + + if (renderDirections.contains(Direction.SOUTH)) { + sides[5] = new Quad(new Vector3f[] { shared[4], shared[5], shared[6], shared[7] }, new Vector3f[] { previous[4], previous[5], previous[6], previous[7] }, u4, v1, u5, v2, textureWidth, textureHeight, mirror, Direction.SOUTH); + } + this.quads = sides; + + this.vertices = vertices; + this.shared = shared; + this.previous = previous; + } + + public void updateVertices(Matrix4f mat) { + VertexHistory history = idToHistory.computeIfAbsent(CapturedRenderingState.INSTANCE.getUniqueEntityId(), VertexHistory::new); + for (int i = 0; i < 8; i++) { + var src = this.vertices[i]; + var dst = this.shared[i]; + + src.mulPosition(mat, dst); + + if (!ShadowRenderingState.areShadowsCurrentlyBeingRendered()) { + previous[i].set(history.storedPositions[i]); + history.storedPositions[i].set(dst); + } + } + + } + + public static class Quad { + public final Vector3f[] positions; + public final Vector2f[] textures; + public final Vector3f[] prevPositions; + + public final Vector3f direction; + + public Quad(Vector3f[] positions, Vector3f[] prevPositions, float u1, float v1, float u2, float v2, float textureWidth, float textureHeight, boolean flip, Direction direction) { + var textures = new Vector2f[4]; + textures[0] = new Vector2f(u2 / textureWidth, v1 / textureHeight); + textures[1] = new Vector2f(u1 / textureWidth, v1 / textureHeight); + textures[2] = new Vector2f(u1 / textureWidth, v2 / textureHeight); + textures[3] = new Vector2f(u2 / textureWidth, v2 / textureHeight); + + if (flip) { + int len = positions.length; + + for (int i = 0; i < len / 2; ++i) { + var pos = positions[i]; + positions[i] = positions[len - 1 - i]; + positions[len - 1 - i] = pos; + + var pos2 = prevPositions[i]; + prevPositions[i] = prevPositions[len - 1 - i]; + prevPositions[len - 1 - i] = pos2; + + var tex = textures[i]; + textures[i] = textures[len - 1 - i]; + textures[len - 1 - i] = tex; + } + } + + this.positions = positions; + this.prevPositions = prevPositions; + this.textures = textures; + + this.direction = direction.step(); + + if (flip) { + this.direction.mul(-1.0F, 1.0F, 1.0F); + } + } + + public int getNormal(Matrix3f mat) { + return MatrixHelper.transformNormal(mat, this.direction.x, this.direction.y, this.direction.z); + } + } +} diff --git a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/impl/entities/IrisModelCuboidAccessor.java b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/impl/entities/IrisModelCuboidAccessor.java new file mode 100644 index 0000000000..b575c59169 --- /dev/null +++ b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/impl/entities/IrisModelCuboidAccessor.java @@ -0,0 +1,5 @@ +package net.coderbot.iris.compat.sodium.impl.entities; + +public interface IrisModelCuboidAccessor { + IrisModelCuboid iris$copy(); +} diff --git a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/impl/entities/VertexHistory.java b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/impl/entities/VertexHistory.java new file mode 100644 index 0000000000..308aff1c08 --- /dev/null +++ b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/impl/entities/VertexHistory.java @@ -0,0 +1,13 @@ +package net.coderbot.iris.compat.sodium.impl.entities; + +import org.joml.Vector3f; + +public class VertexHistory { + public Vector3f[] storedPositions = new Vector3f[8]; + + public VertexHistory(int id) { + for (int i = 0; i < 8; i++) { + storedPositions[i] = new Vector3f(); + } + } +} diff --git a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/impl/vertex_format/entity_xhfp/EntityVertex.java b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/impl/vertex_format/entity_xhfp/EntityVertex.java index 99dc7ed331..ef135ba008 100644 --- a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/impl/vertex_format/entity_xhfp/EntityVertex.java +++ b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/impl/vertex_format/entity_xhfp/EntityVertex.java @@ -29,12 +29,12 @@ public final class EntityVertex { private static final int OFFSET_OVERLAY = 24; private static final int OFFSET_LIGHT = 28; private static final int OFFSET_NORMAL = 32; - private static final int OFFSET_TANGENT = 50; + private static final int OFFSET_TANGENT = 46; private static Vector3f lastNormal = new Vector3f(); public static void write(long ptr, - float x, float y, float z, int color, float u, float v, float midU, float midV, int light, int overlay, int normal, int tangent) { + float x, float y, float z, int color, float u, float v, short midU, short midV, int light, int overlay, int normal, int tangent) { MemoryUtil.memPutFloat(ptr + OFFSET_POSITION + 0, x); MemoryUtil.memPutFloat(ptr + OFFSET_POSITION + 4, y); MemoryUtil.memPutFloat(ptr + OFFSET_POSITION + 8, z); @@ -51,13 +51,25 @@ public static void write(long ptr, MemoryUtil.memPutInt(ptr + OFFSET_NORMAL, normal); MemoryUtil.memPutInt(ptr + OFFSET_TANGENT, tangent); - MemoryUtil.memPutFloat(ptr + OFFSET_MID_TEXTURE, midU); - MemoryUtil.memPutFloat(ptr + OFFSET_MID_TEXTURE + 4, midV); + MemoryUtil.memPutShort(ptr + OFFSET_MID_TEXTURE, midU); + MemoryUtil.memPutShort(ptr + OFFSET_MID_TEXTURE + 2, midV); MemoryUtil.memPutShort(ptr + 36, (short) CapturedRenderingState.INSTANCE.getCurrentRenderedEntity()); MemoryUtil.memPutShort(ptr + 38, (short) CapturedRenderingState.INSTANCE.getCurrentRenderedBlockEntity()); MemoryUtil.memPutShort(ptr + 40, (short) CapturedRenderingState.INSTANCE.getCurrentRenderedItem()); + } + + public static void writeWithVelocity(long ptr, + float x, float y, float z, float prevX, float prevY, float prevZ, int color, float u, float v, short midU, short midV, int light, int overlay, int normal, int tangent) { + write(ptr, x, y, z, color, u, v, midU, midV, light, overlay, normal, tangent); + + MemoryUtil.memPutFloat(ptr + 50, x - prevX); + MemoryUtil.memPutFloat(ptr + 54, y - prevY); + MemoryUtil.memPutFloat(ptr + 58, z - prevZ); + } + private static short encodeTexture(float value) { + return (short) (Math.min(0.99999997F, value) * 65536); } public static void write2(long ptr, diff --git a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/copyEntity/CuboidMixin.java b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/copyEntity/CuboidMixin.java index 59e46b063f..fabadf296c 100644 --- a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/copyEntity/CuboidMixin.java +++ b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/copyEntity/CuboidMixin.java @@ -1,7 +1,7 @@ package net.coderbot.iris.compat.sodium.mixin.copyEntity; -import me.jellysquid.mods.sodium.client.model.ModelCuboidAccessor; -import me.jellysquid.mods.sodium.client.render.immediate.model.ModelCuboid; +import net.coderbot.iris.compat.sodium.impl.entities.IrisModelCuboid; +import net.coderbot.iris.compat.sodium.impl.entities.IrisModelCuboidAccessor; import net.minecraft.client.model.geom.ModelPart; import net.minecraft.core.Direction; import org.objectweb.asm.Opcodes; @@ -14,18 +14,18 @@ import java.util.Set; @Mixin(ModelPart.Cube.class) -public class CuboidMixin implements ModelCuboidAccessor { +public class CuboidMixin implements IrisModelCuboidAccessor { @Unique - private ModelCuboid sodium$cuboid; + private IrisModelCuboid iris$cuboid; // Inject at the start of the function, so we don't capture modified locals @Inject(method = "", at = @At(value = "FIELD", opcode = Opcodes.PUTFIELD, target = "Lnet/minecraft/client/model/geom/ModelPart$Cube;polygons:[Lnet/minecraft/client/model/geom/ModelPart$Polygon;", ordinal = 0)) private void onInit(int u, int v, float x, float y, float z, float sizeX, float sizeY, float sizeZ, float extraX, float extraY, float extraZ, boolean mirror, float textureWidth, float textureHeight, Set renderDirections, CallbackInfo ci) { - this.sodium$cuboid = new ModelCuboid(u, v, x, y, z, sizeX, sizeY, sizeZ, extraX, extraY, extraZ, mirror, textureWidth, textureHeight, renderDirections); + this.iris$cuboid = new IrisModelCuboid(u, v, x, y, z, sizeX, sizeY, sizeZ, extraX, extraY, extraZ, mirror, textureWidth, textureHeight, renderDirections); } @Override - public ModelCuboid sodium$copy() { - return this.sodium$cuboid; + public IrisModelCuboid iris$copy() { + return this.iris$cuboid; } } diff --git a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/copyEntity/ModelPartMixin.java b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/copyEntity/ModelPartMixin.java index a5c2885e0f..a33cb923cc 100644 --- a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/copyEntity/ModelPartMixin.java +++ b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/copyEntity/ModelPartMixin.java @@ -8,6 +8,13 @@ import net.caffeinemc.mods.sodium.api.vertex.format.common.ModelVertex; import net.caffeinemc.mods.sodium.api.util.ColorABGR; import net.caffeinemc.mods.sodium.api.math.MatrixHelper; +import net.coderbot.iris.compat.sodium.impl.entities.IrisModelCuboid; +import net.coderbot.iris.compat.sodium.impl.entities.IrisModelCuboidAccessor; +import net.coderbot.iris.compat.sodium.impl.vertex_format.entity_xhfp.EntityVertex; +import net.coderbot.iris.vertices.ImmediateState; +import net.coderbot.iris.vertices.NormI8; +import net.coderbot.iris.vertices.NormalHelper; +import net.irisshaders.iris.api.v0.IrisApi; import net.minecraft.client.model.geom.ModelPart; import org.lwjgl.system.MemoryStack; import org.spongepowered.asm.mixin.Mixin; @@ -36,20 +43,27 @@ public class ModelPartMixin { @Shadow public float zScale; @Unique - private ModelCuboid[] sodium$cuboids; + private IrisModelCuboid[] sodium$cuboids; @Inject(method = "", at = @At("RETURN")) private void onInit(List cuboids, Map children, CallbackInfo ci) { - var copies = new ModelCuboid[cuboids.size()]; + var copies = new IrisModelCuboid[cuboids.size()]; for (int i = 0; i < cuboids.size(); i++) { - var accessor = (ModelCuboidAccessor) cuboids.get(i); - copies[i] = accessor.sodium$copy(); + var accessor = (IrisModelCuboidAccessor) cuboids.get(i); + copies[i] = accessor.iris$copy(); } this.sodium$cuboids = copies; } + private boolean extend() { + return IrisApi.getInstance().isShaderPackInUse() && ImmediateState.renderWithExtendedVertexFormat; + } + private static short encodeTexture(float value) { + return (short) (Math.min(0.99999997F, value) * 65536); + } + /** * @author JellySquid * @reason Use optimized vertex writer, avoid allocations, use quick matrix transformations @@ -65,33 +79,67 @@ private void renderCuboidsFast(PoseStack.Pose matrices, VertexConsumer vertexCon int color = ColorABGR.pack(red, green, blue, alpha); - for (ModelCuboid cuboid : this.sodium$cuboids) { + for (IrisModelCuboid cuboid : this.sodium$cuboids) { cuboid.updateVertices(matrices.pose()); + boolean extend = extend(); + try (MemoryStack stack = MemoryStack.stackPush()) { long buffer = stack.nmalloc(4 * 6 * ModelVertex.STRIDE); long ptr = buffer; int count = 0; - for (ModelCuboid.Quad quad : cuboid.quads) { + for (IrisModelCuboid.Quad quad : cuboid.quads) { if (quad == null) continue; var normal = quad.getNormal(matrices.normal()); - for (int i = 0; i < 4; i++) { - var pos = quad.positions[i]; - var tex = quad.textures[i]; + float midU = 0, midV = 0; + int tangent = 0; + + if (extend) { + for (int i = 0; i < 4; i++) { + midU += quad.textures[i].x; + midV += quad.textures[i].y; + } + + midU *= 0.25; + midV *= 0.25; + + tangent = NormalHelper.computeTangent(NormI8.unpackX(normal), NormI8.unpackY(normal), NormI8.unpackZ(normal), quad.positions[0].x, quad.positions[0].y, quad.positions[0].z, quad.textures[0].x, quad.textures[0].y, + quad.positions[1].x, quad.positions[1].y, quad.positions[1].z, quad.textures[1].x, quad.textures[1].y, + quad.positions[2].x, quad.positions[2].y, quad.positions[2].z, quad.textures[2].x, quad.textures[2].y + ); + } + + if (extend) { + short midUFinal = encodeTexture(midU); + short midVFinal = encodeTexture(midV); + for (int i = 0; i < 4; i++) { + var pos = quad.positions[i]; + var pos2 = quad.prevPositions[i]; + var tex = quad.textures[i]; + + EntityVertex.writeWithVelocity(ptr, pos.x, pos.y, pos.z, pos2.x, pos2.y, pos2.z, color, tex.x, tex.y, midUFinal, midVFinal, light, overlay, normal, tangent); + + ptr += EntityVertex.STRIDE; + } + } else { + for (int i = 0; i < 4; i++) { + var pos = quad.positions[i]; + var tex = quad.textures[i]; - ModelVertex.write(ptr, pos.x, pos.y, pos.z, color, tex.x, tex.y, overlay, light, normal); + ModelVertex.write(ptr, pos.x, pos.y, pos.z, color, tex.x, tex.y, overlay, light, normal); - ptr += ModelVertex.STRIDE; + ptr += ModelVertex.STRIDE; + } } count += 4; } - writer.push(stack, buffer, count, ModelVertex.FORMAT); + writer.push(stack, buffer, count, extend ? EntityVertex.FORMAT : ModelVertex.FORMAT); } } } diff --git a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/copyEntity/shadows/EntityRenderDispatcherMixin.java b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/copyEntity/shadows/EntityRenderDispatcherMixin.java index b7add70524..b96c30b827 100644 --- a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/copyEntity/shadows/EntityRenderDispatcherMixin.java +++ b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/copyEntity/shadows/EntityRenderDispatcherMixin.java @@ -106,8 +106,8 @@ private static void renderShadowPart(PoseStack.Pose matrices, VertexConsumer ver ); } - float midU = (u1 + u2) / 2; - float midV = (v1 + v2) / 2; + short midU = encodeTexture((u1 + u2) / 2); + short midV = encodeTexture((v1 + v2) / 2); int stride = extended ? EntityVertex.STRIDE : ModelVertex.STRIDE; @@ -146,7 +146,11 @@ private static void renderShadowPart(PoseStack.Pose matrices, VertexConsumer ver } } - @Unique + private static short encodeTexture(float value) { + return (short) (Math.min(0.99999997F, value) * 65536); + } + + @Unique private static void writeShadowVertex(long ptr, Matrix4f matPosition, float x, float y, float z, float u, float v, int color, int normal) { // The transformed position vector float xt = MatrixHelper.transformPositionX(matPosition, x, y, z); @@ -157,7 +161,7 @@ private static void writeShadowVertex(long ptr, Matrix4f matPosition, float x, f } @Unique - private static void writeShadowVertexIris(long ptr, Matrix4f matPosition, float x, float y, float z, float u, float v, int color, float midU, float midV, int normal, int tangent) { + private static void writeShadowVertexIris(long ptr, Matrix4f matPosition, float x, float y, float z, float u, float v, int color, short midU, short midV, int normal, int tangent) { // The transformed position vector float xt = MatrixHelper.transformPositionX(matPosition, x, y, z); float yt = MatrixHelper.transformPositionY(matPosition, x, y, z); diff --git a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/fast_render/MixinModelPart.java b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/fast_render/MixinModelPart.java index 4d833e7d34..f1c78608f0 100644 --- a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/fast_render/MixinModelPart.java +++ b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/fast_render/MixinModelPart.java @@ -97,7 +97,6 @@ private void compile(PoseStack.Pose matrices, VertexConsumer vertexConsumer, int var tex = quad.textures[i]; if (extend) { - EntityVertex.write(ptr, pos.x, pos.y, pos.z, color, tex.x, tex.y, midU, midV, light, overlay, normal, tangent); } else { ModelVertex.write(ptr, pos.x, pos.y, pos.z, color, tex.x, tex.y, light, overlay, normal); } diff --git a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/vertex_format/entity/MixinEntityRenderDispatcher.java b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/vertex_format/entity/MixinEntityRenderDispatcher.java index f100803fd9..c05af9938f 100644 --- a/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/vertex_format/entity/MixinEntityRenderDispatcher.java +++ b/src/sodiumCompatibility/java/net/coderbot/iris/compat/sodium/mixin/vertex_format/entity/MixinEntityRenderDispatcher.java @@ -55,8 +55,8 @@ private static void renderShadowPart(PoseStack.Pose matrices, VertexConsumer ver ); } - float midU = (u1 + u2) / 2; - float midV = (v1 + v2) / 2; + short midU = encodeTexture((u1 + u2) / 2); + short midV = encodeTexture((v1 + v2) / 2); int stride = extended ? EntityVertex.STRIDE : ModelVertex.STRIDE; try (MemoryStack stack = MemoryStack.stackPush()) { @@ -93,8 +93,14 @@ private static void renderShadowPart(PoseStack.Pose matrices, VertexConsumer ver .push(stack, buffer, 4, extended ? EntityVertex.FORMAT : ModelVertex.FORMAT); } } + private static short encodeTexture(float value) { + return (short) (Math.min(0.99999997F, value) * 65536); + } + + @Unique + private static short encodedMid = encodeTexture(0.25f); - private static void writeShadowVertexIris(long ptr, Matrix4f matPosition, float x, float y, float z, float u, float v, int color, float midU, float midV, int normal, int tangent) { + private static void writeShadowVertexIris(long ptr, Matrix4f matPosition, float x, float y, float z, float u, float v, int color, short midU, short midV, int normal, int tangent) { // The transformed position vector float xt = MatrixHelper.transformPositionX(matPosition, x, y, z); float yt = MatrixHelper.transformPositionY(matPosition, x, y, z);