Skip to content

Commit

Permalink
Extremely complicated code
Browse files Browse the repository at this point in the history
  • Loading branch information
IMS212 committed Sep 28, 2024
1 parent eb43f82 commit 2311649
Show file tree
Hide file tree
Showing 28 changed files with 1,079 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package net.irisshaders.iris.compat.sodium.mixin;

import com.mojang.blaze3d.vertex.PoseStack;
import net.caffeinemc.mods.sodium.api.math.MatrixHelper;
import net.caffeinemc.mods.sodium.api.vertex.buffer.VertexBufferWriter;
import net.caffeinemc.mods.sodium.api.vertex.format.common.EntityVertex;
import net.caffeinemc.mods.sodium.client.model.quad.ModelQuadView;
import net.caffeinemc.mods.sodium.client.render.frapi.helper.ColorHelper;
import net.caffeinemc.mods.sodium.client.render.immediate.model.BakedModelEncoder;
import net.irisshaders.iris.Iris;
import net.irisshaders.iris.mixinterface.QuadPositionAccess;
import net.irisshaders.iris.pipeline.QuadPositions;
import net.irisshaders.iris.uniforms.CapturedRenderingState;
import net.irisshaders.iris.uniforms.SystemTimeUniforms;
import net.irisshaders.iris.vertices.sodium.IrisEntityVertex;
import org.joml.Matrix3f;
import org.joml.Matrix4f;
import org.lwjgl.system.MemoryStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(BakedModelEncoder.class)
public abstract class MixinBakedModel {
@Shadow
private static int mergeLighting(int stored, int calculated) {
return 0;
}

@Inject(method = "writeQuadVertices(Lnet/caffeinemc/mods/sodium/api/vertex/buffer/VertexBufferWriter;Lcom/mojang/blaze3d/vertex/PoseStack$Pose;Lnet/caffeinemc/mods/sodium/client/model/quad/ModelQuadView;IIIZ)V", at = @At("HEAD"), cancellable = true)
private static void redirectToIris(VertexBufferWriter writer, PoseStack.Pose matrices, ModelQuadView quad, int color, int light, int overlay, boolean colorize, CallbackInfo ci) {
if (Iris.isPackInUseQuick()) {
ci.cancel();
writeIris(writer, matrices, quad, color, light, overlay, colorize);
}
}

private static void writeIris(VertexBufferWriter writer, PoseStack.Pose matrices, ModelQuadView quad, int color, int light, int overlay, boolean colorize) {
Matrix3f matNormal = matrices.normal();
Matrix4f matPosition = matrices.pose();

QuadPositions quadPositions = ((QuadPositionAccess) quad).getQuadPosition(CapturedRenderingState.INSTANCE.getEntityRollingId());

try (MemoryStack stack = MemoryStack.stackPush()) {
long buffer = stack.nmalloc(4 * IrisEntityVertex.STRIDE);
long ptr = buffer;

float midU = (quad.getTexU(0) + quad.getTexU(1) + quad.getTexU(2) + quad.getTexU(3)) * 0.25f;
float midV = (quad.getTexV(0) + quad.getTexV(1) + quad.getTexV(2) + quad.getTexV(3)) * 0.25f;

for (int i = 0; i < 4; i++) {
// The position vector
float x = quad.getX(i);
float y = quad.getY(i);
float z = quad.getZ(i);

int newLight = mergeLighting(quad.getLight(i), light);

int newColor = color;

if (colorize) {
newColor = ColorHelper.multiplyColor(newColor, quad.getColor(i));
}

// The packed transformed normal vector
int normal = MatrixHelper.transformNormal(matNormal, matrices.trustedNormals, quad.getAccurateNormal(i));

// The transformed position vector
float xt = MatrixHelper.transformPositionX(matPosition, x, y, z);
float yt = MatrixHelper.transformPositionY(matPosition, x, y, z);
float zt = MatrixHelper.transformPositionZ(matPosition, x, y, z);

quadPositions.setAndUpdate(SystemTimeUniforms.COUNTER.getAsInt(), i, xt, yt, zt);

// TODO TANGENT
IrisEntityVertex.write(ptr, xt, yt, zt, quadPositions.velocityX[i], quadPositions.velocityY[i], quadPositions.velocityZ[i], newColor, quad.getTexU(i), quad.getTexV(i), overlay, newLight, normal, 0, midU, midV);
ptr += IrisEntityVertex.STRIDE;
}

writer.push(stack, buffer, 4, IrisEntityVertex.FORMAT);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
package net.irisshaders.iris.compat.sodium.mixin;

import com.mojang.blaze3d.vertex.PoseStack;
import net.caffeinemc.mods.sodium.api.math.MatrixHelper;
import net.caffeinemc.mods.sodium.api.vertex.buffer.VertexBufferWriter;
import net.caffeinemc.mods.sodium.client.render.immediate.model.EntityRenderer;
import net.caffeinemc.mods.sodium.client.render.immediate.model.ModelCuboid;
import net.irisshaders.iris.Iris;
import net.irisshaders.iris.mixinterface.ModelPartAccess;
import net.irisshaders.iris.pipeline.CubePositions;
import net.irisshaders.iris.uniforms.CapturedRenderingState;
import net.irisshaders.iris.uniforms.SystemTimeUniforms;
import net.irisshaders.iris.vertices.NormI8;
import net.irisshaders.iris.vertices.NormalHelper;
import net.irisshaders.iris.vertices.sodium.IrisEntityVertex;
import net.minecraft.core.Direction;
import org.joml.Matrix3f;
import org.joml.Matrix4f;
import org.joml.Vector2f;
import org.joml.Vector3f;
import org.joml.Vector4f;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.system.MemoryUtil;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(EntityRenderer.class)
public abstract class MixinEntityRenderer {
@Shadow
public static void prepareNormalsIfChanged(PoseStack.Pose matrices) {
}

@Shadow
protected static void prepareVertices(PoseStack.Pose matrices, ModelCuboid cuboid) {
}

@Shadow
@Final
private static int NUM_CUBE_FACES;

@Shadow
@Final
private static int NUM_CUBE_VERTICES;

@Shadow
@Final
private static Vector3f[][] VERTEX_POSITIONS_MIRRORED;
@Shadow
@Final
private static Vector3f[][] VERTEX_POSITIONS;
@Shadow
@Final
private static Vector2f[][] VERTEX_TEXTURES_MIRRORED;
@Shadow
@Final
private static Vector2f[][] VERTEX_TEXTURES;
@Shadow
@Final
private static int[] CUBE_NORMALS;
@Shadow
@Final
private static int[] CUBE_NORMALS_MIRRORED;

@Unique
private static int[] CUBE_TANGENTS = new int[6];

@Unique
private static int[] CUBE_TANGENTS_MIRRORED = new int[6];

@Unique
private static final Vector2f[] MID_TEX_VALUES = new Vector2f[6];

static {
for (int i = 0; i < 6; i++) {
MID_TEX_VALUES[i] = new Vector2f();
}
}

private static final int
FACE_NEG_Y = 0, // DOWN
FACE_POS_Y = 1, // UP
FACE_NEG_X = 2, // WEST
FACE_NEG_Z = 3, // NORTH
FACE_POS_X = 4, // EAST
FACE_POS_Z = 5; // SOUTH


@Shadow
@Final
private static int[][] CUBE_VERTICES;
@Unique
private static final long SCRATCH_BUFFER_IRIS = MemoryUtil.nmemAlignedAlloc(64, NUM_CUBE_FACES * NUM_CUBE_VERTICES * IrisEntityVertex.STRIDE);

@Inject(method = "renderCuboid", at = @At("HEAD"), cancellable = true)
private static void redirectToIris(PoseStack.Pose matrices, VertexBufferWriter writer, ModelCuboid cuboid, int light, int overlay, int color, CallbackInfo ci) {
if (Iris.isPackInUseQuick()) {
ci.cancel();
renderCuboidIris(matrices, writer, cuboid, light, overlay, color);
}
}
private static void renderCuboidIris(PoseStack.Pose matrices, VertexBufferWriter writer, ModelCuboid cuboid, int light, int overlay, int color) {
prepareNormalsIfChanged(matrices);

prepareVertices(matrices, cuboid);
prepareMidCoords(cuboid);
prepareTangentsIfChanged(matrices);

var vertexCount = emitQuadsIris(cuboid, color, overlay, light);

try (MemoryStack stack = MemoryStack.stackPush()) {
writer.push(stack, SCRATCH_BUFFER_IRIS, vertexCount, IrisEntityVertex.FORMAT);
}
}

private static void prepareMidCoords(ModelCuboid cuboid) {
buildVertexMidTexCoord(MID_TEX_VALUES[FACE_NEG_Y], cuboid.u1, cuboid.v0, cuboid.u2, cuboid.v1);
buildVertexMidTexCoord(MID_TEX_VALUES[FACE_POS_Y], cuboid.u2, cuboid.v1, cuboid.u3, cuboid.v0);
buildVertexMidTexCoord(MID_TEX_VALUES[FACE_NEG_Z], cuboid.u1, cuboid.v1, cuboid.u2, cuboid.v2);
buildVertexMidTexCoord(MID_TEX_VALUES[FACE_POS_Z], cuboid.u4, cuboid.v1, cuboid.u5, cuboid.v2);
buildVertexMidTexCoord(MID_TEX_VALUES[FACE_NEG_X], cuboid.u2, cuboid.v1, cuboid.u4, cuboid.v2);
buildVertexMidTexCoord(MID_TEX_VALUES[FACE_POS_X], cuboid.u0, cuboid.v1, cuboid.u1, cuboid.v2);
}

private static void buildVertexMidTexCoord(Vector2f midTexValue, float u1, float v1, float u2, float v2) {
midTexValue.set((u1 + u2) * 0.5f, (v1 + v2) * 0.5f);
}

private static Matrix3f lastMatrix2 = new Matrix3f();

private static final Vector4f TANGENT_STORAGE = new Vector4f();

private static void prepareTangentsIfChanged(PoseStack.Pose matrices) {
if (!matrices.normal().equals(lastMatrix2)) {
lastMatrix2.set(matrices.normal());

for (int i = 0; i < 6; i++) {
CUBE_TANGENTS[i] = NormalHelper.computeTangent(TANGENT_STORAGE, NormI8.unpackX(CUBE_NORMALS[i]), NormI8.unpackY(CUBE_NORMALS[i]), NormI8.unpackZ(CUBE_NORMALS[i]),
VERTEX_POSITIONS[i][0].x, VERTEX_POSITIONS[i][0].y, VERTEX_POSITIONS[i][0].z, VERTEX_TEXTURES[i][0].x, VERTEX_TEXTURES[i][0].y,
VERTEX_POSITIONS[i][1].x, VERTEX_POSITIONS[i][1].y, VERTEX_POSITIONS[i][1].z, VERTEX_TEXTURES[i][1].x, VERTEX_TEXTURES[i][1].y,
VERTEX_POSITIONS[i][2].x, VERTEX_POSITIONS[i][2].y, VERTEX_POSITIONS[i][2].z, VERTEX_TEXTURES[i][2].x, VERTEX_TEXTURES[i][2].y);
}

// When mirroring is used, the normals for EAST and WEST are swapped.
CUBE_TANGENTS_MIRRORED[FACE_NEG_Y] = CUBE_TANGENTS[FACE_NEG_Y];
CUBE_TANGENTS_MIRRORED[FACE_POS_Y] = CUBE_TANGENTS[FACE_POS_Y];
CUBE_TANGENTS_MIRRORED[FACE_NEG_Z] = CUBE_TANGENTS[FACE_NEG_Z];
CUBE_TANGENTS_MIRRORED[FACE_POS_Z] = CUBE_TANGENTS[FACE_POS_Z];
CUBE_TANGENTS_MIRRORED[FACE_POS_X] = CUBE_TANGENTS[FACE_NEG_X]; // mirrored
CUBE_TANGENTS_MIRRORED[FACE_NEG_X] = CUBE_TANGENTS[FACE_POS_X]; // mirrored
}
}

private static int emitQuadsIris(ModelCuboid cuboid, int color, int overlay, int light) {
final var positions = cuboid.mirror ? VERTEX_POSITIONS_MIRRORED : VERTEX_POSITIONS;
final var textures = cuboid.mirror ? VERTEX_TEXTURES_MIRRORED : VERTEX_TEXTURES;
final var normals = cuboid.mirror ? CUBE_NORMALS_MIRRORED : CUBE_NORMALS;
final var tangents = cuboid.mirror ? CUBE_TANGENTS_MIRRORED : CUBE_TANGENTS;

CubePositions velocity = ((ModelPartAccess) cuboid).getCubePosition(CapturedRenderingState.INSTANCE.getEntityRollingId());

var vertexCount = 0;

long ptr = SCRATCH_BUFFER_IRIS;

for (int quadIndex = 0; quadIndex < NUM_CUBE_FACES; quadIndex++) {
if (!cuboid.shouldDrawFace(quadIndex)) {
continue;
}

float midU = MID_TEX_VALUES[quadIndex].x;
float midV = MID_TEX_VALUES[quadIndex].y;

velocity.setAndUpdate(SystemTimeUniforms.COUNTER.getAsInt(), CUBE_VERTICES[quadIndex][0], positions[quadIndex][0].x, positions[quadIndex][0].y, positions[quadIndex][0].z);
emitIris(ptr, positions[quadIndex][0], color, textures[quadIndex][0], overlay, light, normals[quadIndex], tangents[quadIndex], velocity.velocityX[CUBE_VERTICES[quadIndex][0]], velocity.velocityY[CUBE_VERTICES[quadIndex][0]], velocity.velocityZ[CUBE_VERTICES[quadIndex][0]], midU, midV);
ptr += IrisEntityVertex.STRIDE;

velocity.setAndUpdate(SystemTimeUniforms.COUNTER.getAsInt(), CUBE_VERTICES[quadIndex][1], positions[quadIndex][1].x, positions[quadIndex][1].y, positions[quadIndex][1].z);
emitIris(ptr, positions[quadIndex][1], color, textures[quadIndex][1], overlay, light, normals[quadIndex], tangents[quadIndex], velocity.velocityX[CUBE_VERTICES[quadIndex][1]], velocity.velocityY[CUBE_VERTICES[quadIndex][1]], velocity.velocityZ[CUBE_VERTICES[quadIndex][1]], midU, midV);
ptr += IrisEntityVertex.STRIDE;

velocity.setAndUpdate(SystemTimeUniforms.COUNTER.getAsInt(), CUBE_VERTICES[quadIndex][2], positions[quadIndex][2].x, positions[quadIndex][2].y, positions[quadIndex][2].z);
emitIris(ptr, positions[quadIndex][2], color, textures[quadIndex][2], overlay, light, normals[quadIndex], tangents[quadIndex], velocity.velocityX[CUBE_VERTICES[quadIndex][2]], velocity.velocityY[CUBE_VERTICES[quadIndex][2]], velocity.velocityZ[CUBE_VERTICES[quadIndex][2]], midU, midV);
ptr += IrisEntityVertex.STRIDE;

velocity.setAndUpdate(SystemTimeUniforms.COUNTER.getAsInt(), CUBE_VERTICES[quadIndex][3], positions[quadIndex][3].x, positions[quadIndex][3].y, positions[quadIndex][3].z);
emitIris(ptr, positions[quadIndex][3], color, textures[quadIndex][3], overlay, light, normals[quadIndex], tangents[quadIndex], velocity.velocityX[CUBE_VERTICES[quadIndex][3]], velocity.velocityY[CUBE_VERTICES[quadIndex][3]], velocity.velocityZ[CUBE_VERTICES[quadIndex][3]], midU, midV);
ptr += IrisEntityVertex.STRIDE;

vertexCount += 4;
}

return vertexCount;
}

private static void emitIris(long ptr, Vector3f pos, int color, Vector2f tex, int overlay, int light, int normal, int tangent,
float prevX, float prevY, float prevZ, float midU, float midV) {
IrisEntityVertex.write(ptr, pos.x, pos.y, pos.z, prevX, prevY, prevZ, color, tex.x, tex.y, overlay, light, normal, tangent, midU, midV);
}
}
Loading

0 comments on commit 2311649

Please sign in to comment.