-
-
Notifications
You must be signed in to change notification settings - Fork 642
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
28 changed files
with
1,079 additions
and
5 deletions.
There are no files selected for viewing
85 changes: 85 additions & 0 deletions
85
common/src/main/java/net/irisshaders/iris/compat/sodium/mixin/MixinBakedModel.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} | ||
} |
204 changes: 204 additions & 0 deletions
204
common/src/main/java/net/irisshaders/iris/compat/sodium/mixin/MixinEntityRenderer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} |
Oops, something went wrong.