Skip to content

Commit

Permalink
The final stretch
Browse files Browse the repository at this point in the history
  • Loading branch information
IMS212 committed Aug 4, 2023
1 parent 6ee5caf commit 9a11d55
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 189 deletions.
2 changes: 1 addition & 1 deletion buildscript/src/main/java/Buildscript.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public class Buildscript extends SimpleFabricProject {
static final boolean SODIUM = true;
static final boolean CUSTOM_SODIUM = true;
static final String MC_VERSION = "1.20.1";
static final String customSodiumName = "sodium-fabric-mc1.20.1-0.5.0-rc1.jar";
static final String customSodiumName = "sodium-fabric-mc1.20.1-0.5.0-rc2.jar";

private static final String[] SOURCE_SETS = new String[] {
"main",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,8 @@ public static void injectVertInit(
"_draw_id = (a_PosId.w >> 8u) & 0xFFu; }",

"uvec3 _get_relative_chunk_coord(uint pos) {\n" +
" return uvec3(pos) >> uvec3(5u, 3u, 0u) & uvec3(7u, 3u, 7u);\n" +
" // Packing scheme is defined by LocalSectionIndex\n" +
" return uvec3(pos) >> uvec3(5u, 0u, 2u) & uvec3(7u, 3u, 7u);\n" +
"}",
"vec3 _get_draw_translation(uint pos) {\n" +
" return _get_relative_chunk_coord(pos) * vec3(16.0f);\n" +
Expand Down
6 changes: 3 additions & 3 deletions src/main/resources/fabric.mod.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@

"custom": {
"sodium:options": {
"mixin.render.world.sky": false,
"mixin.render.entity": false,
"mixin.render.gui.font": false
"mixin.features.render.world.sky": false,
"mixin.features.render.entity": false,
"mixin.features.render.gui.font": false
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public void flipUpcomingQuadNormal() {

@Override
public long write(long ptr,
Material material, Vertex vertex, int chunkId) {
Material material, Vertex vertex, byte chunkId) {
uSum += vertex.u;
vSum += vertex.v;
vertexCount++;
Expand All @@ -69,7 +69,7 @@ public long write(long ptr,
MemoryUtil.memPutShort(ptr + 2L, XHFPModelVertexType.encodePosition(vertex.y));
MemoryUtil.memPutShort(ptr + 4L, XHFPModelVertexType.encodePosition(vertex.z));
MemoryUtil.memPutByte(ptr + 6L, material.bits());
MemoryUtil.memPutByte(ptr + 7L, (byte) chunkId);
MemoryUtil.memPutByte(ptr + 7L, chunkId);

MemoryUtil.memPutInt(ptr + 8, vertex.color);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,9 @@
import me.jellysquid.mods.sodium.client.model.ModelCuboidAccessor;
import me.jellysquid.mods.sodium.client.render.vertex.VertexConsumerUtils;
import me.jellysquid.mods.sodium.client.render.immediate.model.ModelCuboid;
import net.caffeinemc.mods.sodium.api.util.NormI8;
import net.caffeinemc.mods.sodium.api.vertex.format.VertexFormatDescription;
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.vertex_format.entity_xhfp.EntityVertex;
import net.coderbot.iris.vertices.ImmediateState;
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;
Expand All @@ -29,204 +23,93 @@

@Mixin(ModelPart.class)
public class ModelPartMixin {
@Shadow public float x;
@Shadow public float y;
@Shadow public float z;

@Shadow public float yRot;
@Shadow public float xRot;
@Shadow public float zRot;

@Shadow public float xScale;
@Shadow public float yScale;
@Shadow public float zScale;

@Unique
private ModelCuboid[] sodium$cuboids;

@Inject(method = "<init>", at = @At("RETURN"))
private void onInit(List<ModelPart.Cube> cuboids, Map<String, ModelPart> children, CallbackInfo ci) {
var copies = new ModelCuboid[cuboids.size()];

for (int i = 0; i < cuboids.size(); i++) {
var accessor = (ModelCuboidAccessor) cuboids.get(i);
copies[i] = accessor.sodium$copy();
}

this.sodium$cuboids = copies;
}

/**
* @author JellySquid
* @reason Use optimized vertex writer, avoid allocations, use quick matrix transformations
*/
@Inject(method = "compile", at = @At("HEAD"), cancellable = true)
private void renderCuboidsFast(PoseStack.Pose matrices, VertexConsumer vertexConsumer, int light, int overlay, float red, float green, float blue, float alpha, CallbackInfo ci) {
var writer = VertexConsumerUtils.convertOrLog(vertexConsumer);
if(writer == null) {
return;
}

ci.cancel();

boolean extend = shouldExtend();
VertexFormatDescription format = extend ? EntityVertex.FORMAT : ModelVertex.FORMAT;
int stride = extend ? EntityVertex.STRIDE : ModelVertex.STRIDE;
@Shadow public float x;
@Shadow public float y;
@Shadow public float z;

int color = ColorABGR.pack(red, green, blue, alpha);
@Shadow public float yRot;
@Shadow public float xRot;
@Shadow public float zRot;

for (ModelCuboid cuboid : this.sodium$cuboids) {
cuboid.updateVertices(matrices.pose());
@Shadow public float xScale;
@Shadow public float yScale;
@Shadow public float zScale;

try (MemoryStack stack = MemoryStack.stackPush()) {
long buffer = stack.nmalloc(4 * 6 * stride);
long ptr = buffer;
@Unique
private ModelCuboid[] sodium$cuboids;

int count = 0;
@Inject(method = "<init>", at = @At("RETURN"))
private void onInit(List<ModelPart.Cube> cuboids, Map<String, ModelPart> children, CallbackInfo ci) {
var copies = new ModelCuboid[cuboids.size()];

for (ModelCuboid.Quad quad : cuboid.quads) {
if (quad == null) continue;
for (int i = 0; i < cuboids.size(); i++) {
var accessor = (ModelCuboidAccessor) cuboids.get(i);
copies[i] = accessor.sodium$copy();
}

var normal = quad.getNormal(matrices.normal());
this.sodium$cuboids = copies;
}

float midU = 0, midV = 0;
int tangent = 0;
/**
* @author JellySquid
* @reason Use optimized vertex writer, avoid allocations, use quick matrix transformations
*/
@Inject(method = "compile", at = @At("HEAD"), cancellable = true)
private void renderCuboidsFast(PoseStack.Pose matrices, VertexConsumer vertexConsumer, int light, int overlay, float red, float green, float blue, float alpha, CallbackInfo ci) {
var writer = VertexConsumerUtils.convertOrLog(vertexConsumer);
if(writer == null) {
return;
}

if (extend) {
for (int i = 0; i < 4; i++) {
midU += quad.textures[i].x;
midV += quad.textures[i].y;
}
ci.cancel();

midU *= 0.25;
midV *= 0.25;
int color = ColorABGR.pack(red, green, blue, alpha);

tangent = getTangent(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
);
}
for (ModelCuboid cuboid : this.sodium$cuboids) {
cuboid.updateVertices(matrices.pose());

for (int i = 0; i < 4; i++) {
var pos = quad.positions[i];
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, overlay, light, normal);
}

ptr += stride;
}

count += 4;
}

writer.push(stack, buffer, count, format);
}
}
}

/**
* @author JellySquid
* @reason Apply transform more quickly
*/
@Overwrite
public void translateAndRotate(PoseStack matrices) {
matrices.translate(this.x * (1.0F / 16.0F), this.y * (1.0F / 16.0F), this.z * (1.0F / 16.0F));

if (this.xRot != 0.0F || this.yRot != 0.0F || this.zRot != 0.0F) {
MatrixHelper.rotateZYX(matrices.last(), this.zRot, this.yRot, this.xRot);
}

if (this.xScale != 1.0F || this.yScale != 1.0F || this.zScale != 1.0F) {
matrices.scale(this.xScale, this.yScale, this.zScale);
}
}

private static float rsqrt(float value) {
if (value == 0.0f) {
// You heard it here first, folks: 1 divided by 0 equals 1
// In actuality, this is a workaround for normalizing a zero length vector (leaving it as zero length)
return 1.0f;
} else {
return (float) (1.0 / Math.sqrt(value));
}
}
try (MemoryStack stack = MemoryStack.stackPush()) {
long buffer = stack.nmalloc(4 * 6 * ModelVertex.STRIDE);
long ptr = buffer;

private static boolean shouldExtend() {
return IrisApi.getInstance().isShaderPackInUse() && ImmediateState.renderWithExtendedVertexFormat;
}
int count = 0;

private int getTangent(int normal, float x0, float y0, float z0, float u0, float v0, float x1, float y1, float z1, float u1, float v1, float x2, float y2, float z2, float u2, float v2) {
// Capture all of the relevant vertex positions
for (ModelCuboid.Quad quad : cuboid.quads) {
if (quad == null) continue;

float normalX = NormI8.unpackX(normal);
float normalY = NormI8.unpackY(normal);
float normalZ = NormI8.unpackZ(normal);
var normal = quad.getNormal(matrices.normal());

float edge1x = x1 - x0;
float edge1y = y1 - y0;
float edge1z = z1 - z0;
for (int i = 0; i < 4; i++) {
var pos = quad.positions[i];
var tex = quad.textures[i];

float edge2x = x2 - x0;
float edge2y = y2 - y0;
float edge2z = z2 - z0;
ModelVertex.write(ptr, pos.x, pos.y, pos.z, color, tex.x, tex.y, overlay, light, normal);

float deltaU1 = u1 - u0;
float deltaV1 = v1 - v0;
float deltaU2 = u2 - u0;
float deltaV2 = v2 - v0;
ptr += ModelVertex.STRIDE;
}

float fdenom = deltaU1 * deltaV2 - deltaU2 * deltaV1;
float f;
count += 4;
}

if (fdenom == 0.0) {
f = 1.0f;
} else {
f = 1.0f / fdenom;
writer.push(stack, buffer, count, ModelVertex.FORMAT);
}
}
}

/**
* @author JellySquid
* @reason Apply transform more quickly
*/
@Overwrite
public void translateAndRotate(PoseStack matrices) {
matrices.translate(this.x * (1.0F / 16.0F), this.y * (1.0F / 16.0F), this.z * (1.0F / 16.0F));

float tangentx = f * (deltaV2 * edge1x - deltaV1 * edge2x);
float tangenty = f * (deltaV2 * edge1y - deltaV1 * edge2y);
float tangentz = f * (deltaV2 * edge1z - deltaV1 * edge2z);
float tcoeff = rsqrt(tangentx * tangentx + tangenty * tangenty + tangentz * tangentz);
tangentx *= tcoeff;
tangenty *= tcoeff;
tangentz *= tcoeff;

float bitangentx = f * (-deltaU2 * edge1x + deltaU1 * edge2x);
float bitangenty = f * (-deltaU2 * edge1y + deltaU1 * edge2y);
float bitangentz = f * (-deltaU2 * edge1z + deltaU1 * edge2z);
float bitcoeff = rsqrt(bitangentx * bitangentx + bitangenty * bitangenty + bitangentz * bitangentz);
bitangentx *= bitcoeff;
bitangenty *= bitcoeff;
bitangentz *= bitcoeff;

// predicted bitangent = tangent × normal
// Compute the determinant of the following matrix to get the cross product
// i j k
// tx ty tz
// nx ny nz

// Be very careful when writing out complex multi-step calculations
// such as vector cross products! The calculation for pbitangentz
// used to be broken because it multiplied values in the wrong order.

float pbitangentx = tangenty * normalZ - tangentz * normalY;
float pbitangenty = tangentz * normalX - tangentx * normalZ;
float pbitangentz = tangentx * normalY - tangenty * normalX;

float dot = (bitangentx * pbitangentx) + (bitangenty * pbitangenty) + (bitangentz * pbitangentz);
float tangentW;

if (dot < 0) {
tangentW = -1.0F;
} else {
tangentW = 1.0F;
if (this.xRot != 0.0F || this.yRot != 0.0F || this.zRot != 0.0F) {
MatrixHelper.rotateZYX(matrices.last(), this.zRot, this.yRot, this.xRot);
}

return NormalHelper.packNormal(tangentx, tangenty, tangentz, tangentW);
if (this.xScale != 1.0F || this.yScale != 1.0F || this.zScale != 1.0F) {
matrices.scale(this.xScale, this.yScale, this.zScale);
}
}
}

0 comments on commit 9a11d55

Please sign in to comment.