refactor: static hell is now dynamic hell! fuck oop xdd

This commit is contained in:
ZtereoHYPE 2022-09-23 12:45:39 +02:00
parent 885d2b1059
commit 5f77c6d483
4 changed files with 166 additions and 130 deletions

View file

@ -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());
}
}

View file

@ -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();
}
}

View file

@ -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};
}
}

View file

@ -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<Star> 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());
}
}