Skip to content

Commit

Permalink
Indigo shade related fixes and other changes (#2898)
Browse files Browse the repository at this point in the history
* Apply disabled shade from vanilla quads directly to material

- Remove QuadViewImpl.shade

* Fix enhanced AO calculation and respect non-terrain culling state

- Fix AoCalculator using AO face data computed with a potentially different shade state
- Move non-cached computation code to separate method in AoCalculator
- Turn AoCalculator's brightnessFunc and aoFunc into abstract methods
- Do not check null check world in non-terrain AO calculation since it cannot be null
- Pass through lightFace and shade state as method arguments in AoCalculator methods to prevent additional lookups
- Do not check for the axis aligned flag in AbstractQuadRenderer.shadeFlatQuad
- Respect cull parameter passed to non-terrain rendering by merging TerrainBlockRenderInfo into BlockRenderInfo
- Use reusable search pos when calling Block.shouldDrawSide to prevent additional BlockPos allocation
- Change BlockRenderContext.render and TerrainRenderContext.tessellateBlock to return void since return value is no longer used
- Remove QuadViewImpl.vertexStart since it is unused

* Add suggestions

- Mark Direction parameter to BlockRenderInfo.shouldDrawFace as Nullable
- Reuse MaterialFinder in FrameBakedModel

(cherry picked from commit 3a95925af4ebaa352fcf631b9b3e6f99b14062b3)
  • Loading branch information
PepperCode1 authored and modmuss50 committed Feb 23, 2023
1 parent a383ab9 commit 81e8c57
Show file tree
Hide file tree
Showing 11 changed files with 246 additions and 283 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.BlockRenderView;
import net.minecraft.util.math.random.Random;
import net.minecraft.world.BlockRenderView;

import net.fabricmc.fabric.api.renderer.v1.Renderer;
import net.fabricmc.fabric.api.renderer.v1.RendererAccess;
import net.fabricmc.fabric.api.renderer.v1.material.BlendMode;
import net.fabricmc.fabric.api.renderer.v1.material.MaterialFinder;
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh;
import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel;
Expand All @@ -57,9 +57,10 @@ final class FrameBakedModel implements BakedModel, FabricBakedModel {
this.frameMesh = frameMesh;
this.frameSprite = frameSprite;

Renderer renderer = RendererAccess.INSTANCE.getRenderer();
this.translucentMaterial = renderer.materialFinder().blendMode(0, BlendMode.TRANSLUCENT).find();
this.translucentEmissiveMaterial = renderer.materialFinder().blendMode(0, BlendMode.TRANSLUCENT).emissive(0, true).find();
MaterialFinder finder = RendererAccess.INSTANCE.getRenderer().materialFinder();
this.translucentMaterial = finder.blendMode(0, BlendMode.TRANSLUCENT).find();
finder.clear();
this.translucentEmissiveMaterial = finder.blendMode(0, BlendMode.TRANSLUCENT).emissive(0, true).find();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ public static RenderMaterialImpl.Value byIndex(int index) {
return VALUES[index];
}

public static Value setDisableDiffuse(Value material, int textureIndex, boolean disable) {
if (material.disableDiffuse(textureIndex) != disable) {
return byIndex(disable ? (material.bits | DIFFUSE_FLAG) : (material.bits & ~DIFFUSE_FLAG));
}

return material;
}

protected int bits;

public BlendMode blendMode(int textureIndex) {
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
import net.fabricmc.fabric.impl.client.indigo.renderer.IndigoRenderer;
import net.fabricmc.fabric.impl.client.indigo.renderer.RenderMaterialImpl;
import net.fabricmc.fabric.impl.client.indigo.renderer.RenderMaterialImpl.Value;
import net.fabricmc.fabric.impl.client.indigo.renderer.helper.NormalHelper;
import net.fabricmc.fabric.impl.client.indigo.renderer.helper.TextureHelper;
Expand Down Expand Up @@ -116,9 +117,13 @@ public final MutableQuadViewImpl fromVanilla(BakedQuad quad, RenderMaterial mate
data[baseIndex + HEADER_BITS] = EncodingFormat.cullFace(0, cullFace);
nominalFace(quad.getFace());
colorIndex(quad.getColorIndex());

if (!quad.hasShade()) {
material = RenderMaterialImpl.setDisableDiffuse((Value) material, 0, true);
}

material(material);
tag(0);
shade(quad.hasShade());
isGeometryInvalid = true;
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import static net.fabricmc.fabric.impl.client.indigo.renderer.mesh.EncodingFormat.HEADER_BITS;
import static net.fabricmc.fabric.impl.client.indigo.renderer.mesh.EncodingFormat.HEADER_COLOR_INDEX;
import static net.fabricmc.fabric.impl.client.indigo.renderer.mesh.EncodingFormat.HEADER_STRIDE;
import static net.fabricmc.fabric.impl.client.indigo.renderer.mesh.EncodingFormat.HEADER_TAG;
import static net.fabricmc.fabric.impl.client.indigo.renderer.mesh.EncodingFormat.QUAD_STRIDE;
import static net.fabricmc.fabric.impl.client.indigo.renderer.mesh.EncodingFormat.VERTEX_COLOR;
Expand Down Expand Up @@ -52,7 +51,6 @@ public class QuadViewImpl implements QuadView {
/** True when geometry flags or light face may not match geometry. */
protected boolean isGeometryInvalid = true;
protected final Vector3f faceNormal = new Vector3f();
private boolean shade = true;

/** Size and where it comes from will vary in subtypes. But in all cases quad is fully encoded to array. */
protected int[] data;
Expand Down Expand Up @@ -268,15 +266,7 @@ public float spriteV(int vertexIndex, int spriteIndex) {
return Float.intBitsToFloat(data[baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_V]);
}

public int vertexStart() {
return baseIndex + HEADER_STRIDE;
}

public boolean hasShade() {
return shade && !material().disableDiffuse(0);
}

public void shade(boolean shade) {
this.shade = shade;
return !material().disableDiffuse(0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
import net.fabricmc.fabric.impl.client.indigo.renderer.RenderMaterialImpl;
import net.fabricmc.fabric.impl.client.indigo.renderer.aocalc.AoCalculator;
import net.fabricmc.fabric.impl.client.indigo.renderer.helper.ColorHelper;
import net.fabricmc.fabric.impl.client.indigo.renderer.helper.GeometryHelper;
import net.fabricmc.fabric.impl.client.indigo.renderer.mesh.MutableQuadViewImpl;

/**
Expand Down Expand Up @@ -235,9 +234,9 @@ int flatBrightness(MutableQuadViewImpl quad, BlockState blockState, BlockPos pos
* even for un-shaded quads. These are also applied with AO shading but that is done in AO calculator.
*/
private void shadeFlatQuad(MutableQuadViewImpl quad) {
if ((quad.geometryFlags() & GeometryHelper.AXIS_ALIGNED_FLAG) == 0 || quad.hasVertexNormals()) {
// Quads that aren't direction-aligned or that have vertex normals need to be shaded
// using interpolation - vanilla can't handle them. Generally only applies to modded models.
if (quad.hasVertexNormals()) {
// Quads that have vertex normals need to be shaded using interpolation - vanilla can't
// handle them. Generally only applies to modded models.
final float faceShade = blockInfo.blockView.getBrightness(quad.lightFace(), quad.hasShade());

for (int i = 0; i < 4; i++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import org.joml.Matrix4f;

import net.minecraft.block.BlockState;
import net.minecraft.client.render.LightmapTextureManager;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.WorldRenderer;
Expand All @@ -44,10 +43,20 @@
*/
public class BlockRenderContext extends AbstractRenderContext {
private final BlockRenderInfo blockInfo = new BlockRenderInfo();
private final AoCalculator aoCalc = new AoCalculator(blockInfo, this::brightness, this::aoLevel);

private final AoCalculator aoCalc = new AoCalculator(blockInfo) {
@Override
public int light(BlockPos pos, BlockState state) {
return WorldRenderer.getLightmapCoordinates(blockInfo.blockView, state, pos);
}

@Override
public float ao(BlockPos pos, BlockState state) {
return AoLuminanceFix.INSTANCE.apply(blockInfo.blockView, pos, state);
}
};

private VertexConsumer bufferBuilder;
private boolean didOutput = false;
// These are kept as fields to avoid the heap allocation for a supplier.
// BlockModelRenderer allows the caller to supply both the random object and seed.
private Random random;
Expand Down Expand Up @@ -95,35 +104,20 @@ protected int overlay() {
}
};

private int brightness(BlockPos pos, BlockState state) {
if (blockInfo.blockView == null) {
return LightmapTextureManager.MAX_LIGHT_COORDINATE;
}

return WorldRenderer.getLightmapCoordinates(blockInfo.blockView, state, pos);
}

private float aoLevel(BlockPos pos, BlockState state) {
final BlockRenderView blockView = blockInfo.blockView;
return blockView == null ? 1f : AoLuminanceFix.INSTANCE.apply(blockView, pos, state);
}

private VertexConsumer outputBuffer(RenderLayer renderLayer) {
didOutput = true;
return bufferBuilder;
}

public boolean render(BlockRenderView blockView, BakedModel model, BlockState state, BlockPos pos, MatrixStack matrixStack, VertexConsumer buffer, Random random, long seed, int overlay) {
public void render(BlockRenderView blockView, BakedModel model, BlockState state, BlockPos pos, MatrixStack matrixStack, VertexConsumer buffer, boolean cull, Random random, long seed, int overlay) {
this.bufferBuilder = buffer;
this.matrix = matrixStack.peek().getPositionMatrix();
this.normalMatrix = matrixStack.peek().getNormalMatrix();
this.random = random;
this.seed = seed;

this.overlay = overlay;
this.didOutput = false;
aoCalc.clear();
blockInfo.setBlockView(blockView);
blockInfo.prepareForWorld(blockView, cull);
blockInfo.prepareForBlock(state, pos, model.useAmbientOcclusion());

((FabricBakedModel) model).emitBlockQuads(blockView, state, pos, randomSupplier, this);
Expand All @@ -132,8 +126,6 @@ public boolean render(BlockRenderView blockView, BakedModel model, BlockState st
this.bufferBuilder = null;
this.random = null;
this.seed = seed;

return didOutput;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,18 @@

import java.util.function.Supplier;

import org.jetbrains.annotations.Nullable;

import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.color.block.BlockColors;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.RenderLayers;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.BlockRenderView;
import net.minecraft.util.math.random.Random;
import net.minecraft.world.BlockRenderView;

import net.fabricmc.fabric.api.renderer.v1.material.BlendMode;

Expand All @@ -39,6 +42,7 @@
*/
public class BlockRenderInfo {
private final BlockColors blockColorMap = MinecraftClient.getInstance().getBlockColors();
private final BlockPos.Mutable searchPos = new BlockPos.Mutable();
private final Random random = Random.create();
public BlockRenderView blockView;
public BlockPos blockPos;
Expand All @@ -47,6 +51,10 @@ public class BlockRenderInfo {
boolean defaultAo;
RenderLayer defaultLayer;

private boolean enableCulling;
private int cullCompletionFlags;
private int cullResultFlags;

public final Supplier<Random> randomSupplier = () -> {
final Random result = random;
long seed = this.seed;
Expand All @@ -60,18 +68,22 @@ public class BlockRenderInfo {
return result;
};

public void setBlockView(BlockRenderView blockView) {
public void prepareForWorld(BlockRenderView blockView, boolean enableCulling) {
this.blockView = blockView;
this.enableCulling = enableCulling;
}

public void prepareForBlock(BlockState blockState, BlockPos blockPos, boolean modelAO) {
this.blockPos = blockPos;
this.blockState = blockState;
// in the unlikely case seed actually matches this, we'll simply retrieve it more than one
// in the unlikely case seed actually matches this, we'll simply retrieve it more than once
seed = -1L;
defaultAo = modelAO && MinecraftClient.isAmbientOcclusionEnabled() && blockState.getLuminance() == 0;

defaultLayer = RenderLayers.getBlockLayer(blockState);

cullCompletionFlags = 0;
cullResultFlags = 0;
}

public void release() {
Expand All @@ -83,8 +95,25 @@ int blockColor(int colorIndex) {
return 0xFF000000 | blockColorMap.getColor(blockState, blockView, blockPos, colorIndex);
}

boolean shouldDrawFace(Direction face) {
return true;
boolean shouldDrawFace(@Nullable Direction face) {
if (face == null || !enableCulling) {
return true;
}

final int mask = 1 << face.getId();

if ((cullCompletionFlags & mask) == 0) {
cullCompletionFlags |= mask;

if (Block.shouldDrawSide(blockState, blockView, blockPos, face, searchPos.set(blockPos, face))) {
cullResultFlags |= mask;
return true;
} else {
return false;
}
} else {
return (cullResultFlags & mask) != 0;
}
}

RenderLayer effectiveRenderLayer(BlendMode blendMode) {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,19 @@
public class TerrainRenderContext extends AbstractRenderContext {
public static final ThreadLocal<TerrainRenderContext> POOL = ThreadLocal.withInitial(TerrainRenderContext::new);

private final TerrainBlockRenderInfo blockInfo = new TerrainBlockRenderInfo();
private final BlockRenderInfo blockInfo = new BlockRenderInfo();
private final ChunkRenderInfo chunkInfo = new ChunkRenderInfo();
private final AoCalculator aoCalc = new AoCalculator(blockInfo, chunkInfo::cachedBrightness, chunkInfo::cachedAoLevel);
private final AoCalculator aoCalc = new AoCalculator(blockInfo) {
@Override
public int light(BlockPos pos, BlockState state) {
return chunkInfo.cachedBrightness(pos, state);
}

@Override
public float ao(BlockPos pos, BlockState state) {
return chunkInfo.cachedAoLevel(pos, state);
}
};

private final AbstractMeshConsumer meshConsumer = new AbstractMeshConsumer(blockInfo, chunkInfo::getInitializedBuffer, aoCalc, this::transform) {
@Override
Expand Down Expand Up @@ -87,7 +97,7 @@ protected Matrix3f normalMatrix() {
};

public void prepare(ChunkRendererRegion blockView, BuiltChunk chunkRenderer, BuiltChunk.RebuildTask.RenderData renderData, BlockBufferBuilderStorage builders, Set<RenderLayer> initializedLayers) {
blockInfo.setBlockView(blockView);
blockInfo.prepareForWorld(blockView, true);
chunkInfo.prepare(blockView, chunkRenderer, renderData, builders, initializedLayers);
}

Expand All @@ -97,7 +107,7 @@ public void release() {
}

/** Called from chunk renderer hook. */
public boolean tessellateBlock(BlockState blockState, BlockPos blockPos, final BakedModel model, MatrixStack matrixStack) {
public void tessellateBlock(BlockState blockState, BlockPos blockPos, final BakedModel model, MatrixStack matrixStack) {
this.matrix = matrixStack.peek().getPositionMatrix();
this.normalMatrix = matrixStack.peek().getNormalMatrix();

Expand All @@ -111,9 +121,6 @@ public boolean tessellateBlock(BlockState blockState, BlockPos blockPos, final B
CrashReportSection.addBlockInfo(crashReportSection, chunkInfo.blockView, blockPos, blockState);
throw new CrashException(crashReport);
}

// false because we've already marked the chunk as populated - caller doesn't need to
return false;
}

@Override
Expand Down
Loading

0 comments on commit 81e8c57

Please sign in to comment.