Extended clouds

This commit is contained in:
coolGi2007
2021-12-31 04:55:01 +00:00
parent 02862a770f
commit fe725b6795
7 changed files with 724 additions and 16 deletions
@@ -83,6 +83,10 @@ public class Config extends ConfigGui
@ConfigAnnotations.ScreenEntry
public static FogQuality fogQuality;
@ConfigAnnotations.Category("client.graphics")
@ConfigAnnotations.ScreenEntry
public static CloudQuality cloudQuality;
@ConfigAnnotations.Category("client.graphics")
@ConfigAnnotations.ScreenEntry
public static AdvancedGraphics advancedGraphics;
@@ -132,6 +136,18 @@ public class Config extends ConfigGui
}
public static class CloudQuality
{
@ConfigAnnotations.Category("client.graphics.cloudQuality")
@ConfigAnnotations.Entry
public static boolean extendClouds = true;
@ConfigAnnotations.Category("client.graphics.cloudQuality")
@ConfigAnnotations.Entry
public static int cloudHeight = 192;
}
public static class AdvancedGraphics
{
@@ -142,7 +158,7 @@ public class Config extends ConfigGui
@ConfigAnnotations.Category("client.graphics.advancedGraphics")
@ConfigAnnotations.Entry
public static boolean alwaysDrawAtMaxQuality = IAdvancedGraphics.ALWAYS_DRAW_AT_MAD_QUALITY_DEFAULT;
@ConfigAnnotations.Category("client.graphics.advancedGraphics")
@ConfigAnnotations.Entry
public static VanillaOverdraw vanillaOverdraw = IAdvancedGraphics.VANILLA_OVERDRAW_DEFAULT;
@@ -0,0 +1,92 @@
package com.seibel.lod.common.clouds;
import com.mojang.blaze3d.platform.NativeImage;
import net.minecraft.client.renderer.texture.DynamicTexture;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.levelgen.LegacyRandomSource;
import net.minecraft.world.level.levelgen.synth.SimplexNoise;
import java.util.*;
import java.util.List;
public class CloudTexture {
public List<PixelCoordinate> pixels = new LinkedList<PixelCoordinate>() {};
public SimplexNoise noise;
public DynamicTexture cloudsTexture;
public ResourceLocation resourceLocation;
public double cloudiness;
public CloudTexture(ResourceLocation resourceLocation) {
this.resourceLocation = resourceLocation;
}
public void updateImage(long time) {
Random random = new Random(time);
// Comment to clear sky
SkyCoverGenerators.cloudySkyUpdate(random, this.noise, this.cloudsTexture.getPixels(), pixels, this.cloudiness);
}
public void updatePixels() {
pixels.removeIf(pixel -> !fadePixel(Objects.requireNonNull(this.cloudsTexture.getPixels()), pixel.posX, pixel.posZ, pixel.fading));
this.cloudsTexture.upload();
}
public boolean fadePixel(NativeImage image, int x, int z, boolean fading) {
int color = image.getPixelRGBA(x, z);
int alpha = (color >> 24) & 0xFF;
//int alpha = image.getLuminanceOrAlpha(x, z) + 128;
if (fading) alpha -= 5;
else alpha += 5;
int newColor = alpha << 24 | 255 << 16 | 255 << 8 | 255;
//int newColor = NativeImage.combine(alpha, 255, 255, 255);
image.setPixelRGBA(x, z, newColor);
if (alpha <= 0) {
image.setPixelRGBA(x, z, 0);
return false;
} else return alpha < 255;
}
public void setTexture(DynamicTexture texture) {
this.cloudsTexture = texture;
}
public void initNoise(Random random) {
// this.noise = new SimplexNoise(new WorldgenRandom(random.nextLong()));
this.noise = new SimplexNoise(new LegacyRandomSource(random.nextLong()));
}
public DynamicTexture getNativeImage() {
NativeImage image = new NativeImage(256, 256, false);
Random random = new Random();
this.cloudiness = random.nextDouble();
// Switch these out to clear sky
// Never comment both or something weird will happen
// SkyCoverGenerators.clearSkyGenerator(this.noise, image, this.cloudiness);
SkyCoverGenerators.cloudySkyGenerator(this.noise, image, this.cloudiness);
return new DynamicTexture(image);
}
public static class PixelCoordinate {
public int posX;
public int posZ;
public boolean fading;
public PixelCoordinate(int posX, int posZ, boolean fading) {
this.posX = posX;
this.posZ = posZ;
this.fading = fading;
}
}
}
@@ -0,0 +1,56 @@
package com.seibel.lod.common.clouds;
import net.minecraft.client.Minecraft;
import net.minecraft.resources.ResourceLocation;
import java.util.LinkedList;
import java.util.List;
public final class NoiseCloudHandler {
public static List<CloudTexture> cloudTextures = new LinkedList<CloudTexture>() {};
private static long cloudIdx = -1;
private static long timeIdx = -1;
private static long lastTime = -1;
public static void update() {
Minecraft client = Minecraft.getInstance();
assert client.level != null;
long time = client.level.getGameTime();
if (time > lastTime) {
lastTime = time;
updateSkyCover(time);
long update = time / 600;
if (update > timeIdx) {
timeIdx = update;
for (CloudTexture cloudTexture : cloudTextures) {
if (cloudTexture.cloudsTexture.getPixels() != null) {
cloudTexture.updateImage(time);
}
}
}
for (CloudTexture cloudTexture : cloudTextures) {
if (cloudTexture.cloudsTexture.getPixels() != null) {
cloudTexture.updatePixels();
}
}
}
}
public static void updateSkyCover(long time) {
long idx = time / 12000;
if (idx > cloudIdx) {
cloudIdx = idx;
}
}
public static void initCloudTextures(ResourceLocation defaultCloud) {
CloudTexture defaultCloudTexture = new CloudTexture(defaultCloud);
cloudTextures.add(defaultCloudTexture);
}
}
@@ -0,0 +1,68 @@
package com.seibel.lod.common.clouds;
import com.mojang.blaze3d.platform.NativeImage;
import net.minecraft.world.level.levelgen.synth.SimplexNoise;
import java.util.List;
import java.util.Random;
public class SkyCoverGenerators {
public static final int COLOR = NativeImage.combine(255, 255, 255, 255);
// Where the generator for clouds could be made
// TODO: Try to impliment this https://www.reddit.com/r/Minecraft/comments/e7xol/this_is_how_clouds_should_work_gif_simulation/
public static void clearSkyGenerator(SimplexNoise noiseSampler, NativeImage image, double cloudiness) {
for (int x = 0; x < 256; x++) {
for (int z = 0; z < 256; z++) {
if (noiseSampler.getValue(x / 16.0, 0, z / 16.0) * 2.5 < cloudiness || image.getPixelRGBA(x, z) != 0) {
image.setPixelRGBA(x, z, 0);
}
}
}
}
public static void cloudySkyGenerator(SimplexNoise noiseSampler, NativeImage image, double cloudiness) {
for (int x = 0; x < 256; x++) {
for (int z = 0; z < 256; z++) {
image.setPixelRGBA(x, z, COLOR);
if (noiseSampler.getValue(x / 16.0, 0, z / 16.0) * 2.5 >= cloudiness || image.getPixelRGBA(x, z) != 0) {
if ((int) (noiseSampler.getValue(x / 16.0, 0, z / 16.0) * 2.5) != 0) {
image.setPixelRGBA(x, z, 0);
}
}
}
}
}
public static void cloudySkyUpdate(Random random, SimplexNoise noiseSampler, NativeImage image, List<CloudTexture.PixelCoordinate> pixels, double cloudiness) {
int count = random.nextInt(4000) + 4000;
for (int i = 0; i < count; i++) {
int x = random.nextInt(256);
int z = random.nextInt(256);
if (!updatingPixel(x, z, pixels)) {
if (noiseSampler.getValue(x / 16.0, 0, z / 16.0) * 2.5 < cloudiness && image.getPixelRGBA(x, z) == 0) {
if ((int) (noiseSampler.getValue(x / 16.0, 0, z / 16.0) * 2.5) != 0) {
pixels.add(new CloudTexture.PixelCoordinate(x, z, true));
} else {
pixels.add(new CloudTexture.PixelCoordinate(x, z, false));
}
} else {
pixels.add(new CloudTexture.PixelCoordinate(x, z, false));
}
}
}
}
public static boolean updatingPixel(int x, int z, List<CloudTexture.PixelCoordinate> pixels) {
for (CloudTexture.PixelCoordinate pixel : pixels) {
if (pixel.posX == x && pixel.posZ == z) {
return true;
}
}
return false;
}
}
@@ -24,6 +24,9 @@
"DistantHorizons.config.client.graphics.fogQuality.fogColorMode.@tooltip": "What color should fog use?",
"DistantHorizons.config.client.graphics.fogQuality.disableVanillaFog": "Disable vanilla fog",
"DistantHorizons.config.client.graphics.fogQuality.disableVanillaFog.@tooltip": "If true disable Minecraft's fog. \nMay cause issues with other mods that edit fog. \nMay cause errors with other fog editing mods",
"DistantHorizons.config.client.graphics.cloudQuality": "Cloud options",
"DistantHorizons.config.client.graphics.cloudQuality.extendClouds": "Extend the clouds",
"DistantHorizons.config.client.graphics.cloudQuality.cloudHeight": "Cloud height",
"DistantHorizons.config.client.graphics.advancedGraphics": "Advanced quality option",
"DistantHorizons.config.client.graphics.advancedGraphics.lodTemplate": "LOD template",
"DistantHorizons.config.client.graphics.advancedGraphics.lodTemplate.@tooltip": "How should the LODs be drawn? \nNOTE: Currently only CUBIC is implemented!",
@@ -21,6 +21,9 @@ package com.seibel.lod.fabric.mixins;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Matrix4f;
import com.seibel.lod.common.Config;
import com.seibel.lod.common.clouds.CloudTexture;
import com.seibel.lod.common.clouds.NoiseCloudHandler;
import com.seibel.lod.common.wrappers.McObjectConverter;
import net.minecraft.client.renderer.LevelRenderer;
import org.spongepowered.asm.mixin.Mixin;
@@ -33,6 +36,26 @@ import com.seibel.lod.core.objects.math.Mat4f;
import net.minecraft.client.renderer.RenderType;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.*;
import com.mojang.math.Matrix4f;
import net.minecraft.client.CloudStatus;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.*;
import net.minecraft.client.renderer.texture.DynamicTexture;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.network.chat.ChatType;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.*;
import java.util.Random;
/**
* This class is used to mix in my rendering code
* before Minecraft starts rendering blocks.
@@ -40,21 +63,49 @@ import net.minecraft.client.renderer.RenderType;
* render last event, the LODs would render on top
* of the normal terrain.
*
* This is also the mixin for rendering the clouds
*
* @author coolGi2007
* @author James Seibel
* @version 11-21-2021
* @version 12-31-2021
*/
@Mixin(LevelRenderer.class)
public class MixinWorldRenderer
{
@Final @Shadow private static ResourceLocation CLOUDS_LOCATION;
@Shadow private final int ticks;
@Final @Shadow @NotNull private final Minecraft minecraft;
@Shadow private int prevCloudX;
@Shadow private int prevCloudY;
@Shadow private int prevCloudZ;
@Shadow @NotNull private Vec3 prevCloudColor;
@Shadow @NotNull private CloudStatus prevCloudsType;
@Shadow private boolean generateClouds;
@Shadow @NotNull private VertexBuffer cloudBuffer;
@Unique private boolean initializedClouds = false;
private static float previousPartialTicks = 0;
@Inject(at = @At("RETURN"), method = "renderClouds(Lcom/mojang/blaze3d/vertex/PoseStack;Lcom/mojang/math/Matrix4f;FDDD)V")
private void renderClouds(PoseStack modelViewMatrixStack, Matrix4f projectionMatrix, float partialTicks, double cameraXBlockPos, double cameraYBlockPos, double cameraZBlockPos, CallbackInfo callback)
{
public MixinWorldRenderer() {
throw new NullPointerException("Null cannot be cast to non-null type.");
}
@Inject(method = "renderClouds", at = @At("HEAD"), cancellable = true)
public void renderClouds(PoseStack poseStack, Matrix4f model, float tickDelta, double cameraX, double cameraY, double cameraZ, CallbackInfo ci) {
TextureManager textureManager = Minecraft.getInstance().getTextureManager();
registerClouds(textureManager);
NoiseCloudHandler.update();
if (minecraft.level.dimension() == ClientLevel.OVERWORLD) {
CloudTexture cloudTexture = NoiseCloudHandler.cloudTextures.get(NoiseCloudHandler.cloudTextures.size() - 1);
renderCloudLayer(poseStack, model, tickDelta, cameraX, cameraY, cameraZ, Config.Client.Graphics.CloudQuality.cloudHeight, 0, 1, 1, cloudTexture.resourceLocation);
}
ci.cancel();
// get the partial ticks since renderChunkLayer doesn't
// have access to them
previousPartialTicks = partialTicks;
previousPartialTicks = tickDelta;
}
// HEAD or RETURN
@@ -70,4 +121,189 @@ public class MixinWorldRenderer
ClientApi.INSTANCE.renderLods(mcModelViewMatrix, mcProjectionMatrix, previousPartialTicks);
}
}
// TODO: Move these outside of the mixin
// When moved out then put credit to https://github.com/misterslime/fabulousclouds-fabric
private void registerClouds(TextureManager textureManager) {
if (!this.initializedClouds) {
Random random = new Random();
NoiseCloudHandler.initCloudTextures(CLOUDS_LOCATION);
for(CloudTexture cloudTexture : NoiseCloudHandler.cloudTextures) {
cloudTexture.initNoise(random);
DynamicTexture texture = cloudTexture.getNativeImage();
textureManager.register(cloudTexture.resourceLocation, texture);
cloudTexture.setTexture(texture);
}
this.initializedClouds = true;
}
}
private void renderCloudLayer(PoseStack poseStack, Matrix4f model, float tickDelta, double cameraX, double cameraY, double cameraZ, float cloudHeight, float cloudOffset, float cloudScale, float speedMod, ResourceLocation resourceLocation) {
RenderSystem.disableCull();
RenderSystem.enableBlend();
RenderSystem.enableDepthTest();
RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
RenderSystem.depthMask(true);
float scale = 12.0F * cloudScale;
double speed = ((this.ticks + tickDelta) * (0.03F * speedMod));
double posX = (cameraX + speed) / scale;
double posY = (cloudHeight - (float) cameraY + cloudOffset) / cloudScale;
double posZ = cameraZ / scale + 0.33000001311302185D;
posX -= Math.floor(posX / 2048.0D) * 2048;
posZ -= Math.floor(posZ / 2048.0D) * 2048;
float adjustedX = (float) (posX - (double) Math.floor(posX));
float adjustedY = (float) (posY / 4.0D - (double) Math.floor(posY / 4.0D)) * 4.0F;
float adjustedZ = (float) (posZ - (double) Math.floor(posZ));
Vec3 cloudColor = minecraft.level.getCloudColor(tickDelta);
int floorX = (int) Math.floor(posX);
int floorY = (int) Math.floor(posY / 4.0D);
int floorZ = (int) Math.floor(posZ);
if (floorX != this.prevCloudX || floorY != this.prevCloudY || floorZ != this.prevCloudZ || this.minecraft.options.getCloudsType() != this.prevCloudsType || this.prevCloudColor.distanceToSqr(cloudColor) > 2.0E-4D) {
this.prevCloudX = floorX;
this.prevCloudY = floorY;
this.prevCloudZ = floorZ;
this.prevCloudColor = cloudColor;
this.prevCloudsType = this.minecraft.options.getCloudsType();
this.generateClouds = true;
}
RenderSystem.setShader(GameRenderer::getPositionTexColorNormalShader);
if (this.generateClouds) {
this.generateClouds = false;
Tesselator tessellator = Tesselator.getInstance();
BufferBuilder bufferBuilder = tessellator.getBuilder();
if (this.cloudBuffer != null) this.cloudBuffer.close();
this.cloudBuffer = new VertexBuffer();
this.buildCloudLayer(bufferBuilder, posX, posY, posZ, cloudOffset, cloudScale, cloudColor);
bufferBuilder.end();
this.cloudBuffer.upload(bufferBuilder);
}
RenderSystem.setShaderTexture(0, resourceLocation);
FogRenderer.levelFogColor();
poseStack.pushPose();
poseStack.scale(scale, cloudScale, scale);
poseStack.translate(-adjustedX, adjustedY, -adjustedZ);
if (this.cloudBuffer != null) {
int cloudMainIndex = this.prevCloudsType == CloudStatus.FANCY ? 0 : 1;
for (int cloudIndex = 1; cloudMainIndex <= cloudIndex; ++cloudMainIndex) {
if (cloudMainIndex == 0) {
RenderSystem.colorMask(false, false, false, false);
} else {
RenderSystem.colorMask(true, true, true, true);
}
ShaderInstance shader = RenderSystem.getShader();
this.cloudBuffer.drawWithShader(poseStack.last().pose(), model, shader);
}
}
poseStack.popPose();
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
RenderSystem.enableCull();
RenderSystem.disableBlend();
}
private void buildCloudLayer(BufferBuilder bufferBuilder, double cloudX, double cloudY, double cloudZ, float offset, float scale, Vec3 color) {
float lowpFracAccur = (float) Math.pow(2.0, -8);
float mediumpFracAccur = (float) Math.pow(2.0, -10);
float viewDistance = 8;
float cloudThickness = 4.0f;
float adjustedCloudX = (float)Math.floor(cloudX) * lowpFracAccur;
float adjustedCloudZ = (float)Math.floor(cloudZ) * lowpFracAccur;
float redTop = (float)color.x;
float greenTop = (float)color.y;
float blueTop = (float)color.z;
float redEW = redTop * 0.9f;
float greenEW = greenTop * 0.9f;
float blueEW = blueTop * 0.9f;
float redBottom = redTop * 0.7f;
float greenBottom = greenTop * 0.7f;
float blueBottom = blueTop * 0.7f;
float redNS = redTop * 0.8f;
float greenNS = greenTop * 0.8f;
float blueNS = blueTop * 0.8f;
bufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX_COLOR_NORMAL);
float adjustedCloudY = (float)Math.floor(cloudY / cloudThickness) * cloudThickness;
if (this.prevCloudsType == CloudStatus.FANCY) {
int scaledViewDistance = (int) (((Config.Client.Graphics.CloudQuality.extendClouds ? Config.Client.Graphics.Quality.lodChunkRenderDistance : minecraft.options.renderDistance) / 2) / scale) / 2;
for (int x = -scaledViewDistance - 1; x <= scaledViewDistance; ++x) {
for (int z = -scaledViewDistance - 1; z <= scaledViewDistance; ++z) {
int n3;
float scaledX = x * viewDistance;
float scaledZ = z * viewDistance;
if (adjustedCloudY > -5.0f) {
bufferBuilder.vertex(scaledX + 0.0f, adjustedCloudY + 0.0f, scaledZ + 8.0f).uv((scaledX + 0.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + 8.0f) * lowpFracAccur + adjustedCloudZ).color(redBottom, greenBottom, blueBottom, 0.8f).normal(0.0f, -1.0f, 0.0f).endVertex();
bufferBuilder.vertex(scaledX + 8.0f, adjustedCloudY + 0.0f, scaledZ + 8.0f).uv((scaledX + 8.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + 8.0f) * lowpFracAccur + adjustedCloudZ).color(redBottom, greenBottom, blueBottom, 0.8f).normal(0.0f, -1.0f, 0.0f).endVertex();
bufferBuilder.vertex(scaledX + 8.0f, adjustedCloudY + 0.0f, scaledZ + 0.0f).uv((scaledX + 8.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + 0.0f) * lowpFracAccur + adjustedCloudZ).color(redBottom, greenBottom, blueBottom, 0.8f).normal(0.0f, -1.0f, 0.0f).endVertex();
bufferBuilder.vertex(scaledX + 0.0f, adjustedCloudY + 0.0f, scaledZ + 0.0f).uv((scaledX + 0.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + 0.0f) * lowpFracAccur + adjustedCloudZ).color(redBottom, greenBottom, blueBottom, 0.8f).normal(0.0f, -1.0f, 0.0f).endVertex();
}
if (adjustedCloudY <= 5.0f) {
bufferBuilder.vertex(scaledX + 0.0f, adjustedCloudY + cloudThickness - mediumpFracAccur, scaledZ + 8.0f).uv((scaledX + 0.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + 8.0f) * lowpFracAccur + adjustedCloudZ).color(redTop, greenTop, blueTop, 0.8f).normal(0.0f, 1.0f, 0.0f).endVertex();
bufferBuilder.vertex(scaledX + 8.0f, adjustedCloudY + cloudThickness - mediumpFracAccur, scaledZ + 8.0f).uv((scaledX + 8.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + 8.0f) * lowpFracAccur + adjustedCloudZ).color(redTop, greenTop, blueTop, 0.8f).normal(0.0f, 1.0f, 0.0f).endVertex();
bufferBuilder.vertex(scaledX + 8.0f, adjustedCloudY + cloudThickness - mediumpFracAccur, scaledZ + 0.0f).uv((scaledX + 8.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + 0.0f) * lowpFracAccur + adjustedCloudZ).color(redTop, greenTop, blueTop, 0.8f).normal(0.0f, 1.0f, 0.0f).endVertex();
bufferBuilder.vertex(scaledX + 0.0f, adjustedCloudY + cloudThickness - mediumpFracAccur, scaledZ + 0.0f).uv((scaledX + 0.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + 0.0f) * lowpFracAccur + adjustedCloudZ).color(redTop, greenTop, blueTop, 0.8f).normal(0.0f, 1.0f, 0.0f).endVertex();
}
if (x > -1) {
for (n3 = 0; n3 < 8; ++n3) {
bufferBuilder.vertex(scaledX + (float)n3 + 0.0f, adjustedCloudY + 0.0f, scaledZ + 8.0f).uv((scaledX + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudX, (scaledZ + 8.0f) * lowpFracAccur + adjustedCloudZ).color(redEW, greenEW, blueEW, 0.8f).normal(-1.0f, 0.0f, 0.0f).endVertex();
bufferBuilder.vertex(scaledX + (float)n3 + 0.0f, adjustedCloudY + cloudThickness, scaledZ + 8.0f).uv((scaledX + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudX, (scaledZ + 8.0f) * lowpFracAccur + adjustedCloudZ).color(redEW, greenEW, blueEW, 0.8f).normal(-1.0f, 0.0f, 0.0f).endVertex();
bufferBuilder.vertex(scaledX + (float)n3 + 0.0f, adjustedCloudY + cloudThickness, scaledZ + 0.0f).uv((scaledX + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudX, (scaledZ + 0.0f) * lowpFracAccur + adjustedCloudZ).color(redEW, greenEW, blueEW, 0.8f).normal(-1.0f, 0.0f, 0.0f).endVertex();
bufferBuilder.vertex(scaledX + (float)n3 + 0.0f, adjustedCloudY + 0.0f, scaledZ + 0.0f).uv((scaledX + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudX, (scaledZ + 0.0f) * lowpFracAccur + adjustedCloudZ).color(redEW, greenEW, blueEW, 0.8f).normal(-1.0f, 0.0f, 0.0f).endVertex();
}
}
if (x <= 1) {
for (n3 = 0; n3 < 8; ++n3) {
bufferBuilder.vertex(scaledX + (float)n3 + 1.0f - mediumpFracAccur, adjustedCloudY + 0.0f, scaledZ + 8.0f).uv((scaledX + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudX, (scaledZ + 8.0f) * lowpFracAccur + adjustedCloudZ).color(redEW, greenEW, blueEW, 0.8f).normal(1.0f, 0.0f, 0.0f).endVertex();
bufferBuilder.vertex(scaledX + (float)n3 + 1.0f - mediumpFracAccur, adjustedCloudY + cloudThickness, scaledZ + 8.0f).uv((scaledX + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudX, (scaledZ + 8.0f) * lowpFracAccur + adjustedCloudZ).color(redEW, greenEW, blueEW, 0.8f).normal(1.0f, 0.0f, 0.0f).endVertex();
bufferBuilder.vertex(scaledX + (float)n3 + 1.0f - mediumpFracAccur, adjustedCloudY + cloudThickness, scaledZ + 0.0f).uv((scaledX + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudX, (scaledZ + 0.0f) * lowpFracAccur + adjustedCloudZ).color(redEW, greenEW, blueEW, 0.8f).normal(1.0f, 0.0f, 0.0f).endVertex();
bufferBuilder.vertex(scaledX + (float)n3 + 1.0f - mediumpFracAccur, adjustedCloudY + 0.0f, scaledZ + 0.0f).uv((scaledX + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudX, (scaledZ + 0.0f) * lowpFracAccur + adjustedCloudZ).color(redEW, greenEW, blueEW, 0.8f).normal(1.0f, 0.0f, 0.0f).endVertex();
}
}
if (z > -1) {
for (n3 = 0; n3 < 8; ++n3) {
bufferBuilder.vertex(scaledX + 0.0f, adjustedCloudY + cloudThickness, scaledZ + (float)n3 + 0.0f).uv((scaledX + 0.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudZ).color(redNS, greenNS, blueNS, 0.8f).normal(0.0f, 0.0f, -1.0f).endVertex();
bufferBuilder.vertex(scaledX + 8.0f, adjustedCloudY + cloudThickness, scaledZ + (float)n3 + 0.0f).uv((scaledX + 8.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudZ).color(redNS, greenNS, blueNS, 0.8f).normal(0.0f, 0.0f, -1.0f).endVertex();
bufferBuilder.vertex(scaledX + 8.0f, adjustedCloudY + 0.0f, scaledZ + (float)n3 + 0.0f).uv((scaledX + 8.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudZ).color(redNS, greenNS, blueNS, 0.8f).normal(0.0f, 0.0f, -1.0f).endVertex();
bufferBuilder.vertex(scaledX + 0.0f, adjustedCloudY + 0.0f, scaledZ + (float)n3 + 0.0f).uv((scaledX + 0.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudZ).color(redNS, greenNS, blueNS, 0.8f).normal(0.0f, 0.0f, -1.0f).endVertex();
}
}
if (z > 1) continue;
for (n3 = 0; n3 < 8; ++n3) {
bufferBuilder.vertex(scaledX + 0.0f, adjustedCloudY + cloudThickness, scaledZ + (float)n3 + 1.0f - mediumpFracAccur).uv((scaledX + 0.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudZ).color(redNS, greenNS, blueNS, 0.8f).normal(0.0f, 0.0f, 1.0f).endVertex();
bufferBuilder.vertex(scaledX + 8.0f, adjustedCloudY + cloudThickness, scaledZ + (float)n3 + 1.0f - mediumpFracAccur).uv((scaledX + 8.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudZ).color(redNS, greenNS, blueNS, 0.8f).normal(0.0f, 0.0f, 1.0f).endVertex();
bufferBuilder.vertex(scaledX + 8.0f, adjustedCloudY + 0.0f, scaledZ + (float)n3 + 1.0f - mediumpFracAccur).uv((scaledX + 8.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudZ).color(redNS, greenNS, blueNS, 0.8f).normal(0.0f, 0.0f, 1.0f).endVertex();
bufferBuilder.vertex(scaledX + 0.0f, adjustedCloudY + 0.0f, scaledZ + (float)n3 + 1.0f - mediumpFracAccur).uv((scaledX + 0.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudZ).color(redNS, greenNS, blueNS, 0.8f).normal(0.0f, 0.0f, 1.0f).endVertex();
}
}
}
} else {
int scaledRenderDistance = (int) ((Config.Client.Graphics.CloudQuality.extendClouds ? Config.Client.Graphics.Quality.lodChunkRenderDistance : minecraft.options.renderDistance) / scale);
for (int x = -scaledRenderDistance; x < scaledRenderDistance; x += scaledRenderDistance) {
for (int z = -scaledRenderDistance; z < scaledRenderDistance; z += scaledRenderDistance) {
bufferBuilder.vertex(x, adjustedCloudY, z + scaledRenderDistance).uv((float)x * lowpFracAccur + adjustedCloudX, (float)(z + scaledRenderDistance) * lowpFracAccur + adjustedCloudZ).color(redTop, greenTop, blueTop, 0.8f).normal(0.0f, -1.0f, 0.0f).endVertex();
bufferBuilder.vertex(x + scaledRenderDistance, adjustedCloudY, z + scaledRenderDistance).uv((float)(x + scaledRenderDistance) * lowpFracAccur + adjustedCloudX, (float)(z + scaledRenderDistance) * lowpFracAccur + adjustedCloudZ).color(redTop, greenTop, blueTop, 0.8f).normal(0.0f, -1.0f, 0.0f).endVertex();
bufferBuilder.vertex(x + scaledRenderDistance, adjustedCloudY, z).uv((float)(x + scaledRenderDistance) * lowpFracAccur + adjustedCloudX, (float)z * lowpFracAccur + adjustedCloudZ).color(redTop, greenTop, blueTop, 0.8f).normal(0.0f, -1.0f, 0.0f).endVertex();
bufferBuilder.vertex(x, adjustedCloudY, z).uv((float)x * lowpFracAccur + adjustedCloudX, (float)z * lowpFracAccur + adjustedCloudZ).color(redTop, greenTop, blueTop, 0.8f).normal(0.0f, -1.0f, 0.0f).endVertex();
}
}
}
}
}
@@ -19,20 +19,43 @@
package com.seibel.lod.forge.mixins;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Matrix4f;
import com.seibel.lod.common.Config;
import com.seibel.lod.common.clouds.CloudTexture;
import com.seibel.lod.common.clouds.NoiseCloudHandler;
import com.seibel.lod.common.wrappers.McObjectConverter;
import net.minecraft.client.renderer.LevelRenderer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Matrix4f;
import com.seibel.lod.core.api.ClientApi;
import com.seibel.lod.core.objects.math.Mat4f;
import com.seibel.lod.common.wrappers.McObjectConverter;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.RenderType;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.*;
import com.mojang.math.Matrix4f;
import net.minecraft.client.CloudStatus;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.*;
import net.minecraft.client.renderer.texture.DynamicTexture;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.network.chat.ChatType;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.*;
import java.util.Random;
/**
* This class is used to mix in my rendering code
* before Minecraft starts rendering blocks.
@@ -40,20 +63,49 @@ import net.minecraft.client.renderer.RenderType;
* render last event, the LODs would render on top
* of the normal terrain.
*
* This is also the mixin for rendering the clouds
*
* @author coolGi2007
* @author James Seibel
* @version 9-19-2021
* @version 12-31-2021
*/
@Mixin(LevelRenderer.class)
public class MixinWorldRenderer
{
@Final @Shadow private static ResourceLocation CLOUDS_LOCATION;
@Shadow private final int ticks;
@Final @Shadow @NotNull private final Minecraft minecraft;
@Shadow private int prevCloudX;
@Shadow private int prevCloudY;
@Shadow private int prevCloudZ;
@Shadow @NotNull private Vec3 prevCloudColor;
@Shadow @NotNull private CloudStatus prevCloudsType;
@Shadow private boolean generateClouds;
@Shadow @NotNull private VertexBuffer cloudBuffer;
@Unique private boolean initializedClouds = false;
private static float previousPartialTicks = 0;
@Inject(at = @At("RETURN"), method = "renderClouds(Lcom/mojang/blaze3d/vertex/PoseStack;Lcom/mojang/math/Matrix4f;FDDD)V")
private void renderClouds(PoseStack modelViewMatrixStack, Matrix4f projectionMatrix, float partialTicks, double cameraXBlockPos, double cameraYBlockPos, double cameraZBlockPos, CallbackInfo callback)
{
public MixinWorldRenderer() {
throw new NullPointerException("Null cannot be cast to non-null type.");
}
@Inject(method = "renderClouds", at = @At("HEAD"), cancellable = true)
public void renderClouds(PoseStack poseStack, Matrix4f model, float tickDelta, double cameraX, double cameraY, double cameraZ, CallbackInfo ci) {
TextureManager textureManager = Minecraft.getInstance().getTextureManager();
registerClouds(textureManager);
NoiseCloudHandler.update();
if (minecraft.level.dimension() == ClientLevel.OVERWORLD) {
CloudTexture cloudTexture = NoiseCloudHandler.cloudTextures.get(NoiseCloudHandler.cloudTextures.size() - 1);
renderCloudLayer(poseStack, model, tickDelta, cameraX, cameraY, cameraZ, Config.Client.Graphics.CloudQuality.cloudHeight, 0, 1, 1, cloudTexture.resourceLocation);
}
ci.cancel();
// get the partial ticks since renderChunkLayer doesn't
// have access to them
previousPartialTicks = partialTicks;
previousPartialTicks = tickDelta;
}
// HEAD or RETURN
@@ -69,4 +121,189 @@ public class MixinWorldRenderer
ClientApi.INSTANCE.renderLods(mcModelViewMatrix, mcProjectionMatrix, previousPartialTicks);
}
}
}
// TODO: Move these outside of the mixin
// When moved out then put credit to https://github.com/misterslime/fabulousclouds-fabric
private void registerClouds(TextureManager textureManager) {
if (!this.initializedClouds) {
Random random = new Random();
NoiseCloudHandler.initCloudTextures(CLOUDS_LOCATION);
for(CloudTexture cloudTexture : NoiseCloudHandler.cloudTextures) {
cloudTexture.initNoise(random);
DynamicTexture texture = cloudTexture.getNativeImage();
textureManager.register(cloudTexture.resourceLocation, texture);
cloudTexture.setTexture(texture);
}
this.initializedClouds = true;
}
}
private void renderCloudLayer(PoseStack poseStack, Matrix4f model, float tickDelta, double cameraX, double cameraY, double cameraZ, float cloudHeight, float cloudOffset, float cloudScale, float speedMod, ResourceLocation resourceLocation) {
RenderSystem.disableCull();
RenderSystem.enableBlend();
RenderSystem.enableDepthTest();
RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
RenderSystem.depthMask(true);
float scale = 12.0F * cloudScale;
double speed = ((this.ticks + tickDelta) * (0.03F * speedMod));
double posX = (cameraX + speed) / scale;
double posY = (cloudHeight - (float) cameraY + cloudOffset) / cloudScale;
double posZ = cameraZ / scale + 0.33000001311302185D;
posX -= Math.floor(posX / 2048.0D) * 2048;
posZ -= Math.floor(posZ / 2048.0D) * 2048;
float adjustedX = (float) (posX - (double) Math.floor(posX));
float adjustedY = (float) (posY / 4.0D - (double) Math.floor(posY / 4.0D)) * 4.0F;
float adjustedZ = (float) (posZ - (double) Math.floor(posZ));
Vec3 cloudColor = minecraft.level.getCloudColor(tickDelta);
int floorX = (int) Math.floor(posX);
int floorY = (int) Math.floor(posY / 4.0D);
int floorZ = (int) Math.floor(posZ);
if (floorX != this.prevCloudX || floorY != this.prevCloudY || floorZ != this.prevCloudZ || this.minecraft.options.getCloudsType() != this.prevCloudsType || this.prevCloudColor.distanceToSqr(cloudColor) > 2.0E-4D) {
this.prevCloudX = floorX;
this.prevCloudY = floorY;
this.prevCloudZ = floorZ;
this.prevCloudColor = cloudColor;
this.prevCloudsType = this.minecraft.options.getCloudsType();
this.generateClouds = true;
}
RenderSystem.setShader(GameRenderer::getPositionTexColorNormalShader);
if (this.generateClouds) {
this.generateClouds = false;
Tesselator tessellator = Tesselator.getInstance();
BufferBuilder bufferBuilder = tessellator.getBuilder();
if (this.cloudBuffer != null) this.cloudBuffer.close();
this.cloudBuffer = new VertexBuffer();
this.buildCloudLayer(bufferBuilder, posX, posY, posZ, cloudOffset, cloudScale, cloudColor);
bufferBuilder.end();
this.cloudBuffer.upload(bufferBuilder);
}
RenderSystem.setShaderTexture(0, resourceLocation);
FogRenderer.levelFogColor();
poseStack.pushPose();
poseStack.scale(scale, cloudScale, scale);
poseStack.translate(-adjustedX, adjustedY, -adjustedZ);
if (this.cloudBuffer != null) {
int cloudMainIndex = this.prevCloudsType == CloudStatus.FANCY ? 0 : 1;
for (int cloudIndex = 1; cloudMainIndex <= cloudIndex; ++cloudMainIndex) {
if (cloudMainIndex == 0) {
RenderSystem.colorMask(false, false, false, false);
} else {
RenderSystem.colorMask(true, true, true, true);
}
ShaderInstance shader = RenderSystem.getShader();
this.cloudBuffer.drawWithShader(poseStack.last().pose(), model, shader);
}
}
poseStack.popPose();
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
RenderSystem.enableCull();
RenderSystem.disableBlend();
}
private void buildCloudLayer(BufferBuilder bufferBuilder, double cloudX, double cloudY, double cloudZ, float offset, float scale, Vec3 color) {
float lowpFracAccur = (float) Math.pow(2.0, -8);
float mediumpFracAccur = (float) Math.pow(2.0, -10);
float viewDistance = 8;
float cloudThickness = 4.0f;
float adjustedCloudX = (float)Math.floor(cloudX) * lowpFracAccur;
float adjustedCloudZ = (float)Math.floor(cloudZ) * lowpFracAccur;
float redTop = (float)color.x;
float greenTop = (float)color.y;
float blueTop = (float)color.z;
float redEW = redTop * 0.9f;
float greenEW = greenTop * 0.9f;
float blueEW = blueTop * 0.9f;
float redBottom = redTop * 0.7f;
float greenBottom = greenTop * 0.7f;
float blueBottom = blueTop * 0.7f;
float redNS = redTop * 0.8f;
float greenNS = greenTop * 0.8f;
float blueNS = blueTop * 0.8f;
bufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX_COLOR_NORMAL);
float adjustedCloudY = (float)Math.floor(cloudY / cloudThickness) * cloudThickness;
if (this.prevCloudsType == CloudStatus.FANCY) {
int scaledViewDistance = (int) (((Config.Client.Graphics.CloudQuality.extendClouds ? Config.Client.Graphics.Quality.lodChunkRenderDistance : minecraft.options.renderDistance) / 2) / scale) / 2;
for (int x = -scaledViewDistance - 1; x <= scaledViewDistance; ++x) {
for (int z = -scaledViewDistance - 1; z <= scaledViewDistance; ++z) {
int n3;
float scaledX = x * viewDistance;
float scaledZ = z * viewDistance;
if (adjustedCloudY > -5.0f) {
bufferBuilder.vertex(scaledX + 0.0f, adjustedCloudY + 0.0f, scaledZ + 8.0f).uv((scaledX + 0.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + 8.0f) * lowpFracAccur + adjustedCloudZ).color(redBottom, greenBottom, blueBottom, 0.8f).normal(0.0f, -1.0f, 0.0f).endVertex();
bufferBuilder.vertex(scaledX + 8.0f, adjustedCloudY + 0.0f, scaledZ + 8.0f).uv((scaledX + 8.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + 8.0f) * lowpFracAccur + adjustedCloudZ).color(redBottom, greenBottom, blueBottom, 0.8f).normal(0.0f, -1.0f, 0.0f).endVertex();
bufferBuilder.vertex(scaledX + 8.0f, adjustedCloudY + 0.0f, scaledZ + 0.0f).uv((scaledX + 8.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + 0.0f) * lowpFracAccur + adjustedCloudZ).color(redBottom, greenBottom, blueBottom, 0.8f).normal(0.0f, -1.0f, 0.0f).endVertex();
bufferBuilder.vertex(scaledX + 0.0f, adjustedCloudY + 0.0f, scaledZ + 0.0f).uv((scaledX + 0.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + 0.0f) * lowpFracAccur + adjustedCloudZ).color(redBottom, greenBottom, blueBottom, 0.8f).normal(0.0f, -1.0f, 0.0f).endVertex();
}
if (adjustedCloudY <= 5.0f) {
bufferBuilder.vertex(scaledX + 0.0f, adjustedCloudY + cloudThickness - mediumpFracAccur, scaledZ + 8.0f).uv((scaledX + 0.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + 8.0f) * lowpFracAccur + adjustedCloudZ).color(redTop, greenTop, blueTop, 0.8f).normal(0.0f, 1.0f, 0.0f).endVertex();
bufferBuilder.vertex(scaledX + 8.0f, adjustedCloudY + cloudThickness - mediumpFracAccur, scaledZ + 8.0f).uv((scaledX + 8.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + 8.0f) * lowpFracAccur + adjustedCloudZ).color(redTop, greenTop, blueTop, 0.8f).normal(0.0f, 1.0f, 0.0f).endVertex();
bufferBuilder.vertex(scaledX + 8.0f, adjustedCloudY + cloudThickness - mediumpFracAccur, scaledZ + 0.0f).uv((scaledX + 8.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + 0.0f) * lowpFracAccur + adjustedCloudZ).color(redTop, greenTop, blueTop, 0.8f).normal(0.0f, 1.0f, 0.0f).endVertex();
bufferBuilder.vertex(scaledX + 0.0f, adjustedCloudY + cloudThickness - mediumpFracAccur, scaledZ + 0.0f).uv((scaledX + 0.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + 0.0f) * lowpFracAccur + adjustedCloudZ).color(redTop, greenTop, blueTop, 0.8f).normal(0.0f, 1.0f, 0.0f).endVertex();
}
if (x > -1) {
for (n3 = 0; n3 < 8; ++n3) {
bufferBuilder.vertex(scaledX + (float)n3 + 0.0f, adjustedCloudY + 0.0f, scaledZ + 8.0f).uv((scaledX + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudX, (scaledZ + 8.0f) * lowpFracAccur + adjustedCloudZ).color(redEW, greenEW, blueEW, 0.8f).normal(-1.0f, 0.0f, 0.0f).endVertex();
bufferBuilder.vertex(scaledX + (float)n3 + 0.0f, adjustedCloudY + cloudThickness, scaledZ + 8.0f).uv((scaledX + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudX, (scaledZ + 8.0f) * lowpFracAccur + adjustedCloudZ).color(redEW, greenEW, blueEW, 0.8f).normal(-1.0f, 0.0f, 0.0f).endVertex();
bufferBuilder.vertex(scaledX + (float)n3 + 0.0f, adjustedCloudY + cloudThickness, scaledZ + 0.0f).uv((scaledX + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudX, (scaledZ + 0.0f) * lowpFracAccur + adjustedCloudZ).color(redEW, greenEW, blueEW, 0.8f).normal(-1.0f, 0.0f, 0.0f).endVertex();
bufferBuilder.vertex(scaledX + (float)n3 + 0.0f, adjustedCloudY + 0.0f, scaledZ + 0.0f).uv((scaledX + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudX, (scaledZ + 0.0f) * lowpFracAccur + adjustedCloudZ).color(redEW, greenEW, blueEW, 0.8f).normal(-1.0f, 0.0f, 0.0f).endVertex();
}
}
if (x <= 1) {
for (n3 = 0; n3 < 8; ++n3) {
bufferBuilder.vertex(scaledX + (float)n3 + 1.0f - mediumpFracAccur, adjustedCloudY + 0.0f, scaledZ + 8.0f).uv((scaledX + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudX, (scaledZ + 8.0f) * lowpFracAccur + adjustedCloudZ).color(redEW, greenEW, blueEW, 0.8f).normal(1.0f, 0.0f, 0.0f).endVertex();
bufferBuilder.vertex(scaledX + (float)n3 + 1.0f - mediumpFracAccur, adjustedCloudY + cloudThickness, scaledZ + 8.0f).uv((scaledX + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudX, (scaledZ + 8.0f) * lowpFracAccur + adjustedCloudZ).color(redEW, greenEW, blueEW, 0.8f).normal(1.0f, 0.0f, 0.0f).endVertex();
bufferBuilder.vertex(scaledX + (float)n3 + 1.0f - mediumpFracAccur, adjustedCloudY + cloudThickness, scaledZ + 0.0f).uv((scaledX + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudX, (scaledZ + 0.0f) * lowpFracAccur + adjustedCloudZ).color(redEW, greenEW, blueEW, 0.8f).normal(1.0f, 0.0f, 0.0f).endVertex();
bufferBuilder.vertex(scaledX + (float)n3 + 1.0f - mediumpFracAccur, adjustedCloudY + 0.0f, scaledZ + 0.0f).uv((scaledX + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudX, (scaledZ + 0.0f) * lowpFracAccur + adjustedCloudZ).color(redEW, greenEW, blueEW, 0.8f).normal(1.0f, 0.0f, 0.0f).endVertex();
}
}
if (z > -1) {
for (n3 = 0; n3 < 8; ++n3) {
bufferBuilder.vertex(scaledX + 0.0f, adjustedCloudY + cloudThickness, scaledZ + (float)n3 + 0.0f).uv((scaledX + 0.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudZ).color(redNS, greenNS, blueNS, 0.8f).normal(0.0f, 0.0f, -1.0f).endVertex();
bufferBuilder.vertex(scaledX + 8.0f, adjustedCloudY + cloudThickness, scaledZ + (float)n3 + 0.0f).uv((scaledX + 8.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudZ).color(redNS, greenNS, blueNS, 0.8f).normal(0.0f, 0.0f, -1.0f).endVertex();
bufferBuilder.vertex(scaledX + 8.0f, adjustedCloudY + 0.0f, scaledZ + (float)n3 + 0.0f).uv((scaledX + 8.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudZ).color(redNS, greenNS, blueNS, 0.8f).normal(0.0f, 0.0f, -1.0f).endVertex();
bufferBuilder.vertex(scaledX + 0.0f, adjustedCloudY + 0.0f, scaledZ + (float)n3 + 0.0f).uv((scaledX + 0.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudZ).color(redNS, greenNS, blueNS, 0.8f).normal(0.0f, 0.0f, -1.0f).endVertex();
}
}
if (z > 1) continue;
for (n3 = 0; n3 < 8; ++n3) {
bufferBuilder.vertex(scaledX + 0.0f, adjustedCloudY + cloudThickness, scaledZ + (float)n3 + 1.0f - mediumpFracAccur).uv((scaledX + 0.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudZ).color(redNS, greenNS, blueNS, 0.8f).normal(0.0f, 0.0f, 1.0f).endVertex();
bufferBuilder.vertex(scaledX + 8.0f, adjustedCloudY + cloudThickness, scaledZ + (float)n3 + 1.0f - mediumpFracAccur).uv((scaledX + 8.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudZ).color(redNS, greenNS, blueNS, 0.8f).normal(0.0f, 0.0f, 1.0f).endVertex();
bufferBuilder.vertex(scaledX + 8.0f, adjustedCloudY + 0.0f, scaledZ + (float)n3 + 1.0f - mediumpFracAccur).uv((scaledX + 8.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudZ).color(redNS, greenNS, blueNS, 0.8f).normal(0.0f, 0.0f, 1.0f).endVertex();
bufferBuilder.vertex(scaledX + 0.0f, adjustedCloudY + 0.0f, scaledZ + (float)n3 + 1.0f - mediumpFracAccur).uv((scaledX + 0.0f) * lowpFracAccur + adjustedCloudX, (scaledZ + (float)n3 + 0.5f) * lowpFracAccur + adjustedCloudZ).color(redNS, greenNS, blueNS, 0.8f).normal(0.0f, 0.0f, 1.0f).endVertex();
}
}
}
} else {
int scaledRenderDistance = (int) ((Config.Client.Graphics.CloudQuality.extendClouds ? Config.Client.Graphics.Quality.lodChunkRenderDistance : minecraft.options.renderDistance) / scale);
for (int x = -scaledRenderDistance; x < scaledRenderDistance; x += scaledRenderDistance) {
for (int z = -scaledRenderDistance; z < scaledRenderDistance; z += scaledRenderDistance) {
bufferBuilder.vertex(x, adjustedCloudY, z + scaledRenderDistance).uv((float)x * lowpFracAccur + adjustedCloudX, (float)(z + scaledRenderDistance) * lowpFracAccur + adjustedCloudZ).color(redTop, greenTop, blueTop, 0.8f).normal(0.0f, -1.0f, 0.0f).endVertex();
bufferBuilder.vertex(x + scaledRenderDistance, adjustedCloudY, z + scaledRenderDistance).uv((float)(x + scaledRenderDistance) * lowpFracAccur + adjustedCloudX, (float)(z + scaledRenderDistance) * lowpFracAccur + adjustedCloudZ).color(redTop, greenTop, blueTop, 0.8f).normal(0.0f, -1.0f, 0.0f).endVertex();
bufferBuilder.vertex(x + scaledRenderDistance, adjustedCloudY, z).uv((float)(x + scaledRenderDistance) * lowpFracAccur + adjustedCloudX, (float)z * lowpFracAccur + adjustedCloudZ).color(redTop, greenTop, blueTop, 0.8f).normal(0.0f, -1.0f, 0.0f).endVertex();
bufferBuilder.vertex(x, adjustedCloudY, z).uv((float)x * lowpFracAccur + adjustedCloudX, (float)z * lowpFracAccur + adjustedCloudZ).color(redTop, greenTop, blueTop, 0.8f).normal(0.0f, -1.0f, 0.0f).endVertex();
}
}
}
}
}