From e7a6e587ffb2307c766597dba4d5121a291672ab Mon Sep 17 00:00:00 2001 From: DIvan2000 Date: Sun, 9 Aug 2026 20:35:57 +0400 Subject: [PATCH] =?UTF-8?q?=D0=A1=D0=B3=D0=BB=D0=B0=D0=B6=D0=B5=D0=BD?= =?UTF-8?q?=D1=8B=20=D0=B1=D0=B8=D0=BE=D0=BC=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/render/fog/FogBiomeStreamer.java | 48 ++++++++++++----- .../client/render/fog/FogBiomeTexture.java | 52 +++++++++---------- 2 files changed, 60 insertions(+), 40 deletions(-) diff --git a/src/client/java/su/divan2000/veila/client/render/fog/FogBiomeStreamer.java b/src/client/java/su/divan2000/veila/client/render/fog/FogBiomeStreamer.java index e4e3c81..7f2a3f1 100644 --- a/src/client/java/su/divan2000/veila/client/render/fog/FogBiomeStreamer.java +++ b/src/client/java/su/divan2000/veila/client/render/fog/FogBiomeStreamer.java @@ -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; @@ -179,23 +180,44 @@ public final class FogBiomeStreamer { .getWorldChunk(chunkX, chunkZ, false); if (chunk == null) return false; - int topY = client.world.getTopY()-1; - + 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; - int surfaceY = chunk.getHeightmap(Heightmap.Type.WORLD_SURFACE).get(x, z); - BlockPos samplePos = new BlockPos(worldX, topY, worldZ); - RegistryEntry biomeEntry = client.world.getBiome(samplePos); + 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; - FogBiomeParams params = FogBiomeParams.forBiome(biomeEntry); - params.pack(array, idx); + BlockPos samplePos = new BlockPos(worldX, topY, worldZ); + RegistryEntry biomeEntry = client.world.getBiome(samplePos); + FogBiomeParams params = FogBiomeParams.forBiome(biomeEntry); + + 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; } } diff --git a/src/client/java/su/divan2000/veila/client/render/fog/FogBiomeTexture.java b/src/client/java/su/divan2000/veila/client/render/fog/FogBiomeTexture.java index e9de662..7bed560 100644 --- a/src/client/java/su/divan2000/veila/client/render/fog/FogBiomeTexture.java +++ b/src/client/java/su/divan2000/veila/client/render/fog/FogBiomeTexture.java @@ -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