From 5f77c6d483c29ff277bd0478a942aac4f03d9f5c Mon Sep 17 00:00:00 2001 From: ZtereoHYPE <57519662+ZtereoHYPE@users.noreply.github.com> Date: Fri, 23 Sep 2022 12:45:39 +0200 Subject: [PATCH] refactor: static hell is now dynamic hell! fuck oop xdd --- .../example/nebula/NebulaSkyboxPainter.java | 54 +++++++ .../ztereohype/example/nebula/Skybox.java | 83 ++++++++++- .../example/nebula/SkyboxPainter.java | 25 ++++ .../ztereohype/example/star/SkyManager.java | 134 +----------------- 4 files changed, 166 insertions(+), 130 deletions(-) create mode 100644 src/main/java/codes/ztereohype/example/nebula/NebulaSkyboxPainter.java create mode 100644 src/main/java/codes/ztereohype/example/nebula/SkyboxPainter.java diff --git a/src/main/java/codes/ztereohype/example/nebula/NebulaSkyboxPainter.java b/src/main/java/codes/ztereohype/example/nebula/NebulaSkyboxPainter.java new file mode 100644 index 0000000..86c66d2 --- /dev/null +++ b/src/main/java/codes/ztereohype/example/nebula/NebulaSkyboxPainter.java @@ -0,0 +1,54 @@ +package codes.ztereohype.example.nebula; + +import codes.ztereohype.example.Gradient; +import net.minecraft.util.FastColor; +import net.minecraft.util.Mth; +import net.minecraft.world.level.levelgen.synth.PerlinNoise; + +import java.awt.*; + +public class NebulaSkyboxPainter extends SkyboxPainter { + private static final float SCALING_FACTOR = 1f; + private static final float BASE_NOISE_AMOUNT = 0.7f; // the amount of base noise to keep + + private final Gradient nebulaGradient; + + public NebulaSkyboxPainter(PerlinNoise noise, Gradient nebula_gradient) { + super(noise); + nebulaGradient = nebula_gradient; + } + + @Override + int getColour(float x, float y, float z) { + float[] projCoords = this.projectOnSphere(x, y, z); + x = projCoords[0]; + y = projCoords[1]; + z = projCoords[2]; + + float offset = (float) noise.getValue(x * SCALING_FACTOR * 3, y * SCALING_FACTOR * 3, z * SCALING_FACTOR * 3); + + x += offset/5f; + y += offset/5f; + z += offset/5f; + + // 0..1 + double noiseValue = Mth.clamp(noise.getValue(x * SCALING_FACTOR, y * SCALING_FACTOR, z * SCALING_FACTOR) + 0.5, 0D, 1D); + + // 0..1 + double subtractionValue = Mth.clamp(noise.getOctaveNoise(1).noise(x * SCALING_FACTOR, y * SCALING_FACTOR, z * SCALING_FACTOR) + 0.5, 0D, 1D); + +// double[] derivates = new double[3]; +// noise.getOctaveNoise(0).noiseWithDerivative(x * SCALING_FACTOR, y * SCALING_FACTOR, z * SCALING_FACTOR, derivates); +// double maxDerivative = Mth.clamp(Math.max(Math.max(derivates[0], derivates[1]), derivates[2]) * 0.5 + 0.5, 0, 0); + + int alpha = (int)(Mth.clamp((noiseValue * (1D / BASE_NOISE_AMOUNT) - (1D / BASE_NOISE_AMOUNT - 1)) * 255D, 1D, 254.99D)); // otherwise death occurs + + alpha = (int) Mth.clamp(alpha - subtractionValue * 128, 0, 255); //todo subtract colour channels separately + + double colourValue = Mth.clamp((alpha / 255D), 0D, 1D); + + Color color = nebulaGradient.getAt(colourValue); + + return FastColor.ARGB32.color(alpha, color.getBlue(), color.getGreen(), color.getRed()); + } +} diff --git a/src/main/java/codes/ztereohype/example/nebula/Skybox.java b/src/main/java/codes/ztereohype/example/nebula/Skybox.java index 047940c..5648e1d 100644 --- a/src/main/java/codes/ztereohype/example/nebula/Skybox.java +++ b/src/main/java/codes/ztereohype/example/nebula/Skybox.java @@ -1,16 +1,22 @@ package codes.ztereohype.example.nebula; +import codes.ztereohype.example.ExampleMod; +import com.mojang.blaze3d.platform.NativeImage; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.*; import com.mojang.math.Matrix4f; import lombok.Getter; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.texture.DynamicTexture; +import net.minecraft.world.level.levelgen.synth.ImprovedNoise; +import net.minecraft.world.level.levelgen.synth.PerlinNoise; + +import java.util.stream.IntStream; public class Skybox { public static final int RESOLUTION = 256; - public final DynamicTexture skyTexture = new DynamicTexture(RESOLUTION * 4, RESOLUTION * 4, false); + private final DynamicTexture skyTexture = new DynamicTexture(RESOLUTION * 4, RESOLUTION * 4, false); private final @Getter VertexBuffer skyboxBuffer = new VertexBuffer(); @@ -18,6 +24,7 @@ public class Skybox { generateVertices(); } + @SuppressWarnings("ConstantConditions") public void render(PoseStack poseStack, Matrix4f projectionMatrix) { RenderSystem.setShader(GameRenderer::getPositionTexShader); RenderSystem.setShaderTexture(0, skyTexture.getId()); @@ -25,7 +32,78 @@ public class Skybox { this.skyboxBuffer.bind(); this.skyboxBuffer.drawWithShader(poseStack.last() .pose(), projectionMatrix, GameRenderer.getPositionTexShader()); - VertexBuffer.unbind(); + } + + public void paint(SkyboxPainter painter) { + NativeImage skyNativeTex = this.skyTexture.getPixels(); + + // top face + for (int texY = 0; texY < RESOLUTION; texY++) { + for (int texX = 0; texX < RESOLUTION; texX++) { + float x = (texX / (float) RESOLUTION) * 2 - 1; + float y = 1; + float z = (texY / (float) RESOLUTION) * 2 - 1; + + skyNativeTex.setPixelRGBA(texX + 2 * RESOLUTION, texY, painter.getColour(x, y, z)); + } + } + + // bottom face + for (int texY = 0; texY < RESOLUTION; texY++) { + for (int texX = 0; texX < RESOLUTION; texX++) { + float x = (texX / (float) RESOLUTION) * 2 - 1; + float y = -1; + float z = (texY / (float) RESOLUTION) * 2 - 1; + + skyNativeTex.setPixelRGBA(texX + 2 * RESOLUTION, texY + 2 * RESOLUTION, painter.getColour(x, y, z)); + } + } + + // -x face + for (int texY = 0; texY < RESOLUTION; texY++) { + for (int texX = 0; texX < RESOLUTION; texX++) { + float x = -1; + float y = (texY / (float) RESOLUTION) * 2 - 1; + float z = (texX / (float) RESOLUTION) * 2 - 1; + + skyNativeTex.setPixelRGBA(texX, texY + RESOLUTION, painter.getColour(x, y, z)); + } + } + + // +x face + for (int texY = 0; texY < RESOLUTION; texY++) { + for (int texX = 0; texX < RESOLUTION; texX++) { + float x = 1; + float y = (texY / (float) RESOLUTION) * 2 - 1; + float z = (texX / (float) RESOLUTION) * 2 - 1; + + skyNativeTex.setPixelRGBA(texX + 2 * RESOLUTION, texY + RESOLUTION, painter.getColour(x, y, z)); + } + } + + // +z face + for (int texY = 0; texY < RESOLUTION; texY++) { + for (int texX = 0; texX < RESOLUTION; texX++) { + float x = (texX / (float) RESOLUTION) * 2 - 1; + float y = (texY / (float) RESOLUTION) * 2 - 1; + float z = 1; + + skyNativeTex.setPixelRGBA(texX + RESOLUTION, texY + RESOLUTION, painter.getColour(x, y, z)); + } + } + + // -z face + for (int texY = 0; texY < RESOLUTION; texY++) { + for (int texX = 0; texX < RESOLUTION; texX++) { + float x = (texX / (float) RESOLUTION) * 2 - 1; + float y = (texY / (float) RESOLUTION) * 2 - 1; + float z = -1; + + skyNativeTex.setPixelRGBA(texX + 3 * RESOLUTION, texY + RESOLUTION, painter.getColour(x, y, z)); + } + } + + this.skyTexture.upload(); } private void generateVertices() { @@ -75,6 +153,5 @@ public class Skybox { skyboxBuffer.bind(); skyboxBuffer.upload(skyboxBuilder.end()); -// VertexBuffer.unbind(); } } diff --git a/src/main/java/codes/ztereohype/example/nebula/SkyboxPainter.java b/src/main/java/codes/ztereohype/example/nebula/SkyboxPainter.java new file mode 100644 index 0000000..dccb516 --- /dev/null +++ b/src/main/java/codes/ztereohype/example/nebula/SkyboxPainter.java @@ -0,0 +1,25 @@ +package codes.ztereohype.example.nebula; + +import net.minecraft.util.Mth; +import net.minecraft.world.level.levelgen.synth.PerlinNoise; + +public abstract class SkyboxPainter { + protected final PerlinNoise noise; + + SkyboxPainter(PerlinNoise noise) { + this.noise = noise; + } + + abstract int getColour(float x, float y, float z); + + public float[] projectOnSphere(float x, float y, float z) { + float invDistance = Mth.fastInvSqrt(x * x + y * y + z * z); + + //divide by distance to get projection on sphere (shorten the vector) + x *= invDistance; + y *= invDistance; + z *= invDistance; + + return new float[] {x, y, z}; + } +} diff --git a/src/main/java/codes/ztereohype/example/star/SkyManager.java b/src/main/java/codes/ztereohype/example/star/SkyManager.java index 7488bdd..762b753 100644 --- a/src/main/java/codes/ztereohype/example/star/SkyManager.java +++ b/src/main/java/codes/ztereohype/example/star/SkyManager.java @@ -2,7 +2,9 @@ package codes.ztereohype.example.star; import codes.ztereohype.example.ExampleMod; import codes.ztereohype.example.Gradient; +import codes.ztereohype.example.nebula.NebulaSkyboxPainter; import codes.ztereohype.example.nebula.Skybox; +import codes.ztereohype.example.nebula.SkyboxPainter; import com.mojang.blaze3d.platform.NativeImage; import com.mojang.blaze3d.vertex.*; import net.minecraft.util.FastColor; @@ -24,7 +26,6 @@ public class SkyManager { private static final BufferBuilder starBufferBuilder = Tesselator.getInstance().getBuilder(); private static final int STARS = 1500; - private static final float SCALING_FACTOR = 1f; public static ArrayList starList = new ArrayList<>(); public static void generateSky() { @@ -39,7 +40,10 @@ public class SkyManager { buildGradients(); - generateNebulaTextures(randomSource); + PerlinNoise perlinNoise = PerlinNoise.create(randomSource, IntStream.of(1, 2, 3, 4, 5)); + NebulaSkyboxPainter painter = new NebulaSkyboxPainter(perlinNoise, NEBULA_GRADIENT); + + ExampleMod.nebulaSkybox.paint(painter); starList.clear(); generateStars(randomSource); @@ -72,7 +76,7 @@ public class SkyManager { float randZ = randomSource.nextFloat() * 2.0F - 1.0F; float resizeSpeed = 0.03f + randomSource.nextFloat() * 0.04f; - float spinSpeed = randomSource.nextFloat() * 0.02f - 0.01f; // wtf is this? + float spinSpeed = randomSource.nextFloat() * 0.02f - 0.01f; Color starColor = STAR_GRADIENT.getAt(randomSource.nextFloat()); @@ -96,130 +100,6 @@ public class SkyManager { starBuffer.bind(); starBuffer.upload(starBufferBuilder.end()); -// VertexBuffer.unbind(); - } - - public static void generateNebulaTextures(RandomSource randomSource) { - PerlinNoise perlinNoise = PerlinNoise.create(randomSource, IntStream.of(1, 2, 3, 4, 5)); - ImprovedNoise distortionNoise = new ImprovedNoise(randomSource); - NativeImage skyNativeTex = ExampleMod.nebulaSkybox.skyTexture.getPixels(); - -// for (int face = 0; face < 6; ++face) { -// for (int texY = 0; texY < NEBULAS_RESOLUTION; texY++) { -// for (int texX = 0; texX < NEBULAS_RESOLUTION; texX++) { -// float x = (texX / (float) NEBULAS_RESOLUTION) * 2 - 1; -// float y = 1; -// float z = (texY / (float) NEBULAS_RESOLUTION) * 2 - 1; -// -// -// -// skyNativeTex.setPixelRGBA(texX + 2 * NEBULAS_RESOLUTION, texY, getFunnyColour(x, y, z, perlinNoise, distortionNoise)); -// } -// } -// } - - // top face - for (int texY = 0; texY < RESOLUTION; texY++) { - for (int texX = 0; texX < RESOLUTION; texX++) { - float x = (texX / (float) RESOLUTION) * 2 - 1; - float y = 1; - float z = (texY / (float) RESOLUTION) * 2 - 1; - - skyNativeTex.setPixelRGBA(texX + 2 * RESOLUTION, texY, getFunnyColour(x, y, z, perlinNoise, distortionNoise)); - } - } - - // bottom face - for (int texY = 0; texY < RESOLUTION; texY++) { - for (int texX = 0; texX < RESOLUTION; texX++) { - float x = (texX / (float) RESOLUTION) * 2 - 1; - float y = -1; - float z = (texY / (float) RESOLUTION) * 2 - 1; - - skyNativeTex.setPixelRGBA(texX + 2 * RESOLUTION, texY + 2 * RESOLUTION, getFunnyColour(x, y, z, perlinNoise, distortionNoise)); - } - } - - // -x face - for (int texY = 0; texY < RESOLUTION; texY++) { - for (int texX = 0; texX < RESOLUTION; texX++) { - float x = -1; - float y = (texY / (float) RESOLUTION) * 2 - 1; - float z = (texX / (float) RESOLUTION) * 2 - 1; - - skyNativeTex.setPixelRGBA(texX, texY + RESOLUTION, getFunnyColour(x, y, z, perlinNoise, distortionNoise)); - } - } - - // +x face - for (int texY = 0; texY < RESOLUTION; texY++) { - for (int texX = 0; texX < RESOLUTION; texX++) { - float x = 1; - float y = (texY / (float) RESOLUTION) * 2 - 1; - float z = (texX / (float) RESOLUTION) * 2 - 1; - - skyNativeTex.setPixelRGBA(texX + 2 * RESOLUTION, texY + RESOLUTION, getFunnyColour(x, y, z, perlinNoise, distortionNoise)); - } - } - - // +z face - for (int texY = 0; texY < RESOLUTION; texY++) { - for (int texX = 0; texX < RESOLUTION; texX++) { - float x = (texX / (float) RESOLUTION) * 2 - 1; - float y = (texY / (float) RESOLUTION) * 2 - 1; - float z = 1; - - skyNativeTex.setPixelRGBA(texX + RESOLUTION, texY + RESOLUTION, getFunnyColour(x, y, z, perlinNoise, distortionNoise)); - } - } - - // -z face - for (int texY = 0; texY < RESOLUTION; texY++) { - for (int texX = 0; texX < RESOLUTION; texX++) { - float x = (texX / (float) RESOLUTION) * 2 - 1; - float y = (texY / (float) RESOLUTION) * 2 - 1; - float z = -1; - - skyNativeTex.setPixelRGBA(texX + 3 * RESOLUTION, texY + RESOLUTION, getFunnyColour(x, y, z, perlinNoise, distortionNoise)); - } - } - - ExampleMod.nebulaSkybox.skyTexture.upload(); - } - - public static int getFunnyColour(float x, float y, float z, PerlinNoise noise, ImprovedNoise subtractionNoise) { - double baseNoiseAmount = 0.7f; // the amount of base noise to keep - - float invDistance = Mth.fastInvSqrt(x * x + y * y + z * z); - - //divide by distance to get projection on sphere (shorten the vector) - x *= invDistance; - y *= invDistance; - z *= invDistance; - - float offset = (float) noise.getValue(x * SCALING_FACTOR * 3, y * SCALING_FACTOR * 3, z * SCALING_FACTOR * 3); - - x += offset/5f; - y += offset/5f; - z += offset/5f; - - // 0..1 - double noiseValue = Mth.clamp(noise.getValue(x * SCALING_FACTOR, y * SCALING_FACTOR, z * SCALING_FACTOR) + 0.5, 0D, 1D); - double subtractionValue = Mth.clamp(subtractionNoise.noise(x * SCALING_FACTOR, y * SCALING_FACTOR, z * SCALING_FACTOR) + 0.5, 0D, 1D); - -// double[] derivates = new double[3]; -// noise.getOctaveNoise(0).noiseWithDerivative(x * SCALING_FACTOR, y * SCALING_FACTOR, z * SCALING_FACTOR, derivates); -// double maxDerivative = Mth.clamp(Math.max(Math.max(derivates[0], derivates[1]), derivates[2]) * 0.5 + 0.5, 0, 0); - - int alpha = (int)(Mth.clamp((noiseValue * (1D / baseNoiseAmount) - (1D / baseNoiseAmount - 1)) * 255D, 1D, 254.99D)); // otherwise death occurs - - alpha = (int) Mth.clamp(alpha - subtractionValue * 255, 0, 255); //todo subtract colour channels separately - - double colourValue = Mth.clamp((alpha / 255D), 0D, 1D); - - Color color = NEBULA_GRADIENT.getAt(colourValue); - - return FastColor.ARGB32.color(alpha, color.getBlue(), color.getGreen(), color.getRed()); } }