Skip to content

Commit

Permalink
Allow faces of an "elements" model to have disabled ambient occlusion (
Browse files Browse the repository at this point in the history
  • Loading branch information
nikita488 authored Sep 8, 2022
1 parent 94e1e54 commit e0477f8
Show file tree
Hide file tree
Showing 25 changed files with 341 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,14 @@
}

}
@@ -113,6 +_,7 @@
private void m_111012_(BlockAndTintGetter p_111013_, BlockState p_111014_, BlockPos p_111015_, PoseStack p_111016_, VertexConsumer p_111017_, List<BakedQuad> p_111018_, float[] p_111019_, BitSet p_111020_, ModelBlockRenderer.AmbientOcclusionFace p_111021_, int p_111022_) {
for(BakedQuad bakedquad : p_111018_) {
this.m_111039_(p_111013_, p_111014_, p_111015_, bakedquad.m_111303_(), bakedquad.m_111306_(), p_111019_, p_111020_);
+ if (!net.minecraftforge.client.ForgeHooksClient.calculateFaceWithoutAO(p_111013_, p_111014_, p_111015_, bakedquad, p_111020_.get(0), p_111021_.f_111149_, p_111021_.f_111150_))
p_111021_.m_111167_(p_111013_, p_111014_, p_111015_, bakedquad.m_111306_(), p_111019_, p_111020_, bakedquad.m_111307_());
this.m_111023_(p_111013_, p_111014_, p_111015_, p_111017_, p_111016_.m_85850_(), bakedquad, p_111021_.f_111149_[0], p_111021_.f_111149_[1], p_111021_.f_111149_[2], p_111021_.f_111149_[3], p_111021_.f_111150_[0], p_111021_.f_111150_[1], p_111021_.f_111150_[2], p_111021_.f_111150_[3], p_111022_);
}
@@ -217,17 +_,21 @@

}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
--- a/net/minecraft/client/renderer/block/model/BakedQuad.java
+++ b/net/minecraft/client/renderer/block/model/BakedQuad.java
@@ -12,13 +_,19 @@
protected final Direction f_111294_;
protected final TextureAtlasSprite f_111295_;
private final boolean f_111296_;
+ private final boolean hasAmbientOcclusion;

public BakedQuad(int[] p_111298_, int p_111299_, Direction p_111300_, TextureAtlasSprite p_111301_, boolean p_111302_) {
+ this(p_111298_, p_111299_, p_111300_, p_111301_, p_111302_, true);
+ }
+
+ public BakedQuad(int[] p_111298_, int p_111299_, Direction p_111300_, TextureAtlasSprite p_111301_, boolean p_111302_, boolean hasAmbientOcclusion) {
this.f_111292_ = p_111298_;
this.f_111293_ = p_111299_;
this.f_111294_ = p_111300_;
this.f_111295_ = p_111301_;
this.f_111296_ = p_111302_;
+ this.hasAmbientOcclusion = hasAmbientOcclusion;
}

public TextureAtlasSprite m_173410_() {
@@ -43,5 +_,9 @@

public boolean m_111307_() {
return this.f_111296_;
+ }
+
+ public boolean hasAmbientOcclusion() {
+ return this.hasAmbientOcclusion;
}
}
Original file line number Diff line number Diff line change
@@ -1,33 +1,40 @@
--- a/net/minecraft/client/renderer/block/model/BlockElementFace.java
+++ b/net/minecraft/client/renderer/block/model/BlockElementFace.java
@@ -19,12 +_,18 @@
@@ -19,12 +_,24 @@
public final int f_111355_;
public final String f_111356_;
public final BlockFaceUV f_111357_;
+ public final int emissivity;
+ public final boolean hasAmbientOcclusion;

public BlockElementFace(@Nullable Direction p_111359_, int p_111360_, String p_111361_, BlockFaceUV p_111362_) {
+ this(p_111359_, p_111360_, p_111361_, p_111362_, 0);
+ this(p_111359_, p_111360_, p_111361_, p_111362_, 0, true);
+ }
+
+ public BlockElementFace(@Nullable Direction p_111359_, int p_111360_, String p_111361_, BlockFaceUV p_111362_, int emissivity) {
+ this(p_111359_, p_111360_, p_111361_, p_111362_, emissivity, true);
+ }
+
+ public BlockElementFace(@Nullable Direction p_111359_, int p_111360_, String p_111361_, BlockFaceUV p_111362_, int emissivity, boolean hasAmbientOcclusion) {
this.f_111354_ = p_111359_;
this.f_111355_ = p_111360_;
this.f_111356_ = p_111361_;
this.f_111357_ = p_111362_;
+ this.emissivity = emissivity;
+ this.hasAmbientOcclusion = hasAmbientOcclusion;
}

@OnlyIn(Dist.CLIENT)
@@ -37,7 +_,10 @@
@@ -37,7 +_,11 @@
int i = this.m_111368_(jsonobject);
String s = this.m_111370_(jsonobject);
BlockFaceUV blockfaceuv = p_111367_.deserialize(jsonobject, BlockFaceUV.class);
- return new BlockElementFace(direction, i, s, blockfaceuv);
+ int emissivity = GsonHelper.m_13824_(jsonobject, "emissivity", 0);
+ if (emissivity != net.minecraft.util.Mth.m_14045_(emissivity, 0, 15))
+ throw new JsonParseException("The emissivity value must be between 0 and 15. Found: " + emissivity);
+ return new BlockElementFace(direction, i, s, blockfaceuv, emissivity);
+ boolean hasAmbientOcclusion = GsonHelper.m_13855_(jsonobject, "ambientocclusion", true);
+ return new BlockElementFace(direction, i, s, blockfaceuv, emissivity, hasAmbientOcclusion);
}

protected int m_111368_(JsonObject p_111369_) {
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

- return new BakedQuad(aint, p_111603_.f_111355_, direction, p_111604_, p_111608_);
+ net.minecraftforge.client.ForgeHooksClient.fillNormal(aint, direction);
+ var quad = new BakedQuad(aint, p_111603_.f_111355_, direction, p_111604_, p_111608_);
+ var quad = new BakedQuad(aint, p_111603_.f_111355_, direction, p_111604_, p_111608_, p_111603_.hasAmbientOcclusion);
+ net.minecraftforge.client.model.QuadTransformers.settingEmissivity(p_111603_.emissivity).processInPlace(quad);
+ return quad;
}
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/net/minecraftforge/client/ForgeHooksClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
import net.minecraft.client.renderer.ShaderInstance;
import net.minecraft.client.renderer.Sheets;
import net.minecraft.client.renderer.block.BlockRenderDispatcher;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.ItemTransforms;
import net.minecraft.client.renderer.culling.Frustum;
import net.minecraft.client.renderer.texture.TextureAtlas;
Expand Down Expand Up @@ -561,6 +562,18 @@ private static Vector3f getVertexPos(int[] data, int vertex)
return new Vector3f(x, y, z);
}

public static boolean calculateFaceWithoutAO(BlockAndTintGetter getter, BlockState state, BlockPos pos, BakedQuad quad, boolean isFaceCubic, float[] brightness, int[] lightmap)
{
if (quad.hasAmbientOcclusion())
return false;

BlockPos lightmapPos = isFaceCubic ? pos.relative(quad.getDirection()) : pos;

brightness[0] = brightness[1] = brightness[2] = brightness[3] = getter.getShade(quad.getDirection(), quad.isShade());
lightmap[0] = lightmap[1] = lightmap[2] = lightmap[3] = LevelRenderer.getLightColor(getter, state, lightmapPos);
return true;
}

public static void loadEntityShader(Entity entity, GameRenderer entityRenderer)
{
if (entity != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ static IQuadTransformer applyingLightmap(int lightmap)
private static BakedQuad copy(BakedQuad quad)
{
var vertices = quad.getVertices();
return new BakedQuad(Arrays.copyOf(vertices, vertices.length), quad.getTintIndex(), quad.getDirection(), quad.getSprite(), quad.isShade());
return new BakedQuad(Arrays.copyOf(vertices, vertices.length), quad.getTintIndex(), quad.getDirection(), quad.getSprite(), quad.isShade(), quad.hasAmbientOcclusion());
}

private static int findOffset(VertexFormatElement element)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,9 @@ public JsonObject toJson() {
if (face.emissivity > 0) {
faceObj.addProperty("emissivity", face.emissivity);
}
if (!face.hasAmbientOcclusion) {
faceObj.addProperty("ambientocclusion", face.hasAmbientOcclusion);
}
faces.add(dir.getSerializedName(), faceObj);
}
if (!part.faces.isEmpty()) {
Expand Down Expand Up @@ -517,6 +520,7 @@ public class FaceBuilder {
private float[] uvs;
private FaceRotation rotation = FaceRotation.ZERO;
private int emissivity = 0;
private boolean hasAmbientOcclusion = true;

FaceBuilder(Direction dir) {
// param unused for functional match
Expand Down Expand Up @@ -583,11 +587,22 @@ public FaceBuilder emissive() {
return emissivity(15);
}

/**
* Set the ambient occlusion of the face.
*
* @param ao the ambient occlusion
* @return this builder
*/
public FaceBuilder ao(boolean ao) {
this.hasAmbientOcclusion = ao;
return this;
}

BlockElementFace build() {
if (this.texture == null) {
throw new IllegalStateException("A model face must have a texture");
}
return new BlockElementFace(cullface, tintindex, texture, new BlockFaceUV(uvs, rotation.rotation), emissivity);
return new BlockElementFace(cullface, tintindex, texture, new BlockFaceUV(uvs, rotation.rotation), emissivity, hasAmbientOcclusion);
}

public ElementBuilder end() { return ElementBuilder.this; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.color.block.BlockColors;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.block.ModelBlockRenderer;
Expand Down Expand Up @@ -67,8 +68,11 @@ public void tesselateWithAO(BlockAndTintGetter level, BakedModel model, BlockSta

public static boolean render(VertexConsumer vertexConsumer, QuadLighter lighter, BlockAndTintGetter level, BakedModel model, BlockState state, BlockPos pos, PoseStack poseStack, boolean checkSides, RandomSource rand, long seed, int packedOverlay, ModelData modelData, RenderType renderType)
{
ForgeModelBlockRenderer renderer = (ForgeModelBlockRenderer)Minecraft.getInstance().getBlockRenderer().getModelRenderer();
var pose = poseStack.last();
var empty = true;
var smoothLighter = lighter instanceof SmoothQuadLighter;
QuadLighter flatLighter = null;

rand.setSeed(seed);
List<BakedQuad> quads = model.getQuads(state, null, rand, modelData, renderType);
Expand All @@ -78,7 +82,19 @@ public static boolean render(VertexConsumer vertexConsumer, QuadLighter lighter,
lighter.setup(level, pos, state);
for (BakedQuad quad : quads)
{
lighter.process(vertexConsumer, pose, quad, packedOverlay);
if (smoothLighter && !quad.hasAmbientOcclusion())
{
if (flatLighter == null)
{
flatLighter = renderer.flatLighter.get();
flatLighter.setup(level, pos, state);
}
flatLighter.process(vertexConsumer, pose, quad, packedOverlay);
}
else
{
lighter.process(vertexConsumer, pose, quad, packedOverlay);
}
}
}

Expand All @@ -99,11 +115,25 @@ public static boolean render(VertexConsumer vertexConsumer, QuadLighter lighter,
}
for (BakedQuad quad : quads)
{
lighter.process(vertexConsumer, pose, quad, packedOverlay);
if (smoothLighter && !quad.hasAmbientOcclusion())
{
if (flatLighter == null)
{
flatLighter = renderer.flatLighter.get();
flatLighter.setup(level, pos, state);
}
flatLighter.process(vertexConsumer, pose, quad, packedOverlay);
}
else
{
lighter.process(vertexConsumer, pose, quad, packedOverlay);
}
}
}
}
lighter.reset();
if (flatLighter != null)
flatLighter.reset();
return !empty;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public class QuadBakingVertexConsumer implements VertexConsumer
private Direction direction = Direction.DOWN;
private TextureAtlasSprite sprite = UnitTextureAtlasSprite.INSTANCE;
private boolean shade;
private boolean hasAmbientOcclusion;

public QuadBakingVertexConsumer(Consumer<BakedQuad> quadConsumer)
{
Expand Down Expand Up @@ -127,7 +128,7 @@ public void endVertex()
if (++vertexIndex != 4)
return;
// We have a full quad, pass it to the consumer and reset
quadConsumer.accept(new BakedQuad(quadData, tintIndex, direction, sprite, shade));
quadConsumer.accept(new BakedQuad(quadData, tintIndex, direction, sprite, shade, hasAmbientOcclusion));
vertexIndex = 0;
quadData = new int[QUAD_DATA_SIZE];
}
Expand Down Expand Up @@ -161,4 +162,9 @@ public void setShade(boolean shade)
{
this.shade = shade;
}

public void setHasAmbientOcclusion(boolean hasAmbientOcclusion)
{
this.hasAmbientOcclusion = hasAmbientOcclusion;
}
}
3 changes: 2 additions & 1 deletion src/main/resources/forge.exc
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ net/minecraft/client/renderer/block/ModelBlockRenderer.renderModel(Lcom/mojang/b
net/minecraft/client/renderer/block/ModelBlockRenderer.tesselateBlock(Lnet/minecraft/world/level/BlockAndTintGetter;Lnet/minecraft/client/resources/model/BakedModel;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/BlockPos;Lcom/mojang/blaze3d/vertex/PoseStack;Lcom/mojang/blaze3d/vertex/VertexConsumer;ZLnet/minecraft/util/RandomSource;JILnet/minecraftforge/client/model/data/ModelData;Lnet/minecraft/client/renderer/RenderType;)V=|p_111048_,p_111049_,p_111050_,p_111051_,p_111052_,p_111053_,p_111054_,p_111055_,p_111056_,p_111057_,modelData,renderType
net/minecraft/client/renderer/block/ModelBlockRenderer.tesselateWithAO(Lnet/minecraft/world/level/BlockAndTintGetter;Lnet/minecraft/client/resources/model/BakedModel;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/BlockPos;Lcom/mojang/blaze3d/vertex/PoseStack;Lcom/mojang/blaze3d/vertex/VertexConsumer;ZLnet/minecraft/util/RandomSource;JILnet/minecraftforge/client/model/data/ModelData;Lnet/minecraft/client/renderer/RenderType;)V=|p_111079_,p_111080_,p_111081_,p_111082_,p_111083_,p_111084_,p_111085_,p_111086_,p_111087_,p_111088_,modelData,renderType
net/minecraft/client/renderer/block/ModelBlockRenderer.tesselateWithoutAO(Lnet/minecraft/world/level/BlockAndTintGetter;Lnet/minecraft/client/resources/model/BakedModel;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/BlockPos;Lcom/mojang/blaze3d/vertex/PoseStack;Lcom/mojang/blaze3d/vertex/VertexConsumer;ZLnet/minecraft/util/RandomSource;JILnet/minecraftforge/client/model/data/ModelData;Lnet/minecraft/client/renderer/RenderType;)V=|p_111091_,p_111092_,p_111093_,p_111094_,p_111095_,p_111096_,p_111097_,p_111098_,p_111099_,p_111100_,modelData,renderType
net/minecraft/client/renderer/block/model/BlockElementFace.<init>(Lnet/minecraft/core/Direction;ILjava/lang/String;Lnet/minecraft/client/renderer/block/model/BlockFaceUV;I)V=|p_111359_,p_111360_,p_111361_,p_111362_,emissivity
net/minecraft/client/renderer/block/model/BakedQuad.<init>([IILnet/minecraft/core/Direction;Lnet/minecraft/client/renderer/texture/TextureAtlasSprite;ZZ)V=|p_111298_,p_111299_,p_111300_,p_111301_,p_111302_,hasAmbientOcclusion
net/minecraft/client/renderer/block/model/BlockElementFace.<init>(Lnet/minecraft/core/Direction;ILjava/lang/String;Lnet/minecraft/client/renderer/block/model/BlockFaceUV;IZ)V=|p_111359_,p_111360_,p_111361_,p_111362_,emissivity,hasAmbientOcclusion
net/minecraft/client/renderer/block/model/BlockModel.bakeVanilla(Lnet/minecraft/client/resources/model/ModelBakery;Lnet/minecraft/client/renderer/block/model/BlockModel;Ljava/util/function/Function;Lnet/minecraft/client/resources/model/ModelState;Lnet/minecraft/resources/ResourceLocation;ZLnet/minecraftforge/client/RenderTypeGroup;)Lnet/minecraft/client/resources/model/BakedModel;=|p_111450_,p_111451_,p_111452_,p_111453_,p_111454_,p_111455_,renderTypes
net/minecraft/client/renderer/block/model/ItemTransform.<init>(Lcom/mojang/math/Vector3f;Lcom/mojang/math/Vector3f;Lcom/mojang/math/Vector3f;Lcom/mojang/math/Vector3f;)V=|p_111760_,p_111761_,p_111762_,rightRotation
net/minecraft/client/renderer/block/model/ItemTransforms.<init>(Lnet/minecraft/client/renderer/block/model/ItemTransform;Lnet/minecraft/client/renderer/block/model/ItemTransform;Lnet/minecraft/client/renderer/block/model/ItemTransform;Lnet/minecraft/client/renderer/block/model/ItemTransform;Lnet/minecraft/client/renderer/block/model/ItemTransform;Lnet/minecraft/client/renderer/block/model/ItemTransform;Lnet/minecraft/client/renderer/block/model/ItemTransform;Lnet/minecraft/client/renderer/block/model/ItemTransform;Lcom/google/common/collect/ImmutableMap;)V=|p_111798_,p_111799_,p_111800_,p_111801_,p_111802_,p_111803_,p_111804_,p_111805_,moddedTransforms
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (c) Forge Development LLC and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/

package net.minecraftforge.debug.client;

import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.material.Material;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;

/**
* Test mod that demos disabling ambient occlusion on specific faces of "elements" models.
*/
@Mod(AmbientOcclusionElementsTest.MOD_ID)
public class AmbientOcclusionElementsTest
{
public static final String MOD_ID = "ambient_occlusion_elements_test";
private static final DeferredRegister<Block> BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MOD_ID);
private static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, MOD_ID);

public static final RegistryObject<Block> AO_BLOCK_SHADE = BLOCKS.register("ambient_occlusion_shade", () -> new Block(BlockBehaviour.Properties.of(Material.STONE)));
public static final RegistryObject<Block> AO_BLOCK_NO_SHADE = BLOCKS.register("ambient_occlusion_no_shade", () -> new Block(BlockBehaviour.Properties.of(Material.STONE)));
public static final RegistryObject<Block> NO_AO_BLOCK_SHADE = BLOCKS.register("no_ambient_occlusion_shade", () -> new Block(BlockBehaviour.Properties.of(Material.STONE)));
public static final RegistryObject<Block> NO_AO_BLOCK_NO_SHADE = BLOCKS.register("no_ambient_occlusion_no_shade", () -> new Block(BlockBehaviour.Properties.of(Material.STONE)));
public static final RegistryObject<Item> AO_BLOCK_SHADE_ITEM = ITEMS.register("ambient_occlusion_shade", () -> new BlockItem(AO_BLOCK_SHADE.get(), new Item.Properties().tab(CreativeModeTab.TAB_DECORATIONS)));
public static final RegistryObject<Item> AO_BLOCK_NO_SHADE_ITEM = ITEMS.register("ambient_occlusion_no_shade", () -> new BlockItem(AO_BLOCK_NO_SHADE.get(), new Item.Properties().tab(CreativeModeTab.TAB_DECORATIONS)));
public static final RegistryObject<Item> NO_AO_BLOCK_SHADE_ITEM = ITEMS.register("no_ambient_occlusion_shade", () -> new BlockItem(NO_AO_BLOCK_SHADE.get(), new Item.Properties().tab(CreativeModeTab.TAB_DECORATIONS)));
public static final RegistryObject<Item> NO_AO_BLOCK_NO_SHADE_ITEM = ITEMS.register("no_ambient_occlusion_no_shade", () -> new BlockItem(NO_AO_BLOCK_NO_SHADE.get(), new Item.Properties().tab(CreativeModeTab.TAB_DECORATIONS)));

public AmbientOcclusionElementsTest()
{
IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
BLOCKS.register(modEventBus);
ITEMS.register(modEventBus);
}
}
2 changes: 2 additions & 0 deletions src/test/resources/META-INF/mods.toml
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,8 @@ modId="item_use_animation_test"
modId="custom_color_resolver_test"
[[mods]]
modId="custom_item_decorations_test"
[[mods]]
modId="ambient_occlusion_elements_test"


# ADD ABOVE THIS LINE
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"variants": {
"": { "model": "ambient_occlusion_elements_test:block/ambient_occlusion_no_shade" }
}
}
Loading

0 comments on commit e0477f8

Please sign in to comment.