Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 30 additions & 7 deletions src/main/java/me/cortex/voxy/client/core/model/ModelFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import me.cortex.voxy.client.core.model.bakery.SoftwareModelTextureBakery;
import me.cortex.voxy.client.core.rendering.util.UploadStream;
import me.cortex.voxy.common.Logger;
import me.cortex.voxy.common.util.LumiseneUtil;
import me.cortex.voxy.common.util.MemoryBuffer;
import me.cortex.voxy.common.util.Pair;
import me.cortex.voxy.common.world.other.Mapper;
Expand Down Expand Up @@ -188,7 +189,7 @@ public boolean addEntry(int blockId) {

//Before we enqueue the baking of this blockstate, we must check if it has a fluid state associated with it
// if it does, we must ensure that it is (effectivly) baked BEFORE we bake this blockstate
boolean isFluid = blockState.getBlock() instanceof LiquidBlock;
boolean isFluid = isFluidBlockState(blockState);
if ((!isFluid) && (!blockState.getFluidState().isEmpty())) {
//Insert into the fluid LUT
var fluidState = blockState.getFluidState().createLegacyBlock();
Expand Down Expand Up @@ -359,7 +360,8 @@ private ModelBakeResultUpload processTextureBakeResult(int blockId, BlockState b

//TODO: add thing for `blockState.hasEmissiveLighting()` and `blockState.getLuminance()`

boolean isFluid = blockState.getBlock() instanceof LiquidBlock;
boolean isFluid = isFluidBlockState(blockState);
boolean isLumisene = LumiseneUtil.isLumisene(blockState);
int modelId = -1;


Expand All @@ -377,7 +379,7 @@ private ModelBakeResultUpload processTextureBakeResult(int blockId, BlockState b
}
}

var colourProvider = getColourProvider(blockState.getBlock());
var colourProvider = getColourProvider(blockState);

boolean isBiomeColourDependent = false;
if (colourProvider != null) {
Expand Down Expand Up @@ -479,7 +481,7 @@ private ModelBakeResultUpload processTextureBakeResult(int blockId, BlockState b
metadata |= layer == RenderType.translucent()?2:0;
metadata |= needsDoubleSidedQuads?4:0;
metadata |= ((!isFluid) && !blockState.getFluidState().isEmpty())?8:0;//Has a fluid state accosiacted with it and is not itself a fluid
metadata |= isFluid?16:0;//Is a fluid
metadata |= (isFluid && !isLumisene)?16:0;//Is a fluid

metadata |= cullsSame?32:0;

Expand All @@ -500,6 +502,13 @@ private ModelBakeResultUpload processTextureBakeResult(int blockId, BlockState b
fullyOpaque = false;
continue;
}
if (face >= Direction.NORTH.get3DDataValue() && LumiseneUtil.isThinLumisene(blockState)) {
metadata |= 0xFF;//Mark the face as non-existent
MemoryUtil.memPutInt(faceUploadPtr, -1);

fullyOpaque = false;
continue;
}
var faceSize = TextureUtils.computeBounds(textureData[face], checkMode);
int writeCount = TextureUtils.getWrittenPixelCount(textureData[face], checkMode);

Expand Down Expand Up @@ -707,7 +716,7 @@ private BiomeUploadResult addBiome0(int id, Biome biome) {
int i = 0;
long modelUpPtr = result.modelBiomeIndexPairs.address;
for (var entry : this.modelsRequiringBiomeColours) {
var colourProvider = getColourProvider(entry.right().getBlock());
var colourProvider = getColourProvider(entry.right());
if (colourProvider == null) {
throw new IllegalStateException();
}
Expand All @@ -726,10 +735,15 @@ private BiomeUploadResult addBiome0(int id, Biome biome) {
return result;
}

private static BlockColor getColourProvider(Block block) {
private static BlockColor getColourProvider(BlockState blockState) {
if (LumiseneUtil.isLumisene(blockState)) {
return null;
}

Block block = blockState.getBlock();
BlockState defaultState = block.defaultBlockState();
var blockColors = Minecraft.getInstance().getBlockColors();
if (block instanceof LiquidBlock) {
if (isFluidBlockState(blockState) || isFluidBlockState(defaultState)) {
return (state, world, pos, tintIndex) -> blockColors.getColor(state, world, pos, tintIndex);
}
int color;
Expand All @@ -744,6 +758,15 @@ private static BlockColor getColourProvider(Block block) {
return null;
}

public static boolean isFluidBlockState(BlockState state) {
if (state.getBlock() instanceof LiquidBlock) {
return true;
}

FluidState fluidState = state.getFluidState();
return !fluidState.isEmpty() && fluidState.createLegacyBlock().getBlock() == state.getBlock();
}

//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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
import com.mojang.blaze3d.vertex.VertexConsumer;

import me.cortex.voxy.client.core.model.ModelFactory;
import me.cortex.voxy.common.util.LumiseneUtil;
import me.cortex.voxy.common.util.UnsafeUtil;
import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandlerRegistry;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ItemBlockRenderTypes;
import net.minecraft.client.renderer.RenderType;
Expand All @@ -19,7 +21,6 @@
import net.minecraft.world.level.LightLayer;
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.RenderShape;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
Expand Down Expand Up @@ -143,7 +144,7 @@ public BlockEntity getBlockEntity(BlockPos pos) {

@Override
public BlockState getBlockState(BlockPos pos) {
if (shouldReturnAirForFluid(pos, face)) {
if (shouldReturnAirForFluid(pos, face) || shouldReturnAirAboveLumisene(state, pos)) {
return Blocks.AIR.defaultBlockState();
}

Expand All @@ -161,7 +162,7 @@ public BlockState getBlockState(BlockPos pos) {

@Override
public FluidState getFluidState(BlockPos pos) {
if (shouldReturnAirForFluid(pos, face)) {
if (shouldReturnAirForFluid(pos, face) || shouldReturnAirAboveLumisene(state, pos)) {
return Blocks.AIR.defaultBlockState().getFluidState();
}

Expand Down Expand Up @@ -193,7 +194,13 @@ public float getShade(Direction direction, boolean bl) {
} else {
this.opaqueVC.setDefaultMeta(this.opaqueVC.getDefaultMeta()&~1);//remove discard
}
Minecraft.getInstance().getBlockRenderer().renderLiquid(BlockPos.ZERO, getter, vc, state, state.getFluidState());
FluidState fluidState = state.getFluidState();
var handler = FluidRenderHandlerRegistry.INSTANCE.get(fluidState.getType());
if (handler != null) {
handler.renderFluid(BlockPos.ZERO, getter, vc, state, fluidState);
} else {
Minecraft.getInstance().getBlockRenderer().renderLiquid(BlockPos.ZERO, getter, vc, state, fluidState);
}
this.translucentVC.setDefaultMeta(0);//Reset default meta
this.opaqueVC.setDefaultMeta(0);//Reset default meta
}
Expand All @@ -204,6 +211,10 @@ private static boolean shouldReturnAirForFluid(BlockPos pos, int face) {
return dot >= 1;
}

private static boolean shouldReturnAirAboveLumisene(BlockState state, BlockPos pos) {
return pos.getY() > 0 && LumiseneUtil.isLumisene(state);
}

public void free() {
this.opaqueVC.free();
this.translucentVC.free();
Expand All @@ -219,13 +230,10 @@ public void free() {
public int renderToOutput(BlockState state, long outputBuffer) {
MemoryUtil.memSet(outputBuffer, 0, 16 * 16 * 8 * 6);

boolean isBlock = true;
if (state.getBlock() instanceof LiquidBlock) {
isBlock = false;
}
boolean isBlock = !ModelFactory.isFluidBlockState(state);

RenderType blockRenderLayer = null;
if (state.getBlock() instanceof LiquidBlock) {
if (!isBlock) {
blockRenderLayer = ItemBlockRenderTypes.getRenderLayer(state.getFluidState());
} else {
if (state.getBlock() instanceof LeavesBlock) {
Expand Down Expand Up @@ -268,8 +276,6 @@ public int renderToOutput(BlockState state, long outputBuffer) {
}
} else {// Is fluid, slow path :(

if (!(state.getBlock() instanceof LiquidBlock))
throw new IllegalStateException();
for (int i = 0; i < VIEWS.length; i++) {
this.opaqueVC.reset();
this.translucentVC.reset();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import me.cortex.voxy.client.core.model.ModelQueries;
import me.cortex.voxy.client.core.util.ScanMesher2D;
import me.cortex.voxy.common.Logger;
import me.cortex.voxy.common.util.LumiseneUtil;
import me.cortex.voxy.common.util.MemoryBuffer;
import me.cortex.voxy.common.util.UnsafeUtil;
import me.cortex.voxy.common.world.WorldEngine;
Expand Down Expand Up @@ -241,6 +242,9 @@ private int prepareSectionData(final long[] rawSectionData) {
//TODO: cache the results of this, then link it to `block` do same optimization as SaveLoadSystem3

long modelMetadata = this.modelMan.getModelMetadataFromClientId(modelId);
if (LumiseneUtil.isLumisene(this.world.getMapper(), block)) {
block = Mapper.withLight(block, 0xFF);
}

sectionData[i * 2] = packPartialQuadData(modelId, block, modelMetadata);
sectionData[i * 2 + 1] = modelMetadata;
Expand Down Expand Up @@ -1718,4 +1722,4 @@ public BuiltSection generateMesh(WorldSection section) {
public void free() {
this.quadBuffer.free();
}
}
}
54 changes: 54 additions & 0 deletions src/main/java/me/cortex/voxy/common/util/LumiseneUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package me.cortex.voxy.common.util;

import me.cortex.voxy.common.world.other.Mapper;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.FluidState;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public final class LumiseneUtil {
private static final float MIN_VISIBLE_WALL_HEIGHT = 1.0f / 16.0f;
private static final Map<BlockState, Boolean> STATE_CACHE = new ConcurrentHashMap<>();

private LumiseneUtil() {
}

public static boolean isLumisene(Mapper mapper, long mappingId) {
return !Mapper.isAir(mappingId) && isLumisene(mapper.getBlockStateFromBlockId(Mapper.getBlockId(mappingId)));
}

public static boolean isLumisene(BlockState state) {
return STATE_CACHE.computeIfAbsent(state, LumiseneUtil::computeIsLumisene);
}

private static boolean computeIsLumisene(BlockState state) {
ResourceLocation blockId = BuiltInRegistries.BLOCK.getKey(state.getBlock());
if (isLumiseneId(blockId)) {
return true;
}

FluidState fluidState = state.getFluidState();
return !fluidState.isEmpty() && isLumiseneId(BuiltInRegistries.FLUID.getKey(fluidState.getType()));
}

public static boolean isThinLumisene(BlockState state) {
if (!isLumisene(state)) {
return false;
}

FluidState fluidState = state.getFluidState();
if (fluidState.isEmpty()) {
return false;
}

float height = fluidState.getOwnHeight();
return height > 0.0f && height < MIN_VISIBLE_WALL_HEIGHT;
}

private static boolean isLumiseneId(ResourceLocation id) {
return id != null && "supplementaries".equals(id.getNamespace()) && id.getPath().contains("lumisene");
}
}
21 changes: 20 additions & 1 deletion src/main/java/me/cortex/voxy/common/world/other/Mipper.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package me.cortex.voxy.common.world.other;

import me.cortex.voxy.common.util.LumiseneUtil;

import static me.cortex.voxy.common.world.other.Mapper.withLight;

//Mipper for data
Expand Down Expand Up @@ -57,8 +59,20 @@ public static long mip(long I000, long I100, long I001, long I101,
max = Math.max((mapper.getBlockStateOpacity(I000)<<4), max);
}

long lumisene = firstLumisene(mapper, I111);
if (Mapper.isAir(lumisene)) lumisene = firstLumisene(mapper, I110);
if (Mapper.isAir(lumisene)) lumisene = firstLumisene(mapper, I011);
if (Mapper.isAir(lumisene)) lumisene = firstLumisene(mapper, I010);
if (Mapper.isAir(lumisene)) lumisene = firstLumisene(mapper, I101);
if (Mapper.isAir(lumisene)) lumisene = firstLumisene(mapper, I100);
if (Mapper.isAir(lumisene)) lumisene = firstLumisene(mapper, I001);
if (Mapper.isAir(lumisene)) lumisene = firstLumisene(mapper, I000);
if (!Mapper.isAir(lumisene)) {
return withLight(lumisene, 0xFF);
}

if (max != -1) {
return switch (max&0b111) {
long result = switch (max&0b111) {
case 0 -> I000;
case 1 -> I001;
case 2 -> I010;
Expand All @@ -69,6 +83,7 @@ public static long mip(long I000, long I100, long I001, long I101,
case 7 -> I111;
default -> throw new IllegalStateException("Unexpected value: " + (max&0b111));
};
return LumiseneUtil.isLumisene(mapper, result) ? withLight(result, 0xFF) : result;
} else {
int blockLight = (Mapper.getLightId(I000) & 0xF0) + (Mapper.getLightId(I001) & 0xF0) + (Mapper.getLightId(I010) & 0xF0) + (Mapper.getLightId(I011) & 0xF0) +
(Mapper.getLightId(I100) & 0xF0) + (Mapper.getLightId(I101) & 0xF0) + (Mapper.getLightId(I110) & 0xF0) + (Mapper.getLightId(I111) & 0xF0);
Expand All @@ -80,4 +95,8 @@ public static long mip(long I000, long I100, long I001, long I101,
return withLight(I111, (blockLight << 4) | skyLight);
}
}

private static long firstLumisene(Mapper mapper, long id) {
return LumiseneUtil.isLumisene(mapper, id) ? id : 0;
}
}
6 changes: 4 additions & 2 deletions src/main/resources/assets/voxy/shaders/lod/quad_util.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@ uvec3 makeRemainingAttributes(const in BlockModel model, const in Quad quad, uin
}

uint addin = 0;
if (!isTranslucent) {
if (isTranslucent) {
tinting.w = 1.0;
} else {
tinting.w = 0.0;
//Encode the face, the lod level and
uint encodedData = 0;
Expand Down Expand Up @@ -186,4 +188,4 @@ float computeDirectionalFaceTint(bool isShaded, uint face) {
return NO_SHADE_FACE_TINT;
}
}
#endif
#endif
Loading