diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/model/light/smooth/SmoothLightPipeline.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/model/light/smooth/SmoothLightPipeline.java index 781f5780c2..1cbe1b1014 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/model/light/smooth/SmoothLightPipeline.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/model/light/smooth/SmoothLightPipeline.java @@ -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; /** @@ -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 @@ -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); } /** @@ -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); } /** @@ -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); } /** @@ -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) { @@ -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; @@ -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; @@ -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; @@ -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; }