mirror of
https://github.com/wisplite/crystalline-sky.git
synced 2026-10-30 13:32:18 -05:00
make the sky loop around under the horizon
This commit is contained in:
+71
-3
@@ -4,6 +4,7 @@ import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import com.mojang.blaze3d.pipeline.RenderTarget;
|
||||
import com.mojang.blaze3d.pipeline.TextureTarget;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import io.github.slimeistdev.crystalline_sky.compat.Mods;
|
||||
import io.github.slimeistdev.crystalline_sky.compat.iris.IrisHelpers;
|
||||
@@ -15,10 +16,12 @@ import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.CloudStatus;
|
||||
import net.minecraft.client.DeltaTracker;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.FogRenderer;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.client.renderer.LevelRenderer;
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Matrix4f;
|
||||
@@ -48,6 +51,9 @@ public abstract class LevelRendererMixin implements LevelRenderer_Duck {
|
||||
@Shadow
|
||||
public abstract void renderClouds(PoseStack matrices, Matrix4f matrix4f, Matrix4f matrix4f2, float tickDelta, double cameraX, double cameraY, double cameraZ);
|
||||
|
||||
@Shadow
|
||||
public abstract void renderSky(Matrix4f frustumMatrix, Matrix4f projectionMatrix, float partialTick, Camera camera, boolean isFoggy, Runnable skyFogSetup);
|
||||
|
||||
@Unique
|
||||
@Nullable
|
||||
private RenderTarget crystalline_sky$skyBuffer;
|
||||
@@ -104,9 +110,15 @@ public abstract class LevelRendererMixin implements LevelRenderer_Duck {
|
||||
Matrix4f matrix4f, Matrix4f matrix4f2, CallbackInfo ci) {
|
||||
var skyBuffer = crystalline_sky$getSkyFramebuffer();
|
||||
skyBuffer.clear(Minecraft.ON_OSX);
|
||||
var copiedFromIris = Mods.IRIS.runIfInstalled(() -> () -> IrisHelpers.copySkyToBuffer(skyBuffer));
|
||||
if (!copiedFromIris.orElse(false))
|
||||
((RenderTarget_Duck) skyBuffer).crystalline_sky$copyColorFrom(minecraft.getMainRenderTarget());
|
||||
|
||||
float partialTick = tickCounter.getGameTimeDeltaPartialTick(false);
|
||||
if (crystalline_sky$isBelowHorizon(partialTick)) {
|
||||
crystalline_sky$renderSkyBuffer(skyBuffer, tickCounter, camera, gameRenderer, matrix4f, matrix4f2);
|
||||
} else {
|
||||
var copiedFromIris = Mods.IRIS.runIfInstalled(() -> () -> IrisHelpers.copySkyToBuffer(skyBuffer));
|
||||
if (!copiedFromIris.orElse(false))
|
||||
((RenderTarget_Duck) skyBuffer).crystalline_sky$copyColorFrom(minecraft.getMainRenderTarget());
|
||||
}
|
||||
|
||||
// render clouds
|
||||
CloudStatus cloudRenderMode = this.minecraft.options.getCloudsType();
|
||||
@@ -143,4 +155,60 @@ public abstract class LevelRendererMixin implements LevelRenderer_Duck {
|
||||
renderSectionLayer(CrystallineRenderTypes.SKY, x, y, z, matrix4f, positionMatrix);
|
||||
renderSectionLayer(CrystallineRenderTypes.SKYBOX, x, y, z, matrix4f, positionMatrix);
|
||||
}
|
||||
|
||||
@Unique
|
||||
private boolean crystalline_sky$isBelowHorizon(float partialTick) {
|
||||
var level = minecraft.level;
|
||||
var player = minecraft.player;
|
||||
if (level == null || player == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
double eyeY = player.getEyePosition(partialTick).y;
|
||||
double horizon = level.getLevelData().getHorizonHeight(level);
|
||||
return eyeY < horizon;
|
||||
}
|
||||
|
||||
@Unique
|
||||
private void crystalline_sky$renderSkyBuffer(
|
||||
RenderTarget skyBuffer,
|
||||
DeltaTracker tickCounter,
|
||||
Camera camera,
|
||||
GameRenderer gameRenderer,
|
||||
Matrix4f frustumMatrix,
|
||||
Matrix4f projectionMatrix
|
||||
) {
|
||||
float partialTick = tickCounter.getGameTimeDeltaPartialTick(false);
|
||||
Vec3 cameraPos = camera.getPosition();
|
||||
float renderDistance = gameRenderer.getRenderDistance();
|
||||
boolean isFoggy = minecraft.level.effects().isFoggyAt(Mth.floor(cameraPos.x), Mth.floor(cameraPos.y))
|
||||
|| minecraft.gui.getBossOverlay().shouldCreateWorldFog();
|
||||
|
||||
skyBuffer.bindWrite(false);
|
||||
SharedRenderVariables.pushSkipVoidSky();
|
||||
try {
|
||||
FogRenderer.setupColor(
|
||||
camera,
|
||||
partialTick,
|
||||
minecraft.level,
|
||||
minecraft.options.getEffectiveRenderDistance(),
|
||||
gameRenderer.getDarkenWorldAmount(partialTick)
|
||||
);
|
||||
FogRenderer.levelFogColor();
|
||||
RenderSystem.clear(16640, Minecraft.ON_OSX);
|
||||
FogRenderer.setupFog(camera, FogRenderer.FogMode.FOG_SKY, renderDistance, isFoggy, partialTick);
|
||||
RenderSystem.setShader(GameRenderer::getPositionShader);
|
||||
this.renderSky(
|
||||
frustumMatrix,
|
||||
projectionMatrix,
|
||||
partialTick,
|
||||
camera,
|
||||
isFoggy,
|
||||
() -> FogRenderer.setupFog(camera, FogRenderer.FogMode.FOG_SKY, renderDistance, isFoggy, partialTick)
|
||||
);
|
||||
} finally {
|
||||
SharedRenderVariables.popSkipVoidSky();
|
||||
minecraft.getMainRenderTarget().bindWrite(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package io.github.slimeistdev.crystalline_sky.mixin.client;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import io.github.slimeistdev.crystalline_sky.util.SharedRenderVariables;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.renderer.LevelRenderer;
|
||||
import net.minecraft.world.level.LevelHeightAccessor;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
||||
@Mixin(value = LevelRenderer.class, remap = false)
|
||||
public class LevelRendererRenderSkyMixin {
|
||||
@WrapOperation(
|
||||
method = "renderSky",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/multiplayer/ClientLevel$ClientLevelData;getHorizonHeight(Lnet/minecraft/world/level/LevelHeightAccessor;)D"
|
||||
)
|
||||
)
|
||||
private double crystalline_sky$skipVoidSkyWhenCapturing(
|
||||
ClientLevel.ClientLevelData levelData,
|
||||
LevelHeightAccessor level,
|
||||
Operation<Double> original
|
||||
) {
|
||||
if (SharedRenderVariables.shouldSkipVoidSky()) {
|
||||
return Double.NEGATIVE_INFINITY;
|
||||
}
|
||||
|
||||
return original.call(levelData, level);
|
||||
}
|
||||
}
|
||||
+13
@@ -8,6 +8,7 @@ public class SharedRenderVariables {
|
||||
// because chunk meshing is multithreaded :(
|
||||
public static final ThreadLocal<MutableInt> shadeFullBright = ThreadLocal.withInitial(() -> new MutableInt(0));
|
||||
private static int blockIrisShaderFramebufferBind = 0;
|
||||
private static int skipVoidSky = 0;
|
||||
|
||||
public static boolean shouldShadeFullBright() {
|
||||
return shadeFullBright.get().intValue() > 0;
|
||||
@@ -32,4 +33,16 @@ public class SharedRenderVariables {
|
||||
public static void popBlockIrisShaderFramebufferBind() {
|
||||
blockIrisShaderFramebufferBind--;
|
||||
}
|
||||
|
||||
public static boolean shouldSkipVoidSky() {
|
||||
return skipVoidSky > 0;
|
||||
}
|
||||
|
||||
public static void pushSkipVoidSky() {
|
||||
skipVoidSky++;
|
||||
}
|
||||
|
||||
public static void popSkipVoidSky() {
|
||||
skipVoidSky--;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
"client.GameRendererMixin",
|
||||
"client.LevelRenderer_NoSodium_Mixin",
|
||||
"client.LevelRendererMixin",
|
||||
"client.LevelRendererRenderSkyMixin",
|
||||
"client.ModelBlockRendererMixin",
|
||||
"client.RenderTargetMixin",
|
||||
"client.TextureAtlasAccessor",
|
||||
|
||||
Reference in New Issue
Block a user