LinearColorBlender breaks any case where a precise position is required in a BlockColorProvider.
devpelux opened this issue ยท 2 comments
Version information
mc1.19-0.4.2+build.16
Expected Behavior
I've implemented a new block that requires its precise position to get data to calculate the color.
It needs its precise actual position to get its associated block entity, then get an item stored inside the block entity.
ColorProviderRegistry.BLOCK.register(TunBlock::getContainedFluidColor, TUN);
public static int getContainedFluidColor(BlockState state, BlockRenderView view, BlockPos pos, int i) {
if (view.getBlockEntity(pos) instanceof TunBlockEntity tunEntity) {
if (tunEntity.hasContained()) {
return containable.get(tunEntity.getContained()).getColor(state, view, pos, i);
}
}
return -1;
}
Actual Behavior
With sodium installed, the color provider receives the neighbors block positions but not the actual block position.
This is caused by LinearColorBlender that requires the neighbors block colors to blend them.
The result, in by specific case, is that the color provider cannot get the block entity, and the result obtained is null, so it returns the empty color.
Calling trace
Reproduction Steps
Create a new block, then register a color provider for the block.
Start a debug session, with a breakpoint inside the method for getting the color.
Check the BlockPos parameter.
Check the actual block pos of the block (the block position, not the player position!) with F3 in the game.
Remember to add sodium into the mods folder into your run folder!
Example:
ColorProviderRegistry.BLOCK.register(MyBlock::getPartColor, MYBLOCK);
public static int getPartColor(BlockState state, BlockRenderView view, BlockPos pos, int i) {
if (view.getBlockEntity(pos) instanceof MyBlockEntity entity) { //<<< Place the breakpoint here.
//Calculating color from the block-entity...
}
return -1;
}
Java version
Java 17
CPU
Intel(R) Core(TM) i7-9750H
GPU
NVIDIA RTX 2080
Additional information
No response
Workaround
A workaround is to add a mixin to LinearColorBlender.getVertexColor()
, to get the color from the actual block position without blending.
Create a registry to register all the blocks needing the precise position:
/**
* All the registered blocks in this registry
* will ignore sodium color blending optimizations.<br>
* This is a singleton.
*/
public class IgnoreColorBlendingRegistry {
/** Gets the instance. */
private static final IgnoreColorBlendingRegistry INSTANCE = new IgnoreColorBlendingRegistry();
private final Set<Identifier> blockIds = new HashSet<>();
/** Initializes a new {@link IgnoreColorBlendingRegistry}. */
private IgnoreColorBlendingRegistry() {}
/** Registers a block into the registry. */
public static void register(Block block) {
INSTANCE.blockIds.add(Registry.BLOCK.getId(block));
}
/** Checks if a block is into the registry. */
public static boolean isRegistered(Block block) {
return INSTANCE.blockIds.contains(Registry.BLOCK.getId(block));
}
}
Then register the blocks that should avoid blending to work correctly:
IgnoreColorBlendingRegistry.register(MYBLOCK);
Lastly add a client-side mixin to LinearColorBlender.getVertexColor()
:
@Mixin(LinearColorBlender.class)
public abstract class LinearColorBlenderMixin {
@Shadow protected abstract <T> int getBlockColor(BlockRenderView world, T state, ColorSampler<T> sampler, int x, int y, int z, int colorIdx);
@Inject(method = "getVertexColor", at = @At("HEAD"), cancellable = true)
private <T> void injectGetVertexColor(BlockRenderView world, BlockPos origin, ModelQuadView quad, ColorSampler<T> sampler,
T state, int vertexIdx, CallbackInfoReturnable<Integer> cir) {
if (state instanceof BlockState blockState) {
if (IgnoreColorBlendingRegistry.isRegistered(blockState.getBlock())) {
int color = getBlockColor(world, state, sampler, origin.getX(), origin.getY(), origin.getZ(), quad.getColorIndex());
cir.setReturnValue(ColorARGB.toABGR(color));
}
}
}
}
This is for blocks, you can make a similar behaviour with fluids or other "state" types (for fluids, the state will be FluidState).
Closes because is a duplicate of #895