From c705a49cc5703f4e9e476e1165cc6dfcb812cd33 Mon Sep 17 00:00:00 2001
From: PepperCode1 <44146161+PepperCode1@users.noreply.github.com>
Date: Sun, 4 Aug 2024 06:52:02 -0600
Subject: [PATCH] Add `ShadeMode` to FRAPI (#3937)
* Add ShadeMode to the API
- Update material documentation
- Use ShadeMode in VanillaModelEncoder
* Add ShadeMode support to Indigo
- Rewrite header packing constants in EncodingFormat to match material packing constants
- Pass buffer Function to TerrainRenderContext instead of allocators and buffer map
- Restore functionality of ChunkRenderInfo#release
- Set captured terrain context to null after releasing it
- Bump mixin compatibility level to Java 21
- Remove unused AWs
* Add test for ShadeMode
- Fix RiverstoneUnbakedModel not calling setParents on models that it will bake
* Clarify documentation of inverted material properties
---
.../api/renderer/v1/material/BlendMode.java | 6 +-
.../renderer/v1/material/MaterialFinder.java | 59 ++++++++++++----
.../renderer/v1/material/MaterialView.java | 9 +++
.../api/renderer/v1/material/ShadeMode.java | 36 ++++++++++
.../renderer/v1/model/FabricBakedModel.java | 2 +-
.../api/renderer/v1/model/ModelHelper.java | 4 +-
.../impl/renderer/VanillaModelEncoder.java | 13 ++--
.../fabric-renderer-api-v1.mixins.json | 2 +-
.../test/renderer/OctagonalColumnBlock.java | 36 ++++++++++
.../fabric/test/renderer/Registration.java | 2 +-
.../renderer/client/ModelResolverImpl.java | 11 ++-
.../client/OctagonalColumnUnbakedModel.java | 11 ++-
.../client/RiverstoneUnbakedModel.java | 2 +
.../blockstates/octagonal_column.json | 3 +-
.../indigo/renderer/IndigoRenderer.java | 3 +-
.../indigo/renderer/aocalc/AoCalculator.java | 45 ++++--------
.../renderer/material/MaterialFinderImpl.java | 9 +++
.../renderer/material/MaterialViewImpl.java | 23 +++++--
.../indigo/renderer/mesh/EncodingFormat.java | 69 +++++++++++--------
.../render/AbstractBlockRenderContext.java | 36 +++-------
.../renderer/render/ChunkRenderInfo.java | 34 +++------
.../renderer/render/TerrainRenderContext.java | 9 ++-
.../indigo/renderer/BakedModelMixin.java | 43 ------------
.../indigo/renderer/SectionBuilderMixin.java | 31 ++++-----
.../fabric-renderer-indigo.accesswidener | 4 --
.../fabric-renderer-indigo.mixins.json | 3 +-
26 files changed, 288 insertions(+), 217 deletions(-)
create mode 100644 fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/api/renderer/v1/material/ShadeMode.java
create mode 100644 fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/OctagonalColumnBlock.java
delete mode 100644 fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/mixin/client/indigo/renderer/BakedModelMixin.java
diff --git a/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/api/renderer/v1/material/BlendMode.java b/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/api/renderer/v1/material/BlendMode.java
index 4ee361c04..feab8ae7f 100644
--- a/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/api/renderer/v1/material/BlendMode.java
+++ b/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/api/renderer/v1/material/BlendMode.java
@@ -17,13 +17,15 @@
package net.fabricmc.fabric.api.renderer.v1.material;
import net.minecraft.client.render.RenderLayer;
+import net.minecraft.client.render.RenderLayers;
/**
- * Defines how sprite pixels will be blended with the scene.
+ * Controls how sprite pixels will be blended with the scene.
*/
public enum BlendMode {
/**
- * Emulate blending behavior of {@code BlockRenderLayer} associated with the block.
+ * Emulate blending behavior of the {@link RenderLayer} associated with the block state through
+ * {@link RenderLayers}.
*/
DEFAULT(null),
diff --git a/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/api/renderer/v1/material/MaterialFinder.java b/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/api/renderer/v1/material/MaterialFinder.java
index 25c157ae6..636bd5583 100644
--- a/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/api/renderer/v1/material/MaterialFinder.java
+++ b/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/api/renderer/v1/material/MaterialFinder.java
@@ -17,6 +17,7 @@
package net.fabricmc.fabric.api.renderer.v1.material;
import net.minecraft.block.BlockState;
+import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.item.ItemStack;
@@ -34,33 +35,42 @@ import net.fabricmc.fabric.api.util.TriState;
*/
public interface MaterialFinder extends MaterialView {
/**
- * Defines how sprite pixels will be blended with the scene.
+ * Controls how sprite pixels should be blended with the scene.
*
- *
See {@link BlendMode} for more information.
+ *
The default value is {@link BlendMode#DEFAULT}.
+ *
+ * @see BlendMode
*/
MaterialFinder blendMode(BlendMode blendMode);
/**
- * Vertex color(s) will be modified for quad color index unless disabled.
+ * Controls whether vertex colors should be modified for quad coloring. This property
+ * is inverted, so a value of {@code false} means that quad coloring will be applied.
+ *
+ *
The default value is {@code false}.
*/
MaterialFinder disableColorIndex(boolean disable);
/**
* When true, sprite texture and color will be rendered at full brightness.
* Lightmap values provided via {@link QuadEmitter#lightmap(int)} will be ignored.
- * False by default
*
- *
This is the preferred method for emissive lighting effects. Some renderers
- * with advanced lighting models may not use block lightmaps and this method will
+ *
This is the preferred method for emissive lighting effects. Some renderers
+ * with advanced lighting pipelines may not use block lightmaps and this method will
* allow per-sprite emissive lighting in future extensions that support overlay sprites.
*
*
Note that color will still be modified by diffuse shading and ambient occlusion,
* unless disabled via {@link #disableDiffuse(boolean)} and {@link #ambientOcclusion(TriState)}.
+ *
+ *
The default value is {@code false}.
*/
MaterialFinder emissive(boolean isEmissive);
/**
- * Vertex color(s) will be modified for diffuse shading unless disabled.
+ * Controls whether vertex colors should be modified for diffuse shading. This property
+ * is inverted, so a value of {@code false} means that diffuse shading will be applied.
+ *
+ *
The default value is {@code false}.
*
*
This property is guaranteed to be respected in block contexts. Some renderers may also respect it in item
* contexts, but this is not guaranteed.
@@ -68,11 +78,15 @@ public interface MaterialFinder extends MaterialView {
MaterialFinder disableDiffuse(boolean disable);
/**
- * Controls whether vertex color(s) will be modified for ambient occlusion.
+ * Controls whether vertex colors should be modified for ambient occlusion.
*
- *
By default, ambient occlusion will be used if {@link BakedModel#useAmbientOcclusion() the model uses ambient occlusion}
- * and the block state has {@link BlockState#getLuminance() a luminance} of 0.
- * Set to {@link TriState#TRUE} or {@link TriState#FALSE} to override this behavior.
+ *
If set to {@link TriState#DEFAULT}, ambient occlusion will be used if
+ * {@linkplain BakedModel#useAmbientOcclusion() the model uses ambient occlusion} and the block state has
+ * {@linkplain BlockState#getLuminance() a luminance} of 0. Set to {@link TriState#TRUE} or {@link TriState#FALSE}
+ * to override this behavior. {@link TriState#TRUE} will not have an effect if
+ * {@linkplain MinecraftClient#isAmbientOcclusionEnabled() ambient occlusion is disabled globally}.
+ *
+ *
The default value is {@link TriState#DEFAULT}.
*
*
This property is respected only in block contexts. It will not have an effect in other contexts.
*/
@@ -81,14 +95,33 @@ public interface MaterialFinder extends MaterialView {
/**
* Controls whether glint should be applied.
*
- *
By default, glint will be applied in item contexts if {@link ItemStack#hasGlint() the item stack has glint}.
- * Set to {@link TriState#TRUE} or {@link TriState#FALSE} to override this behavior.
+ *
If set to {@link TriState#DEFAULT}, glint will be applied in item contexts if
+ * {@linkplain ItemStack#hasGlint() the item stack has glint}. Set to {@link TriState#TRUE} or
+ * {@link TriState#FALSE} to override this behavior.
+ *
+ *
The default value is {@link TriState#DEFAULT}.
*
*
This property is guaranteed to be respected in item contexts. Some renderers may also respect it in block
* contexts, but this is not guaranteed.
*/
MaterialFinder glint(TriState mode);
+ /**
+ * A hint to the renderer about how the quad is intended to be shaded, for example through ambient occlusion and
+ * diffuse shading. The renderer is free to ignore this hint.
+ *
+ *
The default value is {@link ShadeMode#ENHANCED}.
+ *
+ *
This property is respected only in block contexts. It will not have an effect in other contexts.
+ *
+ * @see ShadeMode
+ *
+ * @apiNote The default implementation will be removed in the next breaking release.
+ */
+ default MaterialFinder shadeMode(ShadeMode mode) {
+ return this;
+ }
+
/**
* Copies all properties from the given {@link MaterialView} to this material finder.
*/
diff --git a/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/api/renderer/v1/material/MaterialView.java b/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/api/renderer/v1/material/MaterialView.java
index 31bb0c8b2..36b90ac32 100644
--- a/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/api/renderer/v1/material/MaterialView.java
+++ b/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/api/renderer/v1/material/MaterialView.java
@@ -54,4 +54,13 @@ public interface MaterialView {
* @see MaterialFinder#glint(TriState)
*/
TriState glint();
+
+ /**
+ * @see MaterialFinder#shadeMode(ShadeMode)
+ *
+ * @apiNote The default implementation will be removed in the next breaking release.
+ */
+ default ShadeMode shadeMode() {
+ return ShadeMode.ENHANCED;
+ }
}
diff --git a/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/api/renderer/v1/material/ShadeMode.java b/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/api/renderer/v1/material/ShadeMode.java
new file mode 100644
index 000000000..e83c91d88
--- /dev/null
+++ b/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/api/renderer/v1/material/ShadeMode.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016, 2017, 2018, 2019 FabricMC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.fabricmc.fabric.api.renderer.v1.material;
+
+/**
+ * A hint to the renderer about how the quad is intended to be shaded, for example through ambient occlusion and
+ * diffuse shading. The renderer is free to ignore this hint.
+ */
+public enum ShadeMode {
+ /**
+ * Conveys the intent that shading should be generally consistent, lack edge cases, and produce visually pleasing
+ * results, even for quads that are not used by vanilla or are not possible to create through resource packs in
+ * vanilla.
+ */
+ ENHANCED,
+
+ /**
+ * Conveys the intent that shading should mimic vanilla results, potentially to preserve certain visuals produced
+ * by resource packs that modify models.
+ */
+ VANILLA;
+}
diff --git a/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/api/renderer/v1/model/FabricBakedModel.java b/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/api/renderer/v1/model/FabricBakedModel.java
index 40b497d72..0015121b1 100644
--- a/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/api/renderer/v1/model/FabricBakedModel.java
+++ b/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/api/renderer/v1/model/FabricBakedModel.java
@@ -94,7 +94,7 @@ public interface FabricBakedModel {
* @param context Accepts model output.
*/
default void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context) {
- VanillaModelEncoder.emitBlockQuads((BakedModel) this, state, randomSupplier, context, context.getEmitter());
+ VanillaModelEncoder.emitBlockQuads((BakedModel) this, state, randomSupplier, context);
}
/**
diff --git a/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/api/renderer/v1/model/ModelHelper.java b/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/api/renderer/v1/model/ModelHelper.java
index 5d58406c2..acd6589d1 100644
--- a/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/api/renderer/v1/model/ModelHelper.java
+++ b/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/api/renderer/v1/model/ModelHelper.java
@@ -20,6 +20,7 @@ import java.util.Arrays;
import java.util.List;
import com.google.common.collect.ImmutableList;
+import org.jetbrains.annotations.Nullable;
import org.joml.Vector3f;
import net.minecraft.client.MinecraftClient;
@@ -46,7 +47,7 @@ public final class ModelHelper {
* Null is returned as {@link #NULL_FACE_ID}.
* Use {@link #faceFromIndex(int)} to retrieve encoded face.
*/
- public static int toFaceIndex(Direction face) {
+ public static int toFaceIndex(@Nullable Direction face) {
return face == null ? NULL_FACE_ID : face.getId();
}
@@ -57,6 +58,7 @@ public final class ModelHelper {
* optionally including the null face. (Use < or <= {@link #NULL_FACE_ID}
* to exclude or include the null value, respectively.)
*/
+ @Nullable
public static Direction faceFromIndex(int faceIndex) {
return FACES[faceIndex];
}
diff --git a/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/impl/renderer/VanillaModelEncoder.java b/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/impl/renderer/VanillaModelEncoder.java
index af2a817ca..73cf27200 100644
--- a/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/impl/renderer/VanillaModelEncoder.java
+++ b/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/impl/renderer/VanillaModelEncoder.java
@@ -30,6 +30,7 @@ import net.minecraft.util.math.random.Random;
import net.fabricmc.fabric.api.renderer.v1.Renderer;
import net.fabricmc.fabric.api.renderer.v1.RendererAccess;
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
+import net.fabricmc.fabric.api.renderer.v1.material.ShadeMode;
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
import net.fabricmc.fabric.api.renderer.v1.model.ModelHelper;
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
@@ -41,12 +42,12 @@ import net.fabricmc.fabric.api.util.TriState;
*/
public class VanillaModelEncoder {
private static final Renderer RENDERER = RendererAccess.INSTANCE.getRenderer();
- private static final RenderMaterial MATERIAL_STANDARD = RENDERER.materialFinder().find();
- private static final RenderMaterial MATERIAL_NO_AO = RENDERER.materialFinder().ambientOcclusion(TriState.FALSE).find();
+ private static final RenderMaterial STANDARD_MATERIAL = RENDERER.materialFinder().shadeMode(ShadeMode.VANILLA).find();
+ private static final RenderMaterial NO_AO_MATERIAL = RENDERER.materialFinder().shadeMode(ShadeMode.VANILLA).ambientOcclusion(TriState.FALSE).find();
- // Separate QuadEmitter parameter so that Indigo can pass its own emitter that handles vanilla quads differently.
- public static void emitBlockQuads(BakedModel model, @Nullable BlockState state, Supplier randomSupplier, RenderContext context, QuadEmitter emitter) {
- final RenderMaterial defaultMaterial = model.useAmbientOcclusion() ? MATERIAL_STANDARD : MATERIAL_NO_AO;
+ public static void emitBlockQuads(BakedModel model, @Nullable BlockState state, Supplier randomSupplier, RenderContext context) {
+ QuadEmitter emitter = context.getEmitter();
+ final RenderMaterial defaultMaterial = model.useAmbientOcclusion() ? STANDARD_MATERIAL : NO_AO_MATERIAL;
for (int i = 0; i <= ModelHelper.NULL_FACE_ID; i++) {
final Direction cullFace = ModelHelper.faceFromIndex(i);
@@ -77,7 +78,7 @@ public class VanillaModelEncoder {
for (int j = 0; j < count; j++) {
final BakedQuad q = quads.get(j);
- emitter.fromVanilla(q, MATERIAL_STANDARD, cullFace);
+ emitter.fromVanilla(q, STANDARD_MATERIAL, cullFace);
emitter.emit();
}
}
diff --git a/fabric-renderer-api-v1/src/client/resources/fabric-renderer-api-v1.mixins.json b/fabric-renderer-api-v1/src/client/resources/fabric-renderer-api-v1.mixins.json
index 76bb95700..ab5ea7a97 100644
--- a/fabric-renderer-api-v1/src/client/resources/fabric-renderer-api-v1.mixins.json
+++ b/fabric-renderer-api-v1/src/client/resources/fabric-renderer-api-v1.mixins.json
@@ -1,7 +1,7 @@
{
"required": true,
"package": "net.fabricmc.fabric.mixin.renderer",
- "compatibilityLevel": "JAVA_17",
+ "compatibilityLevel": "JAVA_21",
"client": [
"client.BakedModelMixin",
"client.MultipartBakedModelMixin",
diff --git a/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/OctagonalColumnBlock.java b/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/OctagonalColumnBlock.java
new file mode 100644
index 000000000..5a3615bba
--- /dev/null
+++ b/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/OctagonalColumnBlock.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016, 2017, 2018, 2019 FabricMC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.fabricmc.fabric.test.renderer;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.state.StateManager;
+import net.minecraft.state.property.BooleanProperty;
+
+public class OctagonalColumnBlock extends Block {
+ public static final BooleanProperty VANILLA_SHADE_MODE = BooleanProperty.of("vanilla_shade_mode");
+
+ public OctagonalColumnBlock(Settings settings) {
+ super(settings);
+ setDefaultState(getDefaultState().with(VANILLA_SHADE_MODE, false));
+ }
+
+ @Override
+ protected void appendProperties(StateManager.Builder builder) {
+ builder.add(VANILLA_SHADE_MODE);
+ }
+}
diff --git a/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/Registration.java b/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/Registration.java
index 9463c25af..7778d2b17 100644
--- a/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/Registration.java
+++ b/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/Registration.java
@@ -32,7 +32,7 @@ public final class Registration {
public static final FrameBlock FRAME_MULTIPART_BLOCK = register("frame_multipart", new FrameBlock(AbstractBlock.Settings.copy(Blocks.IRON_BLOCK).nonOpaque()));
public static final FrameBlock FRAME_VARIANT_BLOCK = register("frame_variant", new FrameBlock(AbstractBlock.Settings.copy(Blocks.IRON_BLOCK).nonOpaque()));
public static final Block PILLAR_BLOCK = register("pillar", new Block(AbstractBlock.Settings.create()));
- public static final Block OCTAGONAL_COLUMN_BLOCK = register("octagonal_column", new Block(AbstractBlock.Settings.create().nonOpaque().strength(1.8F)));
+ public static final Block OCTAGONAL_COLUMN_BLOCK = register("octagonal_column", new OctagonalColumnBlock(AbstractBlock.Settings.create().nonOpaque().strength(1.8F)));
public static final Block RIVERSTONE_BLOCK = register("riverstone", new Block(AbstractBlock.Settings.copy(Blocks.STONE)));
public static final FrameBlock[] FRAME_BLOCKS = new FrameBlock[] {
diff --git a/fabric-renderer-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/renderer/client/ModelResolverImpl.java b/fabric-renderer-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/renderer/client/ModelResolverImpl.java
index 6cb8950f2..625d0b96f 100644
--- a/fabric-renderer-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/renderer/client/ModelResolverImpl.java
+++ b/fabric-renderer-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/renderer/client/ModelResolverImpl.java
@@ -24,6 +24,7 @@ import net.minecraft.client.render.model.UnbakedModel;
import net.minecraft.util.Identifier;
import net.fabricmc.fabric.api.client.model.loading.v1.ModelResolver;
+import net.fabricmc.fabric.api.renderer.v1.material.ShadeMode;
import net.fabricmc.fabric.test.renderer.RendererTest;
public class ModelResolverImpl implements ModelResolver {
@@ -44,6 +45,10 @@ public class ModelResolverImpl implements ModelResolver {
RendererTest.id("item/octagonal_column")
);
+ private static final Set OCTAGONAL_COLUMN_VANILLA_MODEL_LOCATIONS = Set.of(
+ RendererTest.id("block/octagonal_column_vanilla")
+ );
+
private static final Set RIVERSTONE_MODEL_LOCATIONS = Set.of(
RendererTest.id("block/riverstone"),
RendererTest.id("item/riverstone")
@@ -63,7 +68,11 @@ public class ModelResolverImpl implements ModelResolver {
}
if (OCTAGONAL_COLUMN_MODEL_LOCATIONS.contains(id)) {
- return new OctagonalColumnUnbakedModel();
+ return new OctagonalColumnUnbakedModel(ShadeMode.ENHANCED);
+ }
+
+ if (OCTAGONAL_COLUMN_VANILLA_MODEL_LOCATIONS.contains(id)) {
+ return new OctagonalColumnUnbakedModel(ShadeMode.VANILLA);
}
if (RIVERSTONE_MODEL_LOCATIONS.contains(id)) {
diff --git a/fabric-renderer-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/renderer/client/OctagonalColumnUnbakedModel.java b/fabric-renderer-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/renderer/client/OctagonalColumnUnbakedModel.java
index 8cc487930..10c4f81dd 100644
--- a/fabric-renderer-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/renderer/client/OctagonalColumnUnbakedModel.java
+++ b/fabric-renderer-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/renderer/client/OctagonalColumnUnbakedModel.java
@@ -36,6 +36,7 @@ import net.fabricmc.fabric.api.renderer.v1.Renderer;
import net.fabricmc.fabric.api.renderer.v1.RendererAccess;
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.material.ShadeMode;
import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder;
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
@@ -49,6 +50,12 @@ public class OctagonalColumnUnbakedModel implements UnbakedModel {
private static final float A = (float) (1 - Math.sqrt(2) / 2);
private static final float B = (float) (Math.sqrt(2) / 2);
+ private final ShadeMode shadeMode;
+
+ public OctagonalColumnUnbakedModel(ShadeMode shadeMode) {
+ this.shadeMode = shadeMode;
+ }
+
@Override
public Collection getModelDependencies() {
return Collections.emptySet();
@@ -58,8 +65,8 @@ public class OctagonalColumnUnbakedModel implements UnbakedModel {
public void setParents(Function modelLoader) {
}
- @Nullable
@Override
+ @Nullable
public BakedModel bake(Baker baker, Function textureGetter, ModelBakeSettings rotationContainer) {
if (!RendererAccess.INSTANCE.hasRenderer()) {
return null;
@@ -69,7 +76,7 @@ public class OctagonalColumnUnbakedModel implements UnbakedModel {
Renderer renderer = RendererAccess.INSTANCE.getRenderer();
MaterialFinder finder = renderer.materialFinder();
- RenderMaterial glintMaterial = finder.glint(TriState.TRUE).find();
+ RenderMaterial glintMaterial = finder.glint(TriState.TRUE).shadeMode(shadeMode).find();
MeshBuilder builder = renderer.meshBuilder();
QuadEmitter emitter = builder.getEmitter();
diff --git a/fabric-renderer-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/renderer/client/RiverstoneUnbakedModel.java b/fabric-renderer-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/renderer/client/RiverstoneUnbakedModel.java
index 26c0d9324..30a291e08 100644
--- a/fabric-renderer-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/renderer/client/RiverstoneUnbakedModel.java
+++ b/fabric-renderer-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/renderer/client/RiverstoneUnbakedModel.java
@@ -41,6 +41,8 @@ public class RiverstoneUnbakedModel implements UnbakedModel {
@Override
public void setParents(Function modelLoader) {
+ modelLoader.apply(STONE_MODEL_ID).setParents(modelLoader);
+ modelLoader.apply(GOLD_BLOCK_MODEL_ID).setParents(modelLoader);
}
@Nullable
diff --git a/fabric-renderer-api-v1/src/testmodClient/resources/assets/fabric-renderer-api-v1-testmod/blockstates/octagonal_column.json b/fabric-renderer-api-v1/src/testmodClient/resources/assets/fabric-renderer-api-v1-testmod/blockstates/octagonal_column.json
index f62ea8ad6..064068a7b 100644
--- a/fabric-renderer-api-v1/src/testmodClient/resources/assets/fabric-renderer-api-v1-testmod/blockstates/octagonal_column.json
+++ b/fabric-renderer-api-v1/src/testmodClient/resources/assets/fabric-renderer-api-v1-testmod/blockstates/octagonal_column.json
@@ -1,5 +1,6 @@
{
"variants": {
- "": { "model": "fabric-renderer-api-v1-testmod:block/octagonal_column" }
+ "vanilla_shade_mode=false": { "model": "fabric-renderer-api-v1-testmod:block/octagonal_column" },
+ "vanilla_shade_mode=true": { "model": "fabric-renderer-api-v1-testmod:block/octagonal_column_vanilla" }
}
}
diff --git a/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/IndigoRenderer.java b/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/IndigoRenderer.java
index d1eb246bc..b29945548 100644
--- a/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/IndigoRenderer.java
+++ b/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/IndigoRenderer.java
@@ -25,6 +25,7 @@ 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.MeshBuilder;
import net.fabricmc.fabric.impl.client.indigo.renderer.material.MaterialFinderImpl;
+import net.fabricmc.fabric.impl.client.indigo.renderer.material.RenderMaterialImpl;
import net.fabricmc.fabric.impl.client.indigo.renderer.mesh.MeshBuilderImpl;
/**
@@ -64,7 +65,7 @@ public class IndigoRenderer implements Renderer {
if (materialMap.containsKey(id)) return false;
// cast to prevent acceptance of impostor implementations
- materialMap.put(id, material);
+ materialMap.put(id, (RenderMaterialImpl) material);
return true;
}
}
diff --git a/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/aocalc/AoCalculator.java b/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/aocalc/AoCalculator.java
index 2481a3a8a..bc37983e9 100644
--- a/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/aocalc/AoCalculator.java
+++ b/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/aocalc/AoCalculator.java
@@ -45,7 +45,6 @@ import net.minecraft.world.LightType;
import net.fabricmc.fabric.impl.client.indigo.Indigo;
import net.fabricmc.fabric.impl.client.indigo.renderer.aocalc.AoFace.WeightFunction;
import net.fabricmc.fabric.impl.client.indigo.renderer.mesh.EncodingFormat;
-import net.fabricmc.fabric.impl.client.indigo.renderer.mesh.MutableQuadViewImpl;
import net.fabricmc.fabric.impl.client.indigo.renderer.mesh.QuadViewImpl;
import net.fabricmc.fabric.impl.client.indigo.renderer.render.BlockRenderInfo;
@@ -105,41 +104,23 @@ public abstract class AoCalculator {
completionFlags = 0;
}
- public void compute(MutableQuadViewImpl quad, boolean isVanilla) {
+ public void compute(QuadViewImpl quad, boolean vanillaShade) {
final AoConfig config = Indigo.AMBIENT_OCCLUSION_MODE;
- final boolean shouldCompare;
switch (config) {
- case VANILLA:
- calcVanilla(quad);
-
- // no point in comparing vanilla with itself
- shouldCompare = false;
- break;
-
- case EMULATE:
- calcFastVanilla(quad);
- shouldCompare = Indigo.DEBUG_COMPARE_LIGHTING && isVanilla;
- break;
-
- case HYBRID:
- default:
- if (isVanilla) {
- shouldCompare = Indigo.DEBUG_COMPARE_LIGHTING;
+ case VANILLA -> calcVanilla(quad);
+ case EMULATE -> calcFastVanilla(quad);
+ case HYBRID -> {
+ if (vanillaShade) {
calcFastVanilla(quad);
} else {
- shouldCompare = false;
calcEnhanced(quad);
}
-
- break;
-
- case ENHANCED:
- shouldCompare = false;
- calcEnhanced(quad);
+ }
+ case ENHANCED -> calcEnhanced(quad);
}
- if (shouldCompare) {
+ if (Indigo.DEBUG_COMPARE_LIGHTING && vanillaShade && (config == AoConfig.EMULATE || config == AoConfig.HYBRID)) {
float[] vanillaAo = new float[4];
int[] vanillaLight = new int[4];
calcVanilla(quad, vanillaAo, vanillaLight);
@@ -158,7 +139,7 @@ public abstract class AoCalculator {
}
}
- private void calcVanilla(MutableQuadViewImpl quad) {
+ private void calcVanilla(QuadViewImpl quad) {
calcVanilla(quad, ao, light);
}
@@ -169,7 +150,7 @@ public abstract class AoCalculator {
private final BitSet vanillaAoControlBits = new BitSet(3);
private final int[] vertexData = new int[EncodingFormat.QUAD_STRIDE];
- private void calcVanilla(MutableQuadViewImpl quad, float[] aoDest, int[] lightDest) {
+ private void calcVanilla(QuadViewImpl quad, float[] aoDest, int[] lightDest) {
vanillaAoControlBits.clear();
final Direction lightFace = quad.lightFace();
quad.toVanilla(vertexData, 0);
@@ -181,7 +162,7 @@ public abstract class AoCalculator {
System.arraycopy(vanillaCalc.light, 0, lightDest, 0, 4);
}
- private void calcFastVanilla(MutableQuadViewImpl quad) {
+ private void calcFastVanilla(QuadViewImpl quad) {
int flags = quad.geometryFlags();
// force to block face if shape is full cube - matches vanilla logic
@@ -196,7 +177,7 @@ public abstract class AoCalculator {
}
}
- private void calcEnhanced(MutableQuadViewImpl quad) {
+ private void calcEnhanced(QuadViewImpl quad) {
switch (quad.geometryFlags()) {
case AXIS_ALIGNED_FLAG | CUBIC_FLAG | LIGHT_FACE_FLAG:
case AXIS_ALIGNED_FLAG | LIGHT_FACE_FLAG:
@@ -271,7 +252,7 @@ public abstract class AoCalculator {
/** used exclusively in irregular face to avoid new heap allocations each call. */
private final Vector3f vertexNormal = new Vector3f();
- private void irregularFace(MutableQuadViewImpl quad, boolean shade) {
+ private void irregularFace(QuadViewImpl quad, boolean shade) {
final Vector3f faceNorm = quad.faceNormal();
Vector3f normal;
final float[] w = this.w;
diff --git a/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/material/MaterialFinderImpl.java b/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/material/MaterialFinderImpl.java
index cfae150f4..53cdbdbd3 100644
--- a/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/material/MaterialFinderImpl.java
+++ b/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/material/MaterialFinderImpl.java
@@ -22,6 +22,7 @@ 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.MaterialView;
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
+import net.fabricmc.fabric.api.renderer.v1.material.ShadeMode;
import net.fabricmc.fabric.api.util.TriState;
public class MaterialFinderImpl extends MaterialViewImpl implements MaterialFinder {
@@ -84,6 +85,14 @@ public class MaterialFinderImpl extends MaterialViewImpl implements MaterialFind
return this;
}
+ @Override
+ public MaterialFinder shadeMode(ShadeMode mode) {
+ Objects.requireNonNull(mode, "ShadeMode may not be null");
+
+ bits = (bits & ~SHADE_MODE_MASK) | (mode.ordinal() << SHADE_MODE_BIT_OFFSET);
+ return this;
+ }
+
@Override
public MaterialFinder copyFrom(MaterialView material) {
bits = ((MaterialViewImpl) material).bits;
diff --git a/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/material/MaterialViewImpl.java b/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/material/MaterialViewImpl.java
index bb4f269ca..ca8ff4558 100644
--- a/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/material/MaterialViewImpl.java
+++ b/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/material/MaterialViewImpl.java
@@ -16,10 +16,13 @@
package net.fabricmc.fabric.impl.client.indigo.renderer.material;
+import static net.fabricmc.fabric.impl.client.indigo.renderer.mesh.EncodingFormat.bitMask;
+
import net.minecraft.util.math.MathHelper;
import net.fabricmc.fabric.api.renderer.v1.material.BlendMode;
import net.fabricmc.fabric.api.renderer.v1.material.MaterialView;
+import net.fabricmc.fabric.api.renderer.v1.material.ShadeMode;
import net.fabricmc.fabric.api.util.TriState;
/**
@@ -33,6 +36,8 @@ public class MaterialViewImpl implements MaterialView {
private static final int BLEND_MODE_COUNT = BLEND_MODES.length;
private static final TriState[] TRI_STATES = TriState.values();
private static final int TRI_STATE_COUNT = TRI_STATES.length;
+ private static final ShadeMode[] SHADE_MODES = ShadeMode.values();
+ private static final int SHADE_MODE_COUNT = SHADE_MODES.length;
protected static final int BLEND_MODE_BIT_LENGTH = MathHelper.ceilLog2(BLEND_MODE_COUNT);
protected static final int COLOR_DISABLE_BIT_LENGTH = 1;
@@ -40,6 +45,7 @@ public class MaterialViewImpl implements MaterialView {
protected static final int DIFFUSE_BIT_LENGTH = 1;
protected static final int AO_BIT_LENGTH = MathHelper.ceilLog2(TRI_STATE_COUNT);
protected static final int GLINT_BIT_LENGTH = MathHelper.ceilLog2(TRI_STATE_COUNT);
+ protected static final int SHADE_MODE_BIT_LENGTH = MathHelper.ceilLog2(SHADE_MODE_COUNT);
protected static final int BLEND_MODE_BIT_OFFSET = 0;
protected static final int COLOR_DISABLE_BIT_OFFSET = BLEND_MODE_BIT_OFFSET + BLEND_MODE_BIT_LENGTH;
@@ -47,7 +53,8 @@ public class MaterialViewImpl implements MaterialView {
protected static final int DIFFUSE_BIT_OFFSET = EMISSIVE_BIT_OFFSET + EMISSIVE_BIT_LENGTH;
protected static final int AO_BIT_OFFSET = DIFFUSE_BIT_OFFSET + DIFFUSE_BIT_LENGTH;
protected static final int GLINT_BIT_OFFSET = AO_BIT_OFFSET + AO_BIT_LENGTH;
- protected static final int TOTAL_BIT_LENGTH = GLINT_BIT_OFFSET + GLINT_BIT_LENGTH;
+ protected static final int SHADE_MODE_BIT_OFFSET = GLINT_BIT_OFFSET + GLINT_BIT_LENGTH;
+ public static final int TOTAL_BIT_LENGTH = SHADE_MODE_BIT_OFFSET + SHADE_MODE_BIT_LENGTH;
protected static final int BLEND_MODE_MASK = bitMask(BLEND_MODE_BIT_LENGTH, BLEND_MODE_BIT_OFFSET);
protected static final int COLOR_DISABLE_FLAG = bitMask(COLOR_DISABLE_BIT_LENGTH, COLOR_DISABLE_BIT_OFFSET);
@@ -55,19 +62,18 @@ public class MaterialViewImpl implements MaterialView {
protected static final int DIFFUSE_FLAG = bitMask(DIFFUSE_BIT_LENGTH, DIFFUSE_BIT_OFFSET);
protected static final int AO_MASK = bitMask(AO_BIT_LENGTH, AO_BIT_OFFSET);
protected static final int GLINT_MASK = bitMask(GLINT_BIT_LENGTH, GLINT_BIT_OFFSET);
-
- protected static int bitMask(int bitLength, int bitOffset) {
- return ((1 << bitLength) - 1) << bitOffset;
- }
+ protected static final int SHADE_MODE_MASK = bitMask(SHADE_MODE_BIT_LENGTH, SHADE_MODE_BIT_OFFSET);
protected static boolean areBitsValid(int bits) {
int blendMode = (bits & BLEND_MODE_MASK) >>> BLEND_MODE_BIT_OFFSET;
int ao = (bits & AO_MASK) >>> AO_BIT_OFFSET;
int glint = (bits & GLINT_MASK) >>> GLINT_BIT_OFFSET;
+ int shadeMode = (bits & SHADE_MODE_MASK) >>> SHADE_MODE_BIT_OFFSET;
return blendMode < BLEND_MODE_COUNT
&& ao < TRI_STATE_COUNT
- && glint < TRI_STATE_COUNT;
+ && glint < TRI_STATE_COUNT
+ && shadeMode < SHADE_MODE_COUNT;
}
protected int bits;
@@ -105,4 +111,9 @@ public class MaterialViewImpl implements MaterialView {
public TriState glint() {
return TRI_STATES[(bits & GLINT_MASK) >>> GLINT_BIT_OFFSET];
}
+
+ @Override
+ public ShadeMode shadeMode() {
+ return SHADE_MODES[(bits & SHADE_MODE_MASK) >>> SHADE_MODE_BIT_OFFSET];
+ }
}
diff --git a/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/mesh/EncodingFormat.java b/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/mesh/EncodingFormat.java
index 99e190a23..f5714b529 100644
--- a/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/mesh/EncodingFormat.java
+++ b/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/mesh/EncodingFormat.java
@@ -17,6 +17,7 @@
package net.fabricmc.fabric.impl.client.indigo.renderer.mesh;
import com.google.common.base.Preconditions;
+import org.jetbrains.annotations.Nullable;
import net.minecraft.client.render.VertexFormat;
import net.minecraft.client.render.VertexFormats;
@@ -26,6 +27,7 @@ import net.minecraft.util.math.MathHelper;
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView;
import net.fabricmc.fabric.api.renderer.v1.model.ModelHelper;
import net.fabricmc.fabric.impl.client.indigo.renderer.helper.GeometryHelper;
+import net.fabricmc.fabric.impl.client.indigo.renderer.material.MaterialViewImpl;
import net.fabricmc.fabric.impl.client.indigo.renderer.material.RenderMaterialImpl;
/**
@@ -78,66 +80,75 @@ public abstract class EncodingFormat {
/** used for quick clearing of quad buffers. */
static final int[] EMPTY = new int[TOTAL_STRIDE];
- private static final int DIRECTION_MASK = MathHelper.smallestEncompassingPowerOfTwo(ModelHelper.NULL_FACE_ID) - 1;
- private static final int DIRECTION_BIT_COUNT = Integer.bitCount(DIRECTION_MASK);
- private static final int CULL_SHIFT = 0;
- private static final int CULL_INVERSE_MASK = ~(DIRECTION_MASK << CULL_SHIFT);
- private static final int LIGHT_SHIFT = CULL_SHIFT + DIRECTION_BIT_COUNT;
- private static final int LIGHT_INVERSE_MASK = ~(DIRECTION_MASK << LIGHT_SHIFT);
- private static final int NORMALS_SHIFT = LIGHT_SHIFT + DIRECTION_BIT_COUNT;
- private static final int NORMALS_COUNT = 4;
- private static final int NORMALS_MASK = (1 << NORMALS_COUNT) - 1;
- private static final int NORMALS_INVERSE_MASK = ~(NORMALS_MASK << NORMALS_SHIFT);
- private static final int GEOMETRY_SHIFT = NORMALS_SHIFT + NORMALS_COUNT;
- private static final int GEOMETRY_MASK = (1 << GeometryHelper.FLAG_BIT_COUNT) - 1;
- private static final int GEOMETRY_INVERSE_MASK = ~(GEOMETRY_MASK << GEOMETRY_SHIFT);
- private static final int MATERIAL_SHIFT = GEOMETRY_SHIFT + GeometryHelper.FLAG_BIT_COUNT;
- private static final int MATERIAL_MASK = MathHelper.smallestEncompassingPowerOfTwo(RenderMaterialImpl.VALUE_COUNT) - 1;
- private static final int MATERIAL_BIT_COUNT = Integer.bitCount(MATERIAL_MASK);
- private static final int MATERIAL_INVERSE_MASK = ~(MATERIAL_MASK << MATERIAL_SHIFT);
+ private static final int DIRECTION_COUNT = Direction.values().length;
+ private static final int NULLABLE_DIRECTION_COUNT = DIRECTION_COUNT + 1;
+
+ private static final int CULL_BIT_LENGTH = MathHelper.ceilLog2(NULLABLE_DIRECTION_COUNT);
+ private static final int LIGHT_BIT_LENGTH = MathHelper.ceilLog2(DIRECTION_COUNT);
+ private static final int NORMALS_BIT_LENGTH = 4;
+ private static final int GEOMETRY_BIT_LENGTH = GeometryHelper.FLAG_BIT_COUNT;
+ private static final int MATERIAL_BIT_LENGTH = MaterialViewImpl.TOTAL_BIT_LENGTH;
+
+ private static final int CULL_BIT_OFFSET = 0;
+ private static final int LIGHT_BIT_OFFSET = CULL_BIT_OFFSET + CULL_BIT_LENGTH;
+ private static final int NORMALS_BIT_OFFSET = LIGHT_BIT_OFFSET + LIGHT_BIT_LENGTH;
+ private static final int GEOMETRY_BIT_OFFSET = NORMALS_BIT_OFFSET + NORMALS_BIT_LENGTH;
+ private static final int MATERIAL_BIT_OFFSET = GEOMETRY_BIT_OFFSET + GEOMETRY_BIT_LENGTH;
+ private static final int TOTAL_BIT_LENGTH = MATERIAL_BIT_OFFSET + MATERIAL_BIT_LENGTH;
+
+ private static final int CULL_MASK = bitMask(CULL_BIT_LENGTH, CULL_BIT_OFFSET);
+ private static final int LIGHT_MASK = bitMask(LIGHT_BIT_LENGTH, LIGHT_BIT_OFFSET);
+ private static final int NORMALS_MASK = bitMask(NORMALS_BIT_LENGTH, NORMALS_BIT_OFFSET);
+ private static final int GEOMETRY_MASK = bitMask(GEOMETRY_BIT_LENGTH, GEOMETRY_BIT_OFFSET);
+ private static final int MATERIAL_MASK = bitMask(MATERIAL_BIT_LENGTH, MATERIAL_BIT_OFFSET);
static {
- Preconditions.checkArgument(MATERIAL_SHIFT + MATERIAL_BIT_COUNT <= 32, "Indigo header encoding bit count (%s) exceeds integer bit length)", TOTAL_STRIDE);
+ Preconditions.checkArgument(TOTAL_BIT_LENGTH <= 32, "Indigo header encoding bit count (%s) exceeds integer bit length)", TOTAL_STRIDE);
}
+ public static int bitMask(int bitLength, int bitOffset) {
+ return ((1 << bitLength) - 1) << bitOffset;
+ }
+
+ @Nullable
static Direction cullFace(int bits) {
- return ModelHelper.faceFromIndex((bits >>> CULL_SHIFT) & DIRECTION_MASK);
+ return ModelHelper.faceFromIndex((bits & CULL_MASK) >>> CULL_BIT_OFFSET);
}
- static int cullFace(int bits, Direction face) {
- return (bits & CULL_INVERSE_MASK) | (ModelHelper.toFaceIndex(face) << CULL_SHIFT);
+ static int cullFace(int bits, @Nullable Direction face) {
+ return (bits & ~CULL_MASK) | (ModelHelper.toFaceIndex(face) << CULL_BIT_OFFSET);
}
static Direction lightFace(int bits) {
- return ModelHelper.faceFromIndex((bits >>> LIGHT_SHIFT) & DIRECTION_MASK);
+ return ModelHelper.faceFromIndex((bits & LIGHT_MASK) >>> LIGHT_BIT_OFFSET);
}
static int lightFace(int bits, Direction face) {
- return (bits & LIGHT_INVERSE_MASK) | (ModelHelper.toFaceIndex(face) << LIGHT_SHIFT);
+ return (bits & ~LIGHT_MASK) | (ModelHelper.toFaceIndex(face) << LIGHT_BIT_OFFSET);
}
/** indicate if vertex normal has been set - bits correspond to vertex ordinals. */
static int normalFlags(int bits) {
- return (bits >>> NORMALS_SHIFT) & NORMALS_MASK;
+ return (bits & NORMALS_MASK) >>> NORMALS_BIT_OFFSET;
}
static int normalFlags(int bits, int normalFlags) {
- return (bits & NORMALS_INVERSE_MASK) | ((normalFlags & NORMALS_MASK) << NORMALS_SHIFT);
+ return (bits & ~NORMALS_MASK) | ((normalFlags << NORMALS_BIT_OFFSET) & NORMALS_MASK);
}
static int geometryFlags(int bits) {
- return (bits >>> GEOMETRY_SHIFT) & GEOMETRY_MASK;
+ return (bits & GEOMETRY_MASK) >>> GEOMETRY_BIT_OFFSET;
}
static int geometryFlags(int bits, int geometryFlags) {
- return (bits & GEOMETRY_INVERSE_MASK) | ((geometryFlags & GEOMETRY_MASK) << GEOMETRY_SHIFT);
+ return (bits & ~GEOMETRY_MASK) | ((geometryFlags << GEOMETRY_BIT_OFFSET) & GEOMETRY_MASK);
}
static RenderMaterialImpl material(int bits) {
- return RenderMaterialImpl.byIndex((bits >>> MATERIAL_SHIFT) & MATERIAL_MASK);
+ return RenderMaterialImpl.byIndex((bits & MATERIAL_MASK) >>> MATERIAL_BIT_OFFSET);
}
static int material(int bits, RenderMaterialImpl material) {
- return (bits & MATERIAL_INVERSE_MASK) | (material.index() << MATERIAL_SHIFT);
+ return (bits & ~MATERIAL_MASK) | (material.index() << MATERIAL_BIT_OFFSET);
}
}
diff --git a/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/AbstractBlockRenderContext.java b/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/AbstractBlockRenderContext.java
index 38659bb2f..3d9ef25fb 100644
--- a/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/AbstractBlockRenderContext.java
+++ b/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/AbstractBlockRenderContext.java
@@ -33,6 +33,7 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
+import net.fabricmc.fabric.api.renderer.v1.material.ShadeMode;
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
import net.fabricmc.fabric.api.util.TriState;
import net.fabricmc.fabric.impl.client.indigo.Indigo;
@@ -55,18 +56,7 @@ public abstract class AbstractBlockRenderContext extends AbstractRenderContext {
@Override
public void emitDirectly() {
- renderQuad(this, false);
- }
- };
- private final MutableQuadViewImpl vanillaModelEditorQuad = new MutableQuadViewImpl() {
- {
- data = new int[EncodingFormat.TOTAL_STRIDE];
- clear();
- }
-
- @Override
- public void emitDirectly() {
- renderQuad(this, true);
+ renderQuad(this);
}
};
@@ -88,11 +78,6 @@ public abstract class AbstractBlockRenderContext extends AbstractRenderContext {
return editorQuad;
}
- public QuadEmitter getVanillaModelEmitter() {
- // Do not clear the editorQuad since it is not accessible to API users.
- return vanillaModelEditorQuad;
- }
-
@Override
public boolean isFaceCulled(@Nullable Direction face) {
return !blockInfo.shouldDrawFace(face);
@@ -108,7 +93,7 @@ public abstract class AbstractBlockRenderContext extends AbstractRenderContext {
return vanillaModelConsumer;
}
- private void renderQuad(MutableQuadViewImpl quad, boolean isVanilla) {
+ private void renderQuad(MutableQuadViewImpl quad) {
if (!transform(quad)) {
return;
}
@@ -122,10 +107,11 @@ public abstract class AbstractBlockRenderContext extends AbstractRenderContext {
final TriState aoMode = mat.ambientOcclusion();
final boolean ao = blockInfo.useAo && (aoMode == TriState.TRUE || (aoMode == TriState.DEFAULT && blockInfo.defaultAo));
final boolean emissive = mat.emissive();
+ final boolean vanillaShade = mat.shadeMode() == ShadeMode.VANILLA;
final VertexConsumer vertexConsumer = getVertexConsumer(blockInfo.effectiveRenderLayer(mat.blendMode()));
colorizeQuad(quad, colorIndex);
- shadeQuad(quad, isVanilla, ao, emissive);
+ shadeQuad(quad, ao, emissive, vanillaShade);
bufferQuad(quad, vertexConsumer);
}
@@ -140,10 +126,10 @@ public abstract class AbstractBlockRenderContext extends AbstractRenderContext {
}
}
- private void shadeQuad(MutableQuadViewImpl quad, boolean isVanilla, boolean ao, boolean emissive) {
+ private void shadeQuad(MutableQuadViewImpl quad, boolean ao, boolean emissive, boolean vanillaShade) {
// routines below have a bit of copy-paste code reuse to avoid conditional execution inside a hot loop
if (ao) {
- aoCalc.compute(quad, isVanilla);
+ aoCalc.compute(quad, vanillaShade);
if (emissive) {
for (int i = 0; i < 4; i++) {
@@ -157,7 +143,7 @@ public abstract class AbstractBlockRenderContext extends AbstractRenderContext {
}
}
} else {
- shadeFlatQuad(quad, isVanilla);
+ shadeFlatQuad(quad, vanillaShade);
if (emissive) {
for (int i = 0; i < 4; i++) {
@@ -177,11 +163,11 @@ public abstract class AbstractBlockRenderContext extends AbstractRenderContext {
* Starting in 1.16 flat shading uses dimension-specific diffuse factors that can be < 1.0
* even for un-shaded quads. These are also applied with AO shading but that is done in AO calculator.
*/
- private void shadeFlatQuad(MutableQuadViewImpl quad, boolean isVanilla) {
+ private void shadeFlatQuad(MutableQuadViewImpl quad, boolean vanillaShade) {
final boolean hasShade = quad.hasShade();
// Check the AO mode to match how shade is applied during smooth lighting
- if ((Indigo.AMBIENT_OCCLUSION_MODE == AoConfig.HYBRID && !isVanilla) || Indigo.AMBIENT_OCCLUSION_MODE == AoConfig.ENHANCED) {
+ if ((Indigo.AMBIENT_OCCLUSION_MODE == AoConfig.HYBRID && !vanillaShade) || Indigo.AMBIENT_OCCLUSION_MODE == AoConfig.ENHANCED) {
if (quad.hasAllVertexNormals()) {
for (int i = 0; i < 4; i++) {
float shade = normalShade(quad.normalX(i), quad.normalY(i), quad.normalZ(i), hasShade);
@@ -305,7 +291,7 @@ public abstract class AbstractBlockRenderContext extends AbstractRenderContext {
@Override
public void accept(BakedModel model, @Nullable BlockState state) {
- VanillaModelEncoder.emitBlockQuads(model, state, blockInfo.randomSupplier, AbstractBlockRenderContext.this, vanillaModelEditorQuad);
+ VanillaModelEncoder.emitBlockQuads(model, state, blockInfo.randomSupplier, AbstractBlockRenderContext.this);
}
}
}
diff --git a/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/ChunkRenderInfo.java b/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/ChunkRenderInfo.java
index 69a83f398..b16ff91a3 100644
--- a/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/ChunkRenderInfo.java
+++ b/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/ChunkRenderInfo.java
@@ -16,7 +16,7 @@
package net.fabricmc.fabric.impl.client.indigo.renderer.render;
-import java.util.Map;
+import java.util.function.Function;
import it.unimi.dsi.fastutil.longs.Long2FloatOpenHashMap;
import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap;
@@ -24,12 +24,8 @@ import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap;
import net.minecraft.block.BlockState;
import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.RenderLayer;
-import net.minecraft.client.render.VertexFormat;
-import net.minecraft.client.render.VertexFormats;
import net.minecraft.client.render.WorldRenderer;
-import net.minecraft.client.render.chunk.BlockBufferAllocatorStorage;
import net.minecraft.client.render.chunk.ChunkRendererRegion;
-import net.minecraft.client.util.BufferAllocator;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockRenderView;
@@ -69,9 +65,7 @@ public class ChunkRenderInfo {
private final Long2IntOpenHashMap brightnessCache;
private final Long2FloatOpenHashMap aoLevelCache;
- private final BlockPos.Mutable chunkOrigin = new BlockPos.Mutable();
- BlockBufferAllocatorStorage builders;
- Map buffers;
+ private Function bufferFunc;
BlockRenderView blockView;
ChunkRenderInfo() {
@@ -81,31 +75,21 @@ public class ChunkRenderInfo {
aoLevelCache.defaultReturnValue(Float.MAX_VALUE);
}
- void prepare(ChunkRendererRegion blockView, BlockPos chunkOrigin, BlockBufferAllocatorStorage builders, Map buffers) {
+ void prepare(ChunkRendererRegion blockView, Function bufferFunc) {
this.blockView = blockView;
- this.chunkOrigin.set(chunkOrigin);
- this.builders = builders;
- this.buffers = buffers;
+ this.bufferFunc = bufferFunc;
+
brightnessCache.clear();
aoLevelCache.clear();
}
void release() {
+ blockView = null;
+ bufferFunc = null;
}
- /** Lazily retrieves output buffer for given layer, initializing as needed. */
- public BufferBuilder getInitializedBuffer(RenderLayer renderLayer) {
- // TODO 24w21b - possibly AW class_9810#method_60903 which does the same thing?
- BufferBuilder builder = buffers.get(renderLayer);
-
- if (builder == null) {
- BufferAllocator byteBuilder = builders.get(renderLayer);
- builder = new BufferBuilder(byteBuilder, VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR_TEXTURE_LIGHT_NORMAL);
-
- buffers.put(renderLayer, builder);
- }
-
- return builder;
+ BufferBuilder getBuffer(RenderLayer layer) {
+ return bufferFunc.apply(layer);
}
/**
diff --git a/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/TerrainRenderContext.java b/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/TerrainRenderContext.java
index b35bf8396..5dab19342 100644
--- a/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/TerrainRenderContext.java
+++ b/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/TerrainRenderContext.java
@@ -16,14 +16,13 @@
package net.fabricmc.fabric.impl.client.indigo.renderer.render;
-import java.util.Map;
+import java.util.function.Function;
import net.minecraft.block.BlockState;
import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.OverlayTexture;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.VertexConsumer;
-import net.minecraft.client.render.chunk.BlockBufferAllocatorStorage;
import net.minecraft.client.render.chunk.ChunkRendererRegion;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.util.math.MatrixStack;
@@ -69,12 +68,12 @@ public class TerrainRenderContext extends AbstractBlockRenderContext {
@Override
protected VertexConsumer getVertexConsumer(RenderLayer layer) {
- return chunkInfo.getInitializedBuffer(layer);
+ return chunkInfo.getBuffer(layer);
}
- public void prepare(ChunkRendererRegion blockView, BlockPos chunkOrigin, BlockBufferAllocatorStorage builders, Map builderMap) {
+ public void prepare(ChunkRendererRegion blockView, Function bufferFunc) {
+ chunkInfo.prepare(blockView, bufferFunc);
blockInfo.prepareForWorld(blockView, true);
- chunkInfo.prepare(blockView, chunkOrigin, builders, builderMap);
}
public void release() {
diff --git a/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/mixin/client/indigo/renderer/BakedModelMixin.java b/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/mixin/client/indigo/renderer/BakedModelMixin.java
deleted file mode 100644
index 10218850f..000000000
--- a/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/mixin/client/indigo/renderer/BakedModelMixin.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2016, 2017, 2018, 2019 FabricMC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.fabricmc.fabric.mixin.client.indigo.renderer;
-
-import java.util.function.Supplier;
-
-import org.spongepowered.asm.mixin.Mixin;
-
-import net.minecraft.block.BlockState;
-import net.minecraft.client.render.model.BakedModel;
-import net.minecraft.util.math.BlockPos;
-import net.minecraft.util.math.random.Random;
-import net.minecraft.world.BlockRenderView;
-
-import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel;
-import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
-import net.fabricmc.fabric.impl.client.indigo.renderer.render.AbstractBlockRenderContext;
-import net.fabricmc.fabric.impl.renderer.VanillaModelEncoder;
-
-@Mixin(BakedModel.class)
-public interface BakedModelMixin extends FabricBakedModel {
- /**
- * Override the fallback path to shade vanilla quads differently.
- */
- @Override
- default void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context) {
- VanillaModelEncoder.emitBlockQuads((BakedModel) this, state, randomSupplier, context, ((AbstractBlockRenderContext) context).getVanillaModelEmitter());
- }
-}
diff --git a/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/mixin/client/indigo/renderer/SectionBuilderMixin.java b/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/mixin/client/indigo/renderer/SectionBuilderMixin.java
index 72b488fc6..fd4ff9eb9 100644
--- a/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/mixin/client/indigo/renderer/SectionBuilderMixin.java
+++ b/fabric-renderer-indigo/src/client/java/net/fabricmc/fabric/mixin/client/indigo/renderer/SectionBuilderMixin.java
@@ -17,11 +17,11 @@
package net.fabricmc.fabric.mixin.client.indigo.renderer;
import java.util.Map;
-import java.util.Set;
import com.llamalad7.mixinextras.sugar.Local;
import com.mojang.blaze3d.systems.VertexSorter;
import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
@@ -30,7 +30,6 @@ import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import net.minecraft.block.BlockRenderType;
import net.minecraft.block.BlockState;
-import net.minecraft.block.entity.BlockEntity;
import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.VertexConsumer;
@@ -67,17 +66,19 @@ import net.fabricmc.fabric.impl.client.indigo.renderer.render.TerrainRenderConte
*/
@Mixin(SectionBuilder.class)
public abstract class SectionBuilderMixin {
+ @Shadow
+ abstract BufferBuilder beginBufferBuilding(Map builders, BlockBufferAllocatorStorage allocatorStorage, RenderLayer layer);
+
@Inject(method = "build",
at = @At(value = "INVOKE", target = "Lnet/minecraft/util/math/BlockPos;iterate(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/BlockPos;)Ljava/lang/Iterable;"),
locals = LocalCapture.CAPTURE_FAILHARD)
- private void hookChunkBuild(ChunkSectionPos sectionPos, ChunkRendererRegion region, VertexSorter sorter,
- BlockBufferAllocatorStorage builder,
- CallbackInfoReturnable ci,
- @Local(ordinal = 0) Map builderMap) {
- // hook just before iterating over the render chunk's chunks blocks, captures the buffer builder map
-
+ private void hookBuild(ChunkSectionPos sectionPos, ChunkRendererRegion region, VertexSorter sorter,
+ BlockBufferAllocatorStorage allocators,
+ CallbackInfoReturnable cir,
+ @Local(ordinal = 0) Map builderMap) {
+ // hook just before iterating over the render chunk's blocks to capture the buffer builder map
TerrainRenderContext renderer = TerrainRenderContext.POOL.get();
- renderer.prepare(region, sectionPos.getMinPos(), builder, builderMap);
+ renderer.prepare(region, layer -> beginBufferBuilding(builderMap, allocators, layer));
((AccessChunkRendererRegion) region).fabric_setRenderer(renderer);
}
@@ -99,7 +100,7 @@ public abstract class SectionBuilderMixin {
*/
@Redirect(method = "build", require = 1, at = @At(value = "INVOKE",
target = "Lnet/minecraft/client/render/block/BlockRenderManager;renderBlock(Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/BlockRenderView;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumer;ZLnet/minecraft/util/math/random/Random;)V"))
- private void hookChunkBuildTessellate(BlockRenderManager renderManager, BlockState blockState, BlockPos blockPos, BlockRenderView blockView, MatrixStack matrix, VertexConsumer bufferBuilder, boolean checkSides, Random random) {
+ private void hookBuildRenderBlock(BlockRenderManager renderManager, BlockState blockState, BlockPos blockPos, BlockRenderView blockView, MatrixStack matrix, VertexConsumer bufferBuilder, boolean checkSides, Random random) {
if (blockState.getRenderType() == BlockRenderType.MODEL) {
final BakedModel model = renderManager.getModel(blockState);
@@ -115,11 +116,9 @@ public abstract class SectionBuilderMixin {
/**
* Release all references. Probably not necessary but would be $#%! to debug if it is.
*/
- @Inject(method = "build",
- at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/block/BlockModelRenderer;disableBrightnessCache()V"))
- private void hookRebuildChunkReturn(CallbackInfoReturnable> ci) {
- // hook after iterating over the render chunk's chunks blocks, must be called if and only if hookChunkBuild happened
-
- TerrainRenderContext.POOL.get().release();
+ @Inject(method = "build", at = @At(value = "RETURN"))
+ private void hookBuildReturn(ChunkSectionPos sectionPos, ChunkRendererRegion renderRegion, VertexSorter vertexSorter, BlockBufferAllocatorStorage allocatorStorage, CallbackInfoReturnable cir) {
+ ((AccessChunkRendererRegion) renderRegion).fabric_getRenderer().release();
+ ((AccessChunkRendererRegion) renderRegion).fabric_setRenderer(null);
}
}
diff --git a/fabric-renderer-indigo/src/client/resources/fabric-renderer-indigo.accesswidener b/fabric-renderer-indigo/src/client/resources/fabric-renderer-indigo.accesswidener
index 85c5f524a..fce49d4a4 100644
--- a/fabric-renderer-indigo/src/client/resources/fabric-renderer-indigo.accesswidener
+++ b/fabric-renderer-indigo/src/client/resources/fabric-renderer-indigo.accesswidener
@@ -1,11 +1,7 @@
accessWidener v2 named
-accessible class net/minecraft/client/render/chunk/ChunkBuilder$BuiltChunk$RebuildTask
-
accessible class net/minecraft/client/render/block/BlockModelRenderer$AmbientOcclusionCalculator
accessible field net/minecraft/client/render/block/BlockModelRenderer$AmbientOcclusionCalculator brightness [F
accessible field net/minecraft/client/render/block/BlockModelRenderer$AmbientOcclusionCalculator light [I
accessible method net/minecraft/client/render/block/BlockModelRenderer getQuadDimensions (Lnet/minecraft/world/BlockRenderView;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;[ILnet/minecraft/util/math/Direction;[FLjava/util/BitSet;)V
-
-accessible method net/minecraft/client/render/item/ItemRenderer renderBakedItemModel (Lnet/minecraft/client/render/model/BakedModel;Lnet/minecraft/item/ItemStack;IILnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumer;)V
diff --git a/fabric-renderer-indigo/src/client/resources/fabric-renderer-indigo.mixins.json b/fabric-renderer-indigo/src/client/resources/fabric-renderer-indigo.mixins.json
index f7adfac5a..0c59e3c42 100644
--- a/fabric-renderer-indigo/src/client/resources/fabric-renderer-indigo.mixins.json
+++ b/fabric-renderer-indigo/src/client/resources/fabric-renderer-indigo.mixins.json
@@ -1,12 +1,11 @@
{
"required": true,
"package": "net.fabricmc.fabric.mixin.client.indigo.renderer",
- "compatibilityLevel": "JAVA_17",
+ "compatibilityLevel": "JAVA_21",
"plugin": "net.fabricmc.fabric.impl.client.indigo.IndigoMixinConfigPlugin",
"mixins": [
],
"client": [
- "BakedModelMixin",
"BlockModelRendererMixin",
"ChunkRendererRegionMixin",
"ItemRendererAccessor",