Began work on biome colouring

This commit is contained in:
mcrcortex
2024-01-30 21:51:33 +10:00
parent a3f043a577
commit 8860feb58a
7 changed files with 68 additions and 10 deletions

View File

@@ -13,6 +13,9 @@ import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.Camera;
import net.minecraft.client.render.Frustum;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.util.Identifier;
import net.minecraft.world.World;
import net.minecraft.world.chunk.WorldChunk;
@@ -72,6 +75,10 @@ public class VoxelCore {
////Resave the db incase it failed a recovery
//this.world.getMapper().forceResaveStates();
var biomeRegistry = MinecraftClient.getInstance().world.getRegistryManager().get(RegistryKeys.BIOME);
for (var biome : this.world.getMapper().getBiomeEntries()) {
this.renderer.getModelManager().addBiome(biome.id, biomeRegistry.get(new Identifier(biome.biome)));
}
for (var state : this.world.getMapper().getStateEntries()) {
this.renderer.getModelManager().addEntry(state.id, state.state);

View File

@@ -16,6 +16,7 @@ import net.minecraft.client.render.RenderLayers;
import net.minecraft.fluid.FluidState;
import net.minecraft.registry.Registries;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.util.Pair;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.BlockRenderView;
@@ -40,6 +41,7 @@ import static org.lwjgl.opengl.GL12C.GL_TEXTURE_MIN_LOD;
import static org.lwjgl.opengl.GL33.glDeleteSamplers;
import static org.lwjgl.opengl.GL33.glGenSamplers;
import static org.lwjgl.opengl.GL33C.glSamplerParameteri;
import static org.lwjgl.opengl.GL45C.glGenerateTextureMipmap;
import static org.lwjgl.opengl.GL45C.glTextureSubImage2D;
//Manages the storage and updating of model states, textures and colours
@@ -53,6 +55,7 @@ public class ModelManager {
public static final int MODEL_SIZE = 64;
private final ModelTextureBakery bakery;
private final GlBuffer modelBuffer;
private final GlBuffer modelColourBuffer;
private final GlTexture textures;
private final int blockSampler = glGenSamplers();
@@ -91,12 +94,20 @@ public class ModelManager {
private final int[] idMappings;
private final Object2IntOpenHashMap<List<ColourDepthTextureData>> modelTexture2id = new Object2IntOpenHashMap<>();
private final List<Biome> biomes = new ArrayList<>();
private final List<Pair<Integer, BlockState>> modelsRequiringBiomeColours = new ArrayList<>();
public ModelManager(int modelTextureSize) {
this.modelTextureSize = modelTextureSize;
this.bakery = new ModelTextureBakery(modelTextureSize, modelTextureSize);
this.modelBuffer = new GlBuffer(MODEL_SIZE * (1<<16));
this.modelColourBuffer = new GlBuffer(4 * (1<<16));
//TODO: figure out how to do mipping :blobfox_pineapple:
this.textures = new GlTexture().store(GL_RGBA8, 1, modelTextureSize*3*256,modelTextureSize*2*256);
this.textures = new GlTexture().store(GL_RGBA8, 4, modelTextureSize*3*256,modelTextureSize*2*256);
this.metadataCache = new long[1<<16];
this.idMappings = new int[1<<20];//Max of 1 million blockstates mapping to 65k model states
Arrays.fill(this.idMappings, -1);
@@ -263,11 +274,18 @@ public class ModelManager {
//Temporary override to always be non biome specific
if (colourProvider == null) {
MemoryUtil.memPutInt(uploadPtr + 4, -1);//Set the default to nothing so that its faster on the gpu
} else if ((!hasBiomeColourResolver) || true) {
} else if (!hasBiomeColourResolver) {
Biome defaultBiome = MinecraftClient.getInstance().world.getRegistryManager().get(RegistryKeys.BIOME).get(BiomeKeys.PLAINS);
MemoryUtil.memPutInt(uploadPtr + 4, captureColourConstant(colourProvider, blockState, defaultBiome)|0xFF000000);
} else {
} else if (!this.biomes.isEmpty()) {
//Populate the list of biomes for the model state
int biomeIndex = this.modelsRequiringBiomeColours.size() * this.biomes.size();
MemoryUtil.memPutInt(uploadPtr + 4, biomeIndex);
this.modelsRequiringBiomeColours.add(new Pair<>(modelId, blockState));
long clrUploadPtr = UploadStream.INSTANCE.upload(this.modelColourBuffer, biomeIndex * 4L, 4L * this.biomes.size());
for (var biome : this.biomes) {
MemoryUtil.memPutInt(clrUploadPtr, captureColourConstant(colourProvider, blockState, biome)|0xFF000000); clrUploadPtr += 4;
}
}
@@ -277,9 +295,21 @@ public class ModelManager {
this.putTextures(modelId, textureData);
glGenerateTextureMipmap(this.textures.id);
return modelId;
}
public void addBiome(int id, Biome biome) {
this.biomes.add(biome);
if (this.biomes.size()-1 != id) {
throw new IllegalStateException("Biome ordering not consistent with biome id");
}
//TODO: Need to invalidate teh entire colour buffer and reuploadd
}
//TODO: add a method to detect biome dependent colours (can do by detecting if getColor is ever called)
// if it is, need to add it to a list and mark it as biome colour dependent or something then the shader
// will either use the uint as an index or a direct colour multiplier
@@ -388,6 +418,7 @@ public class ModelManager {
public static boolean faceExists(long metadata, int face) {
return ((metadata>>(8*face))&0xFF)!=0xFF;
}
@@ -510,9 +541,14 @@ public class ModelManager {
return this.blockSampler;
}
public int getColourBufferId() {
return this.modelColourBuffer.id;
}
public void free() {
this.bakery.free();
this.modelBuffer.free();
this.modelColourBuffer.free();
this.textures.free();
glDeleteSamplers(this.blockSampler);
}

View File

@@ -81,7 +81,8 @@ public class Gl46FarWorldRenderer extends AbstractFarWorldRenderer {
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, this.geometry.metaId());
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, this.glVisibilityBuffer.id);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, this.models.getBufferId());
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 7, this.lightDataBuffer.id);//Lighting LUT
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 7, this.models.getColourBufferId());
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 8, this.lightDataBuffer.id);//Lighting LUT
glBindVertexArray(0);
}

View File

@@ -11,6 +11,8 @@ public class ActiveSectionTracker {
private final Long2ObjectOpenHashMap<VolatileHolder<WorldSection>>[] loadedSectionCache;
private final SectionLoader loader;
@SuppressWarnings("unchecked")
public ActiveSectionTracker(int layers, SectionLoader loader) {
this.loader = loader;
this.loadedSectionCache = new Long2ObjectOpenHashMap[layers];

View File

@@ -71,7 +71,11 @@ layout(binding = 6, std430) readonly restrict buffer ModelBuffer {
BlockModel modelData[];
};
layout(binding = 7, std430) readonly restrict buffer LightingBuffer {
layout(binding = 7, std430) readonly restrict buffer ModelColourBuffer {
uint colourData[];
};
layout(binding = 8, std430) readonly restrict buffer LightingBuffer {
uint lightData[];
};

View File

@@ -15,3 +15,7 @@ uint faceHasAlphaCuttout(uint faceData) {
uint faceHasAlphaCuttoutOverride(uint faceData) {
return (faceData>>23)&1;
}
bool modelHasBiomeLUT(BlockModel model) {
return ((model.flagsA)&2) != 0;
}

View File

@@ -66,25 +66,25 @@ void main() {
vec3 offset = vec3(size, (float(face&1) + getDepthOffset(faceData, face)) * (1<<lodLevel));
if ((face>>1) == 0) {//Up/down
if ((face>>1) == 0) { //Up/down
offset = offset.xzy;
}
//Not needed, here for readability
//if ((face>>1) == 1) {//north/south
// offset = offset.xyz;
//}
if ((face>>1) == 2) {//west/east
if ((face>>1) == 2) { //west/east
offset = offset.zxy;
}
gl_Position = MVP * vec4(corner + offset,1);
gl_Position = MVP * vec4(corner + offset, 1);
//Compute the uv coordinates
vec2 modelUV = vec2(modelId&0xFF, (modelId>>8)&0xFF)*(1f/(256f));
//TODO: make the face orientated by 2x3 so that division is not a integer div and modulo isnt needed
// as these are very slow ops
baseUV = modelUV + (vec2(face%3, face/3) * (1f/(vec2(3,2)*256f)));
baseUV = modelUV + (vec2(face%3, face/3) * (1f/(vec2(3, 2)*256f)));
uv = respectiveQuadSize + faceOffset;//Add in the face offset for 0,0 uv
discardAlpha = faceHasAlphaCuttout(faceData);
@@ -96,7 +96,11 @@ void main() {
colourTinting = getLighting(extractLightId(quad));
//Apply model colour tinting
colourTinting *= uint2vec4RGBA(model.colourTint).yzwx;
uint tintColour = model.colourTint;
if (modelHasBiomeLUT(model)) {
tintColour = colourData[tintColour + extractBiomeId(quad)];
}
colourTinting *= uint2vec4RGBA(tintColour).yzwx;
//Apply face tint
if (face == 0) {