fixes and work on ao, shading, tinting and lighting
This commit is contained in:
@@ -23,13 +23,14 @@ import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.resources.Identifier;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.ColorResolver;
|
||||
import net.minecraft.world.level.LightLayer;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.Biomes;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.LeavesBlock;
|
||||
import net.minecraft.world.level.block.LiquidBlock;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
@@ -65,9 +66,9 @@ public class ModelFactory {
|
||||
|
||||
//TODO: replace the fluid BlockState with a client model id integer of the fluidState, requires looking up
|
||||
// the fluid state in the mipper
|
||||
private record ModelEntry(ColourDepthTextureData down, ColourDepthTextureData up, ColourDepthTextureData north, ColourDepthTextureData south, ColourDepthTextureData west, ColourDepthTextureData east, int fluidBlockStateId) {
|
||||
public ModelEntry(ColourDepthTextureData[] textures, int fluidBlockStateId) {
|
||||
this(textures[0], textures[1], textures[2], textures[3], textures[4], textures[5], fluidBlockStateId);
|
||||
private record ModelEntry(ColourDepthTextureData down, ColourDepthTextureData up, ColourDepthTextureData north, ColourDepthTextureData south, ColourDepthTextureData west, ColourDepthTextureData east, int fluidBlockStateId, int tintingColour) {
|
||||
public ModelEntry(ColourDepthTextureData[] textures, int fluidBlockStateId, int tintingColour) {
|
||||
this(textures[0], textures[1], textures[2], textures[3], textures[4], textures[5], fluidBlockStateId, tintingColour);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +152,19 @@ public class ModelFactory {
|
||||
this.customBlockStateIdMapping = mapping;
|
||||
}
|
||||
|
||||
private record RawBakeResult(int blockId, BlockState blockState, MemoryBuffer rawData) {
|
||||
private static final class RawBakeResult {
|
||||
private final int blockId;
|
||||
private final BlockState blockState;
|
||||
private final MemoryBuffer rawData;
|
||||
|
||||
public boolean isShaded;
|
||||
|
||||
public RawBakeResult(int blockId, BlockState blockState, MemoryBuffer rawData) {
|
||||
this.blockId = blockId;
|
||||
this.blockState = blockState;
|
||||
this.rawData = rawData;
|
||||
}
|
||||
|
||||
public RawBakeResult(int blockId, BlockState blockState) {
|
||||
this(blockId, blockState, new MemoryBuffer(MODEL_TEXTURE_SIZE*MODEL_TEXTURE_SIZE*2*4*6));
|
||||
}
|
||||
@@ -206,7 +219,7 @@ public class ModelFactory {
|
||||
|
||||
RawBakeResult result = new RawBakeResult(blockId, blockState);
|
||||
int allocation = this.downstream.download(MODEL_TEXTURE_SIZE*MODEL_TEXTURE_SIZE*2*4*6, ptr -> this.rawBakeResults.add(result.cpyBuf(ptr)));
|
||||
this.bakery.renderToStream(blockState, this.downstream.getBufferId(), allocation);
|
||||
result.isShaded = this.bakery.renderToStream(blockState, this.downstream.getBufferId(), allocation);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -232,7 +245,7 @@ public class ModelFactory {
|
||||
}
|
||||
}
|
||||
result.rawData.free();
|
||||
var bakeResult = this.processTextureBakeResult(result.blockId, result.blockState, textureData);
|
||||
var bakeResult = this.processTextureBakeResult(result.blockId, result.blockState, textureData, result.isShaded);
|
||||
if (bakeResult!=null) {
|
||||
this.uploadResults.add(bakeResult);
|
||||
}
|
||||
@@ -248,7 +261,7 @@ public class ModelFactory {
|
||||
var biomeEntry = this.biomeQueue.poll();
|
||||
while (biomeEntry != null) {
|
||||
var biomeRegistry = Minecraft.getInstance().level.registryAccess().lookupOrThrow(Registries.BIOME);
|
||||
var res = this.addBiome0(biomeEntry.id, biomeRegistry.getValue(ResourceLocation.parse(biomeEntry.biome)));
|
||||
var res = this.addBiome0(biomeEntry.id, biomeRegistry.getValue(Identifier.parse(biomeEntry.biome)));
|
||||
if (res != null) {
|
||||
this.uploadResults.add(res);
|
||||
}
|
||||
@@ -324,7 +337,7 @@ public class ModelFactory {
|
||||
}
|
||||
}
|
||||
|
||||
private ModelBakeResultUpload processTextureBakeResult(int blockId, BlockState blockState, ColourDepthTextureData[] textureData) {
|
||||
private ModelBakeResultUpload processTextureBakeResult(int blockId, BlockState blockState, ColourDepthTextureData[] textureData, boolean isShaded) {
|
||||
if (this.idMappings[blockId] != -1) {
|
||||
//This should be impossible to reach as it means that multiple bakes for the same blockId happened and where inflight at the same time!
|
||||
throw new IllegalStateException("Block id already added: " + blockId + " for state: " + blockState);
|
||||
@@ -357,8 +370,16 @@ public class ModelFactory {
|
||||
}
|
||||
}
|
||||
|
||||
var colourProvider = getColourProvider(blockState.getBlock());
|
||||
|
||||
boolean isBiomeColourDependent = false;
|
||||
if (colourProvider != null) {
|
||||
isBiomeColourDependent = isBiomeDependentColour(colourProvider, blockState);
|
||||
}
|
||||
|
||||
ModelEntry entry;
|
||||
{//Deduplicate same entries
|
||||
var entry = new ModelEntry(textureData, clientFluidStateId);
|
||||
entry = new ModelEntry(textureData, clientFluidStateId, isBiomeColourDependent||colourProvider==null?-1:captureColourConstant(colourProvider, blockState, DEFAULT_BIOME)|0xFF000000);
|
||||
int possibleDuplicate = this.modelTexture2id.getInt(entry);
|
||||
if (possibleDuplicate != -1) {//Duplicate found
|
||||
this.idMappings[blockId] = possibleDuplicate;
|
||||
@@ -400,7 +421,6 @@ public class ModelFactory {
|
||||
int checkMode = blockRenderLayer==ChunkSectionLayer.SOLID?TextureUtils.WRITE_CHECK_STENCIL:TextureUtils.WRITE_CHECK_ALPHA;
|
||||
|
||||
|
||||
var colourProvider = getColourProvider(blockState.getBlock());
|
||||
|
||||
|
||||
ModelBakeResultUpload uploadResult = new ModelBakeResultUpload();
|
||||
@@ -409,10 +429,7 @@ public class ModelFactory {
|
||||
|
||||
//TODO: implement;
|
||||
// TODO: if it has a constant colour instead... idk why (apparently for things like spruce leaves)?? but premultiply the texture data by the constant colour
|
||||
boolean isBiomeColourDependent = false;
|
||||
if (colourProvider != null) {
|
||||
isBiomeColourDependent = isBiomeDependentColour(colourProvider, blockState);
|
||||
}
|
||||
|
||||
//If it contains fluid but isnt a fluid
|
||||
if ((!isFluid) && (!blockState.getFluidState().isEmpty()) && clientFluidStateId != -1) {
|
||||
|
||||
@@ -535,7 +552,7 @@ public class ModelFactory {
|
||||
//Change the scale from 0->1 (ends inclusive)
|
||||
// this is cursed also warning stuff at 63 (i.e half a pixel from the end will be clamped to the end)
|
||||
int enc = Math.round(offset*64);
|
||||
faceModelData |= Math.min(enc,63)<<16;
|
||||
faceModelData |= Math.min(enc,62)<<16;
|
||||
//Still have 11 bits free
|
||||
|
||||
//Stuff like fences are solid, however they have extra side piece that mean it needs to have discard on
|
||||
@@ -575,7 +592,10 @@ public class ModelFactory {
|
||||
modelFlags |= colourProvider != null?1:0;
|
||||
modelFlags |= isBiomeColourDependent?2:0;//Basicly whether to use the next int as a colour or as a base index/id into a colour buffer for biome dependent colours
|
||||
modelFlags |= blockRenderLayer == ChunkSectionLayer.TRANSLUCENT?4:0;//Is translucent
|
||||
modelFlags |= blockRenderLayer == ChunkSectionLayer.CUTOUT?0:8;//Dont use mipmaps (AND ALSO FKING SPECIFIES IF IT HAS AO, WHY??? GREAT QUESTION, TODO FIXE THIS)
|
||||
|
||||
|
||||
//TODO: THIS
|
||||
modelFlags |= isShaded?8:0;//model has AO and shade
|
||||
|
||||
//modelFlags |= blockRenderLayer == RenderLayer.getSolid()?0:1;// should discard alpha
|
||||
MemoryUtil.memPutInt(uploadPtr, modelFlags); uploadPtr += 4;
|
||||
@@ -585,7 +605,7 @@ public class ModelFactory {
|
||||
if (colourProvider == null) {
|
||||
MemoryUtil.memPutInt(uploadPtr, -1);//Set the default to nothing so that its faster on the gpu
|
||||
} else if (!isBiomeColourDependent) {
|
||||
MemoryUtil.memPutInt(uploadPtr, captureColourConstant(colourProvider, blockState, DEFAULT_BIOME)|0xFF000000);
|
||||
MemoryUtil.memPutInt(uploadPtr, entry.tintingColour);
|
||||
} else if (!this.biomes.isEmpty()) {
|
||||
//Populate the list of biomes for the model state
|
||||
int biomeIndex = this.modelsRequiringBiomeColours.size() * this.biomes.size();
|
||||
|
||||
@@ -2,6 +2,7 @@ package me.cortex.voxy.client.core.model.bakery;
|
||||
|
||||
|
||||
import me.cortex.voxy.common.util.MemoryBuffer;
|
||||
import net.minecraft.client.model.geom.builders.UVPair;
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
@@ -15,6 +16,8 @@ public final class ReuseVertexConsumer implements VertexConsumer {
|
||||
private int count;
|
||||
private int defaultMeta;
|
||||
|
||||
public boolean anyShaded;
|
||||
|
||||
public ReuseVertexConsumer() {
|
||||
this.reset();
|
||||
}
|
||||
@@ -45,6 +48,11 @@ public final class ReuseVertexConsumer implements VertexConsumer {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VertexConsumer setColor(int i) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReuseVertexConsumer setUv(float u, float v) {
|
||||
MemoryUtil.memPutFloat(this.ptr + 16, u);
|
||||
@@ -67,17 +75,19 @@ public final class ReuseVertexConsumer implements VertexConsumer {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VertexConsumer setLineWidth(float f) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public ReuseVertexConsumer quad(BakedQuad quad, int metadata) {
|
||||
this.anyShaded |= quad.shade();
|
||||
this.ensureCanPut();
|
||||
int[] data = quad.vertices();
|
||||
for (int i = 0; i < 4; i++) {
|
||||
float x = Float.intBitsToFloat(data[i * 8]);
|
||||
float y = Float.intBitsToFloat(data[i * 8 + 1]);
|
||||
float z = Float.intBitsToFloat(data[i * 8 + 2]);
|
||||
this.addVertex(x,y,z);
|
||||
float u = Float.intBitsToFloat(data[i * 8 + 4]);
|
||||
float v = Float.intBitsToFloat(data[i * 8 + 5]);
|
||||
this.setUv(u,v);
|
||||
var pos = quad.position(i);
|
||||
this.addVertex(pos.x(), pos.y(), pos.z());
|
||||
long puv = quad.packedUV(i);
|
||||
this.setUv(UVPair.unpackU(puv),UVPair.unpackV(puv));
|
||||
|
||||
this.meta(metadata);
|
||||
}
|
||||
@@ -98,6 +108,7 @@ public final class ReuseVertexConsumer implements VertexConsumer {
|
||||
}
|
||||
|
||||
public ReuseVertexConsumer reset() {
|
||||
this.anyShaded = false;
|
||||
this.defaultMeta = 0;//RESET THE DEFAULT META
|
||||
this.count = 0;
|
||||
this.ptr = this.buffer.address - VERTEX_FORMAT_SIZE;//the thing is first time this gets incremented by FORMAT_STRIDE
|
||||
|
||||
@@ -191,8 +191,9 @@ public class RenderDataFactory {
|
||||
boolean a = ModelQueries.isTranslucent(metadata);
|
||||
boolean b = ModelQueries.isDoubleSided(metadata);
|
||||
//Pre shift by 1
|
||||
type = a|b?0:4;
|
||||
type |= b?2:0;
|
||||
//type = a|b?0:4;
|
||||
//type |= b&!a?2:0;
|
||||
type = a?0:(b?2:4);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
@@ -39,6 +39,6 @@ bool modelIsTranslucent(BlockModel model) {
|
||||
return ((model.flagsA)&4u) != 0;
|
||||
}
|
||||
|
||||
bool modelHasMipmaps(BlockModel model) {
|
||||
bool modelIsShaded(BlockModel model) {
|
||||
return ((model.flagsA)&8u) != 0;
|
||||
}
|
||||
@@ -98,7 +98,7 @@ layout(binding = LIGHTING_SAMPLER_BINDING) uniform sampler2D lightSampler;
|
||||
|
||||
vec4 getLighting(uint index) {
|
||||
int i2 = int(index);
|
||||
return texture(lightSampler, clamp((vec2((i2>>4)&0xF, i2&0xF))/16, vec2(8.0f/256), vec2(248.0f/256)));
|
||||
return texture(lightSampler, clamp((vec2((i2>>4)&0xF, i2&0xF))/15, vec2(8.0f/256), vec2(248.0f/256)));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -43,15 +43,15 @@ vec4 uint2vec4RGBA(uint colour) {
|
||||
return vec4((uvec4(colour)>>uvec4(24,16,8,0))&uvec4(0xFF))/255.0;
|
||||
}
|
||||
|
||||
bool useMipmaps() {
|
||||
return (interData.x&2u)==0u;
|
||||
}
|
||||
//bool useMipmaps() {
|
||||
// return (interData.x&2u)==0u;
|
||||
//}
|
||||
|
||||
uint tintingState() {
|
||||
return (interData.x>>2)&3u;
|
||||
}
|
||||
|
||||
bool useCutout() {
|
||||
bool useDiscard() {
|
||||
return (interData.x&1u)==1u;
|
||||
}
|
||||
|
||||
@@ -129,14 +129,16 @@ void main() {
|
||||
vec2 uv2 = modf(uv, tile)*(1.0/(vec2(3.0,2.0)*256.0));
|
||||
vec4 colour;
|
||||
vec2 texPos = uv2 + getBaseUV();
|
||||
if (useMipmaps()) {
|
||||
//This is deprecated, TODO: remove the non mip code path
|
||||
//if (useMipmaps())
|
||||
{
|
||||
vec2 uvSmol = uv*(1.0/(vec2(3.0,2.0)*256.0));
|
||||
vec2 dx = dFdx(uvSmol);//vec2(lDx, dDx);
|
||||
vec2 dy = dFdy(uvSmol);//vec2(lDy, dDy);
|
||||
colour = textureGrad(blockModelAtlas, texPos, dx, dy);
|
||||
} else {
|
||||
colour = textureLod(blockModelAtlas, texPos, 0);
|
||||
}
|
||||
}// else {
|
||||
// colour = textureLod(blockModelAtlas, texPos, 0);
|
||||
//}
|
||||
|
||||
//If we are in shaders and are a helper invocation, just exit, as it enables extra performance gains for small sized
|
||||
// fragments, we do this here after derivative computation
|
||||
@@ -162,7 +164,11 @@ void main() {
|
||||
|
||||
|
||||
//Also, small quad is really fking over the mipping level somehow
|
||||
if (useCutout() && (textureLod(blockModelAtlas, texPos, 0).a <= 0.1f)) {
|
||||
#ifndef TRANSLUCENT
|
||||
if (useDiscard() && (textureLod(blockModelAtlas, texPos, 0).a <= 0.1f)) {
|
||||
#else
|
||||
if (textureLod(blockModelAtlas, texPos, 0).a == 0.0f) {
|
||||
#endif
|
||||
//This is stupidly stupidly bad for divergence
|
||||
//TODO: FIXME, basicly what this do is sample the exact pixel (no lod) for discarding, this stops mipmapping fucking it over
|
||||
#ifndef DEBUG_RENDER
|
||||
|
||||
@@ -58,7 +58,8 @@ uint makeQuadFlags(uint faceData, uint modelId, ivec2 quadSize, const in BlockMo
|
||||
flags |= uint(any(greaterThan(quadSize, ivec2(1)))) & faceHasAlphaCuttoutOverride(faceData);
|
||||
}
|
||||
|
||||
flags |= uint(!modelHasMipmaps(model))<<1;//Not mipmaps
|
||||
//TODO: remove, there is no non mip code path anymore
|
||||
//flags |= uint(!modelHasMipmaps(model))<<1;//Not mipmaps
|
||||
|
||||
flags |= faceTintState(faceData)<<2;
|
||||
flags |= face<<4;//Face
|
||||
@@ -71,6 +72,11 @@ uint packVec4(vec4 vec) {
|
||||
return vec_.x|vec_.y|vec_.z|vec_.w;
|
||||
}
|
||||
|
||||
|
||||
#ifndef PATCHED_SHADER
|
||||
float computeDirectionalFaceTint(bool isShaded, uint face);
|
||||
#endif
|
||||
|
||||
uvec3 makeRemainingAttributes(const in BlockModel model, const in Quad quad, uint lodLevel, uint face) {
|
||||
uvec3 attributes = uvec3(0);
|
||||
|
||||
@@ -88,8 +94,10 @@ uvec3 makeRemainingAttributes(const in BlockModel model, const in Quad quad, uin
|
||||
attributes.y = tintColour;
|
||||
#else
|
||||
bool isTranslucent = modelIsTranslucent(model);
|
||||
bool hasAO = modelHasMipmaps(model);//TODO: replace with per face AO flag
|
||||
bool isShaded = hasAO;//TODO: make this a per face flag
|
||||
|
||||
//afak, these are the same variable in vanilla, (i.e. shaded == ao)
|
||||
bool isShaded = modelIsShaded(model);
|
||||
bool hasAO = isShaded;
|
||||
|
||||
vec4 tinting = getLighting(lighting);
|
||||
|
||||
@@ -202,4 +210,5 @@ float computeDirectionalFaceTint(bool isShaded, uint face) {
|
||||
}
|
||||
#endif
|
||||
return 1.0f;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user