Skip to content

Commit

Permalink
Do not bake ambient lighting into cached per-face light data
Browse files Browse the repository at this point in the history
Fixes #2806
  • Loading branch information
jellysquid3 committed Dec 16, 2024
1 parent 173c6e0 commit 5d67cd5
Showing 1 changed file with 47 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
import net.caffeinemc.mods.sodium.client.model.light.data.QuadLightData;
import net.caffeinemc.mods.sodium.client.model.quad.ModelQuadView;
import net.caffeinemc.mods.sodium.client.model.quad.properties.ModelQuadFlags;
import net.caffeinemc.mods.sodium.client.util.DirectionUtil;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.util.Mth;
import net.minecraft.world.level.material.FluidState;
import org.joml.Vector3f;

/**
Expand Down Expand Up @@ -58,12 +58,23 @@ public class SmoothLightPipeline implements LightPipeline {
*/
private final float[] weights = new float[4];

// Cached per-face brightness received from the dimension's ambient lighting.
// This data is static for a given world and dimension.
private final float[] ambientBrightnessShaded = new float[6];
private final float[] ambientBrightnessUnshaded = new float[6];

public SmoothLightPipeline(LightDataAccess cache) {
this.lightCache = cache;

for (int i = 0; i < this.cachedFaceData.length; i++) {
this.cachedFaceData[i] = new AoFaceData();
}

for (Direction direction : DirectionUtil.ALL_DIRECTIONS) {
var level = cache.getLevel();
this.ambientBrightnessShaded[direction.ordinal()] = level.getShade(direction, true);
this.ambientBrightnessUnshaded[direction.ordinal()] = level.getShade(direction, false);
}
}

@Override
Expand Down Expand Up @@ -102,6 +113,8 @@ public void calculate(ModelQuadView quad, BlockPos pos, QuadLightData out, Direc
private void applyAlignedFullFace(AoNeighborInfo neighborInfo, BlockPos pos, Direction dir, QuadLightData out, boolean shade) {
AoFaceData faceData = this.getCachedFaceData(pos, dir, true, shade);
neighborInfo.mapCorners(faceData.lm, faceData.ao, out.lm, out.br);

this.applyAmbientLighting(out.br, dir, shade);
}

/**
Expand All @@ -119,6 +132,8 @@ private void applyAlignedPartialFace(AoNeighborInfo neighborInfo, ModelQuadView
neighborInfo.calculateCornerWeights(cx, cy, cz, weights);
this.applyAlignedPartialFaceVertex(pos, dir, weights, i, out, true, shade);
}

this.applyAmbientLighting(out.br, dir, shade);
}

/**
Expand Down Expand Up @@ -150,6 +165,8 @@ private void applyParallelFace(AoNeighborInfo neighborInfo, ModelQuadView quad,
this.applyInsetPartialFaceVertex(pos, dir, depth, 1.0f - depth, weights, i, out, shade);
}
}

this.applyAmbientLighting(out.br, dir, shade);
}

/**
Expand Down Expand Up @@ -178,6 +195,8 @@ private void applyNonParallelFace(AoNeighborInfo neighborInfo, ModelQuadView qua
this.applyInsetPartialFaceVertex(pos, dir, depth, 1.0f - depth, weights, i, out, shade);
}
}

this.applyAmbientLighting(out.br, dir, shade);
}

private void applyAlignedPartialFaceVertex(BlockPos pos, Direction dir, float[] w, int i, QuadLightData out, boolean offset, boolean shade) {
Expand Down Expand Up @@ -257,7 +276,7 @@ private void applyIrregularFace(BlockPos blockPos, ModelQuadView quad, QuadLight
final AoFaceData fd = gatherInsetFace(quad, blockPos, i, face, shade);
AoNeighborInfo.get(face).calculateCornerWeights(quad.getX(i), quad.getY(i), quad.getZ(i), w);
final float n = x * x;
final float a = fd.getBlendedShade(w);
final float a = fd.getBlendedShade(w) * this.getAmbientBrightness(face, shade);
final float s = fd.getBlendedSkyLight(w);
final float b = fd.getBlendedBlockLight(w);
ao += n * a;
Expand All @@ -275,7 +294,7 @@ private void applyIrregularFace(BlockPos blockPos, ModelQuadView quad, QuadLight
final AoFaceData fd = gatherInsetFace(quad, blockPos, i, face, shade);
AoNeighborInfo.get(face).calculateCornerWeights(quad.getX(i), quad.getY(i), quad.getZ(i), w);
final float n = y * y;
final float a = fd.getBlendedShade(w);
final float a = fd.getBlendedShade(w) * this.getAmbientBrightness(face, shade);
final float s = fd.getBlendedSkyLight(w);
final float b = fd.getBlendedBlockLight(w);
ao += n * a;
Expand All @@ -293,7 +312,7 @@ private void applyIrregularFace(BlockPos blockPos, ModelQuadView quad, QuadLight
final AoFaceData fd = gatherInsetFace(quad, blockPos, i, face, shade);
AoNeighborInfo.get(face).calculateCornerWeights(quad.getX(i), quad.getY(i), quad.getZ(i), w);
final float n = z * z;
final float a = fd.getBlendedShade(w);
final float a = fd.getBlendedShade(w) * this.getAmbientBrightness(face, shade);
final float s = fd.getBlendedSkyLight(w);
final float b = fd.getBlendedBlockLight(w);
ao += n * a;
Expand All @@ -309,29 +328,42 @@ private void applyIrregularFace(BlockPos blockPos, ModelQuadView quad, QuadLight
}
}

private void applySidedBrightness(AoFaceData out, Direction face, boolean shade) {
float brightness = this.lightCache.getLevel().getShade(face, shade);
float[] ao = out.ao;
/**
* Applies the "ambient" lighting from the dimension to a quad that is parallel with the block grid.
* @param brightness The array of brightnesses for each quad vertex
* @param face The facing of the quad
* @param shade Whether the quad should receive directional lighting
*/
private void applyAmbientLighting(final float[] brightness, Direction face, boolean shade) {
final float multiplier = this.getAmbientBrightness(face, shade);

for (int i = 0; i < ao.length; i++) {
ao[i] *= brightness;
for (int i = 0; i < brightness.length; i++) {
brightness[i] *= multiplier;
}
}

/**
* Returns the "ambient" brightness a block face receives in the world.
* @param face The block face
* @param shade Whether the block face is receiving directional light
*/
private float getAmbientBrightness(Direction face, boolean shade) {
return (shade ? this.ambientBrightnessShaded : this.ambientBrightnessUnshaded)[face.ordinal()];
}

/**
* Returns the cached data for a given facing or calculates it if it hasn't been cached.
*/
private AoFaceData getCachedFaceData(BlockPos pos, Direction face, boolean offset, boolean shade) {
AoFaceData data = this.cachedFaceData[offset ? face.ordinal() : face.ordinal() + 6];

if (!data.hasLightData()) {
data.initLightData(this.lightCache, pos, face, offset);

this.applySidedBrightness(data, face, shade);

data.unpackLightData();
if (data.hasLightData()) {
return data;
}

data.initLightData(this.lightCache, pos, face, offset);
data.unpackLightData();

return data;
}

Expand Down

0 comments on commit 5d67cd5

Please sign in to comment.