// Zielpfad: src/main/java/ovh/glitchlabs/ornamentum/client/ModSkyboxRenderer.java package ovh.glitchlabs.ornamentum.client; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexBuffer; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.resources.ResourceLocation; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.neoforge.client.event.RenderLevelStageEvent; import org.joml.Matrix4f; import ovh.glitchlabs.ornamentum.Ornamentum; @EventBusSubscriber(modid = Ornamentum.MODID, value = Dist.CLIENT) public class ModSkyboxRenderer { // Ein Preset pro Index aus dem GUI ("Textur wechseln"). Lege die passenden // PNGs unter assets/ornamentum/textures/sky/ ab (equirektangulare Panoramen). private static final ResourceLocation[] SKY_TEXTURES = { ResourceLocation.fromNamespaceAndPath(Ornamentum.MODID, "textures/sky/custom_sky_0.png"), ResourceLocation.fromNamespaceAndPath(Ornamentum.MODID, "textures/sky/custom_sky_1.png"), ResourceLocation.fromNamespaceAndPath(Ornamentum.MODID, "textures/sky/custom_sky_2.png"), ResourceLocation.fromNamespaceAndPath(Ornamentum.MODID, "textures/sky/custom_sky_3.png") }; private static final ResourceLocation STARS_TEXTURE = ResourceLocation.fromNamespaceAndPath(Ornamentum.MODID, "textures/sky/custom_stars.png"); // r, g, b pro Farb-Preset (Index = colorIndex aus dem GUI, "Farbe wechseln") private static final float[][] COLOR_PRESETS = { {0.55f, 0.75f, 1.00f}, // Blau {0.65f, 0.45f, 0.85f}, // Lila {1.00f, 0.60f, 0.30f}, // Orange {0.40f, 0.85f, 0.45f}, // Grün {0.90f, 0.30f, 0.30f}, // Rot {0.30f, 0.80f, 0.80f} // Türkis }; private static VertexBuffer skySphere; private static VertexBuffer starSphere; @SubscribeEvent public static void onRenderSky(RenderLevelStageEvent event) { if (event.getStage() != RenderLevelStageEvent.Stage.AFTER_SKY) { return; } ClientSkyboxTracker.ActiveSkybox active = ClientSkyboxTracker.getActive(); if (active == null || active.blend() <= 0f) { return; } if (skySphere == null) { skySphere = SkyboxSphereBuilder.buildSphere(16, 16, 100f); } if (starSphere == null) { starSphere = SkyboxSphereBuilder.buildSphere(16, 16, 90f); } ClientLevel level = Minecraft.getInstance().level; if (level == null) { return; } long dayTime = level.getDayTime() % 24000; boolean isNight = dayTime > 13000 && dayTime < 23000; float partialTick = event.getPartialTick().getGameTimeDeltaPartialTick(true); float starVisibility = level.getStarBrightness(partialTick); float[] color = COLOR_PRESETS[active.colorIndex() % COLOR_PRESETS.length]; float darken = isNight ? 0.25f : 1.0f; PoseStack poseStack = event.getPoseStack(); if (poseStack == null) { return; } poseStack.pushPose(); RenderSystem.enableBlend(); RenderSystem.defaultBlendFunc(); RenderSystem.depthMask(false); RenderSystem.setShader(GameRenderer::getPositionTexShader); Matrix4f mvMatrix = new Matrix4f(poseStack.last().pose()); Matrix4f projMatrix = event.getProjectionMatrix(); // 1) Basis-Himmelskugel mit gewählter Textur + Farbton RenderSystem.setShaderColor(color[0] * darken, color[1] * darken, color[2] * darken, active.blend()); RenderSystem.setShaderTexture(0, SKY_TEXTURES[active.texturePreset() % SKY_TEXTURES.length]); skySphere.bind(); skySphere.drawWithShader(mvMatrix, projMatrix, RenderSystem.getShader()); // 2) Sterne-Overlay, nur wenn im GUI aktiviert + es dunkel genug ist if (active.starsEnabled()) { float starAlpha = starVisibility * active.blend(); if (starAlpha > 0.01f) { RenderSystem.setShaderColor(1f, 1f, 1f, starAlpha); RenderSystem.setShaderTexture(0, STARS_TEXTURE); starSphere.bind(); starSphere.drawWithShader(mvMatrix, projMatrix, RenderSystem.getShader()); } } VertexBuffer.unbind(); RenderSystem.setShaderColor(1f, 1f, 1f, 1f); RenderSystem.depthMask(true); RenderSystem.disableBlend(); poseStack.popPose(); } }