Сглажены биомы

This commit is contained in:
2026-08-09 20:35:57 +04:00
parent 9fa0370ad0
commit e7a6e587ff
2 changed files with 60 additions and 40 deletions
@@ -3,7 +3,6 @@ package su.divan2000.veila.client.render.fog;
import net.minecraft.client.MinecraftClient;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.Heightmap;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.chunk.WorldChunk;
@@ -15,8 +14,9 @@ public final class FogBiomeStreamer {
FogWorldVolume.CHUNKS_X * FogWorldVolume.CHUNKS_Z;
private static final int TOTAL_WORDS = (TOTAL_CHUNKS + 63) / 64;
// ИЗМЕНЕНО: 4×4 пикселя на чанк × 4 канала = 64 float
private static final int CHUNK_DATA_FLOATS =
FogWorldVolume.CHUNK_SIZE * FogWorldVolume.CHUNK_SIZE * 4;
FogBiomeTexture.CHUNK_DATA_FLOATS;
private static final int MAX_CHUNKS_PER_TICK = 8;
private static volatile int burstFrames = 0;
@@ -171,6 +171,7 @@ public final class FogBiomeStreamer {
}
}
// ИЗМЕНЕНО: усреднение параметров биомов
private static boolean fillBiomesIntoArray(int chunkX, int chunkZ, float[] array) {
MinecraftClient client = MinecraftClient.getInstance();
if (client.world == null) return false;
@@ -180,22 +181,43 @@ public final class FogBiomeStreamer {
if (chunk == null) return false;
int topY = client.world.getTopY() - 1;
int baseWorldX = chunkX << 4;
int baseWorldZ = chunkZ << 4;
int idx = 0;
for (int z = 0; z < FogWorldVolume.CHUNK_SIZE; z++) {
int worldZ = baseWorldZ + z;
for (int x = 0; x < FogWorldVolume.CHUNK_SIZE; x++) {
int worldX = baseWorldX + x;
// 4×4 пикселя на чанк (каждый покрывает 4×4 блока)
for (int pz = 0; pz < FogBiomeTexture.PIXELS_PER_CHUNK; pz++) {
for (int px = 0; px < FogBiomeTexture.PIXELS_PER_CHUNK; px++) {
// Суммируем параметры всех 16 блоков в этом пикселе
float sumEmission = 0;
float sumTargetDensity = 0;
float sumHumidity = 0;
float sumTimeSensitivity = 0;
for (int dz = 0; dz < FogBiomeTexture.PIXELS_PER_CHUNK; dz++) {
for (int dx = 0; dx < FogBiomeTexture.PIXELS_PER_CHUNK; dx++) {
int localX = px * FogBiomeTexture.PIXELS_PER_CHUNK + dx;
int localZ = pz * FogBiomeTexture.PIXELS_PER_CHUNK + dz;
int worldX = baseWorldX + localX;
int worldZ = baseWorldZ + localZ;
int surfaceY = chunk.getHeightmap(Heightmap.Type.WORLD_SURFACE).get(x, z);
BlockPos samplePos = new BlockPos(worldX, topY, worldZ);
RegistryEntry<Biome> biomeEntry = client.world.getBiome(samplePos);
FogBiomeParams params = FogBiomeParams.forBiome(biomeEntry);
params.pack(array, idx);
sumEmission += params.emissionMultiplier;
sumTargetDensity += params.targetDensityBase;
sumHumidity += params.humidity;
sumTimeSensitivity += params.timeSensitivity;
}
}
// Усредняем
float invCount = 1.0f / (FogBiomeTexture.PIXELS_PER_CHUNK * FogBiomeTexture.PIXELS_PER_CHUNK);
array[idx ] = sumEmission * invCount;
array[idx + 1] = sumTargetDensity * invCount;
array[idx + 2] = sumHumidity * invCount;
array[idx + 3] = sumTimeSensitivity * invCount;
idx += 4;
}
}
@@ -7,26 +7,25 @@ import java.nio.FloatBuffer;
public final class FogBiomeTexture {
public static final int SIZE_X = FogWorldVolume.SIZE_X;
public static final int SIZE_Z = FogWorldVolume.SIZE_Z;
// ИЗМЕНЕНО: 64×64 (один пиксель = 4×4 блока)
public static final int SIZE_X = FogWorldVolume.SIZE_X / 4; // 64
public static final int SIZE_Z = FogWorldVolume.SIZE_Z / 4; // 64
private static int texture = -1;
private static final int[] uploadPBOs = new int[3];
private static int uploadPBOIndex = 0;
private static final int CHUNK_DATA_FLOATS =
FogWorldVolume.CHUNK_SIZE * FogWorldVolume.CHUNK_SIZE * 4;
private static final int CHUNK_DATA_BYTES = CHUNK_DATA_FLOATS * 4;
// ИЗМЕНЕНО: 4×4 пикселя на чанк × 4 канала = 64 float
public static final int PIXELS_PER_CHUNK = 4;
public static final int CHUNK_DATA_FLOATS =
PIXELS_PER_CHUNK * PIXELS_PER_CHUNK * 4;
public static final int CHUNK_DATA_BYTES = CHUNK_DATA_FLOATS * 4;
// Буфер размером с ОДИН чанк
private static final FloatBuffer CHUNK_BUFFER =
BufferUtils.createFloatBuffer(CHUNK_DATA_FLOATS);
// Данные одного чанка
private static final float[] EMPTY_CHUNK = new float[CHUNK_DATA_FLOATS];
// Данные одного пикселя (для clearRegions)
private static final float[] EMPTY_PIXEL = {0.0f, 0.0f, 0.0f, 0.0f};
private FogBiomeTexture() {
@@ -52,8 +51,9 @@ public final class FogBiomeTexture {
(ByteBuffer) null
);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
// ИЗМЕНЕНО: GL_LINEAR для плавной интерполяции между биомами
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL12.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL12.GL_REPEAT);
@@ -63,7 +63,6 @@ public final class FogBiomeTexture {
}
public static void clear() {
// Кладем данные ОДНОГО чанка в буфер один раз
CHUNK_BUFFER.clear();
CHUNK_BUFFER.put(EMPTY_CHUNK);
CHUNK_BUFFER.flip();
@@ -71,19 +70,19 @@ public final class FogBiomeTexture {
GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture);
GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1);
// Для каждого чанка загружаем те же данные из буфера, делая rewind
// 16×16 чанков (теперь каждый = 4×4 пикселя)
for (int z = 0; z < FogWorldVolume.CHUNKS_Z; z++) {
for (int x = 0; x < FogWorldVolume.CHUNKS_X; x++) {
GL11.glTexSubImage2D(
GL11.GL_TEXTURE_2D, 0,
x * FogWorldVolume.CHUNK_SIZE,
z * FogWorldVolume.CHUNK_SIZE,
FogWorldVolume.CHUNK_SIZE,
FogWorldVolume.CHUNK_SIZE,
x * PIXELS_PER_CHUNK,
z * PIXELS_PER_CHUNK,
PIXELS_PER_CHUNK,
PIXELS_PER_CHUNK,
GL11.GL_RGBA, GL11.GL_FLOAT,
CHUNK_BUFFER
);
CHUNK_BUFFER.rewind(); // ← важно: возвращаем позицию к началу
CHUNK_BUFFER.rewind();
}
}
@@ -113,10 +112,10 @@ public final class FogBiomeTexture {
GL11.glTexSubImage2D(
GL11.GL_TEXTURE_2D,
0,
textureChunkX * FogWorldVolume.CHUNK_SIZE,
textureChunkZ * FogWorldVolume.CHUNK_SIZE,
FogWorldVolume.CHUNK_SIZE,
FogWorldVolume.CHUNK_SIZE,
textureChunkX * PIXELS_PER_CHUNK,
textureChunkZ * PIXELS_PER_CHUNK,
PIXELS_PER_CHUNK,
PIXELS_PER_CHUNK,
GL11.GL_RGBA,
GL11.GL_FLOAT,
0L
@@ -136,12 +135,11 @@ public final class FogBiomeTexture {
GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1);
for (int i = 0; i < count; i++) {
int w = widthChunks[i] * FogWorldVolume.CHUNK_SIZE;
int d = depthChunks[i] * FogWorldVolume.CHUNK_SIZE;
int w = widthChunks[i] * PIXELS_PER_CHUNK;
int d = depthChunks[i] * PIXELS_PER_CHUNK;
int totalPixels = w * d;
FloatBuffer clearBuf = BufferUtils.createFloatBuffer(totalPixels * 4);
// Кладем пустые пиксели (RGBA = 0,0,0,0) по одному
for (int j = 0; j < totalPixels; j++) {
clearBuf.put(EMPTY_PIXEL);
}
@@ -149,8 +147,8 @@ public final class FogBiomeTexture {
GL11.glTexSubImage2D(
GL11.GL_TEXTURE_2D, 0,
physX[i] * FogWorldVolume.CHUNK_SIZE,
physZ[i] * FogWorldVolume.CHUNK_SIZE,
physX[i] * PIXELS_PER_CHUNK,
physZ[i] * PIXELS_PER_CHUNK,
w, d,
GL11.GL_RGBA, GL11.GL_FLOAT,
clearBuf