mirror of
https://github.com/GTNewHorizons/Angelica.git
synced 2026-11-08 12:35:01 +00:00
Fix Chisel energised voidstone missing its border corners (#2254)
Fixes #2246
This commit is contained in:
1 parent
85d0641a73
commit
0cae2be1f6
4 files changed
+227
-37
No files matched your search
@@ -7,7 +7,7 @@ asmCompile = "5.0.3"
|
||||
launchwrapper = "1.12"
|
||||
# End Frozen
|
||||
|
||||
lwjgl3 = "3.4.2-SNAPSHOT"
|
||||
lwjgl3 = "3.4.2"
|
||||
# Must equal the LWJGL release shipped by lwjgl3ify. Do not bump without bumping lwjgl3ify.
|
||||
lwjgl3Release = "3.4.2"
|
||||
lwjgl3ify = "3.0.31"
|
||||
|
||||
+3
-36
@@ -36,7 +36,6 @@ import org.embeddedt.embeddium.impl.render.chunk.RenderPassConfiguration;
|
||||
import org.embeddedt.embeddium.impl.render.chunk.compile.ChunkBuildBuffers;
|
||||
import org.embeddedt.embeddium.impl.render.chunk.compile.ChunkBuildContext;
|
||||
import org.embeddedt.embeddium.impl.render.chunk.data.MinecraftBuiltRenderSectionData;
|
||||
import org.embeddedt.embeddium.impl.render.chunk.sprite.SpriteTransparencyLevel;
|
||||
import org.embeddedt.embeddium.impl.render.chunk.terrain.material.Material;
|
||||
import org.embeddedt.embeddium.impl.render.chunk.vertex.format.ChunkVertexEncoder;
|
||||
import org.embeddedt.embeddium.impl.util.QuadUtil;
|
||||
@@ -62,6 +61,7 @@ public class AngelicaChunkBuildContext extends ChunkBuildContext {
|
||||
@Getter private final FloatArrayList teBoundsScratch = new FloatArrayList();
|
||||
@Getter private final long[] deferredMask = new long[64];
|
||||
private final VertexArrayQuadView quadView;
|
||||
private final QuadMaterialSelector materialSelector = new QuadMaterialSelector();
|
||||
private final boolean hasColoredLight;
|
||||
private final float[] tintResult = new float[3];
|
||||
private List<IDynamicLightSource> chunkLightSources;
|
||||
@@ -116,27 +116,6 @@ public class AngelicaChunkBuildContext extends ChunkBuildContext {
|
||||
}
|
||||
}
|
||||
|
||||
private Material selectMaterial(Material material, TextureAtlasSprite sprite, boolean isShaderPackOverride,
|
||||
boolean useRenderPassOptimization) {
|
||||
// Don't apply transparency-based optimization when shader pack explicitly overrides the material
|
||||
if (isShaderPackOverride) {
|
||||
return material;
|
||||
}
|
||||
|
||||
if (useRenderPassOptimization
|
||||
&& sprite != null && sprite.getClass() == TextureAtlasSprite.class && !sprite.hasAnimationMetadata()) {
|
||||
final var transparencyLevel = ((SpriteExtension) sprite).celeritas$getTransparencyLevel();
|
||||
if (transparencyLevel == SpriteTransparencyLevel.OPAQUE
|
||||
&& material == AngelicaRenderPassConfiguration.CUTOUT_MIPPED_MATERIAL) {
|
||||
return AngelicaRenderPassConfiguration.SOLID_MATERIAL;
|
||||
} else if (material == AngelicaRenderPassConfiguration.TRANSLUCENT_MATERIAL && transparencyLevel != SpriteTransparencyLevel.TRANSLUCENT) {
|
||||
return AngelicaRenderPassConfiguration.CUTOUT_MIPPED_MATERIAL;
|
||||
}
|
||||
}
|
||||
|
||||
return material;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void copyRawBuffer(int[] rawBuffer, int vertexCount, int[] vertexStates,
|
||||
int[] shaderOverrideBlockIds,
|
||||
@@ -174,9 +153,7 @@ public class AngelicaChunkBuildContext extends ChunkBuildContext {
|
||||
final short originalBlockId = blockRenderContext.blockId;
|
||||
|
||||
int stateIdx = 0;
|
||||
boolean hasCachedMaterial = false;
|
||||
TextureAtlasSprite lastSprite = null;
|
||||
Material lastMaterial = null;
|
||||
materialSelector.reset(material, isShaderPackOverride, useRenderPassOptimization);
|
||||
this.fluidQuadLightFace = null;
|
||||
|
||||
for (int quadIdx = 0; quadIdx < numQuads; quadIdx++) {
|
||||
@@ -266,17 +243,7 @@ public class AngelicaChunkBuildContext extends ChunkBuildContext {
|
||||
// Apply RGB block light tint from provider
|
||||
applyBlockLightTint(worldX, worldY, worldZ, vertices);
|
||||
|
||||
final Material correctMaterial;
|
||||
if (material == AngelicaRenderPassConfiguration.TRANSLUCENT_MATERIAL && hasVertexTransparency) {
|
||||
correctMaterial = material;
|
||||
} else if (hasCachedMaterial && sprite == lastSprite) {
|
||||
correctMaterial = lastMaterial;
|
||||
} else {
|
||||
correctMaterial = selectMaterial(material, sprite, isShaderPackOverride, useRenderPassOptimization);
|
||||
lastSprite = sprite;
|
||||
lastMaterial = correctMaterial;
|
||||
hasCachedMaterial = true;
|
||||
}
|
||||
final Material correctMaterial = materialSelector.select(facing, sprite, hasVertexTransparency);
|
||||
final var builder = buffers.get(correctMaterial);
|
||||
|
||||
final int shaderOverrideBlockId = shaderOverrideBlockIds[quadIdx * 4];
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package com.gtnewhorizons.angelica.rendering.celeritas;
|
||||
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import org.embeddedt.embeddium.impl.model.quad.properties.ModelQuadFacing;
|
||||
import org.embeddedt.embeddium.impl.render.chunk.sprite.SpriteTransparencyLevel;
|
||||
import org.embeddedt.embeddium.impl.render.chunk.terrain.material.Material;
|
||||
|
||||
class QuadMaterialSelector {
|
||||
private Material material;
|
||||
private boolean canDemote;
|
||||
private int facesAtBaseMaterial;
|
||||
private TextureAtlasSprite lastSprite;
|
||||
private Material lastMaterial;
|
||||
|
||||
void reset(Material material, boolean isShaderPackOverride, boolean useRenderPassOptimization) {
|
||||
this.material = material;
|
||||
// Don't apply transparency-based optimization when shader pack explicitly overrides the material
|
||||
this.canDemote = useRenderPassOptimization && !isShaderPackOverride;
|
||||
facesAtBaseMaterial = 0;
|
||||
lastMaterial = null;
|
||||
}
|
||||
|
||||
Material select(ModelQuadFacing facing, TextureAtlasSprite sprite, boolean hasVertexTransparency) {
|
||||
final int faceBit = 1 << facing.ordinal();
|
||||
final Material correctMaterial;
|
||||
if ((facesAtBaseMaterial & faceBit) != 0 || (material == AngelicaRenderPassConfiguration.TRANSLUCENT_MATERIAL && hasVertexTransparency)) {
|
||||
correctMaterial = material;
|
||||
} else if (lastMaterial != null && sprite == lastSprite) {
|
||||
correctMaterial = lastMaterial;
|
||||
} else {
|
||||
correctMaterial = demote(sprite);
|
||||
lastSprite = sprite;
|
||||
lastMaterial = correctMaterial;
|
||||
}
|
||||
if (correctMaterial == material) {
|
||||
facesAtBaseMaterial |= faceBit;
|
||||
}
|
||||
return correctMaterial;
|
||||
}
|
||||
|
||||
private Material demote(TextureAtlasSprite sprite) {
|
||||
if (canDemote && sprite != null && sprite.getClass() == TextureAtlasSprite.class && !sprite.hasAnimationMetadata()) {
|
||||
final var transparencyLevel = transparencyLevel(sprite);
|
||||
if (transparencyLevel == SpriteTransparencyLevel.OPAQUE && material == AngelicaRenderPassConfiguration.CUTOUT_MIPPED_MATERIAL) {
|
||||
return AngelicaRenderPassConfiguration.SOLID_MATERIAL;
|
||||
} else if (material == AngelicaRenderPassConfiguration.TRANSLUCENT_MATERIAL && transparencyLevel != SpriteTransparencyLevel.TRANSLUCENT) {
|
||||
return AngelicaRenderPassConfiguration.CUTOUT_MIPPED_MATERIAL;
|
||||
}
|
||||
}
|
||||
|
||||
return material;
|
||||
}
|
||||
|
||||
SpriteTransparencyLevel transparencyLevel(TextureAtlasSprite sprite) {
|
||||
return ((SpriteExtension) sprite).celeritas$getTransparencyLevel();
|
||||
}
|
||||
}
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
package com.gtnewhorizons.angelica.rendering.celeritas;
|
||||
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.resources.data.AnimationMetadataSection;
|
||||
import org.embeddedt.embeddium.impl.model.quad.properties.ModelQuadFacing;
|
||||
import org.embeddedt.embeddium.impl.render.chunk.compile.sorting.QuadPrimitiveType;
|
||||
import org.embeddedt.embeddium.impl.render.chunk.sprite.SpriteTransparencyLevel;
|
||||
import org.embeddedt.embeddium.impl.render.chunk.terrain.TerrainRenderPass;
|
||||
import org.embeddedt.embeddium.impl.render.chunk.terrain.material.Material;
|
||||
import org.embeddedt.embeddium.impl.render.chunk.terrain.material.parameters.AlphaCutoffParameter;
|
||||
import org.embeddedt.embeddium.impl.render.chunk.vertex.format.ChunkMeshFormats;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
|
||||
class QuadMaterialSelectorTest {
|
||||
|
||||
private final Material[] previous = new Material[3];
|
||||
private final Map<TextureAtlasSprite, SpriteTransparencyLevel> levels = new IdentityHashMap<>();
|
||||
private final QuadMaterialSelector selector = new QuadMaterialSelector() {
|
||||
@Override
|
||||
SpriteTransparencyLevel transparencyLevel(TextureAtlasSprite sprite) {
|
||||
return levels.get(sprite);
|
||||
}
|
||||
};
|
||||
|
||||
private Material solid;
|
||||
private Material cutout;
|
||||
private Material translucent;
|
||||
|
||||
@BeforeEach
|
||||
void installMaterials() {
|
||||
previous[0] = AngelicaRenderPassConfiguration.SOLID_MATERIAL;
|
||||
previous[1] = AngelicaRenderPassConfiguration.CUTOUT_MIPPED_MATERIAL;
|
||||
previous[2] = AngelicaRenderPassConfiguration.TRANSLUCENT_MATERIAL;
|
||||
|
||||
solid = new Material(pass("solid", false), AlphaCutoffParameter.ZERO, true);
|
||||
cutout = new Material(pass("cutout_mipped", true), AlphaCutoffParameter.HALF, true);
|
||||
translucent = new Material(pass("translucent", false), AlphaCutoffParameter.ZERO, true);
|
||||
|
||||
AngelicaRenderPassConfiguration.SOLID_MATERIAL = solid;
|
||||
AngelicaRenderPassConfiguration.CUTOUT_MIPPED_MATERIAL = cutout;
|
||||
AngelicaRenderPassConfiguration.TRANSLUCENT_MATERIAL = translucent;
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void restoreMaterials() {
|
||||
AngelicaRenderPassConfiguration.SOLID_MATERIAL = previous[0];
|
||||
AngelicaRenderPassConfiguration.CUTOUT_MIPPED_MATERIAL = previous[1];
|
||||
AngelicaRenderPassConfiguration.TRANSLUCENT_MATERIAL = previous[2];
|
||||
}
|
||||
|
||||
private static TerrainRenderPass pass(String name, boolean fragmentDiscard) {
|
||||
return new TerrainRenderPass(name, null, false, fragmentDiscard, false, false, ChunkMeshFormats.VANILLA_LIKE, QuadPrimitiveType.TRIANGULATED, Map.of());
|
||||
}
|
||||
|
||||
private TextureAtlasSprite sprite(String name, SpriteTransparencyLevel level) {
|
||||
final TextureAtlasSprite sprite = new TextureAtlasSprite(name);
|
||||
levels.put(sprite, level);
|
||||
return sprite;
|
||||
}
|
||||
|
||||
private TextureAtlasSprite animated(String name) {
|
||||
final TextureAtlasSprite sprite = sprite(name, SpriteTransparencyLevel.OPAQUE);
|
||||
sprite.animationMetadata = new AnimationMetadataSection(new ArrayList<>(), 16, 16, 1);
|
||||
return sprite;
|
||||
}
|
||||
|
||||
private TextureAtlasSprite custom(String name) {
|
||||
final TextureAtlasSprite sprite = new TextureAtlasSprite(name) {};
|
||||
levels.put(sprite, SpriteTransparencyLevel.OPAQUE);
|
||||
return sprite;
|
||||
}
|
||||
|
||||
private void begin(Material material) {
|
||||
selector.reset(material, false, true);
|
||||
}
|
||||
|
||||
private Material select(ModelQuadFacing facing, TextureAtlasSprite sprite) {
|
||||
return selector.select(facing, sprite, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
void opaqueOverlayStaysWithAnimatedBaseOnTheSameFace() {
|
||||
final TextureAtlasSprite base = animated("hadesX32");
|
||||
final TextureAtlasSprite corner = sprite("metalborder", SpriteTransparencyLevel.OPAQUE);
|
||||
final TextureAtlasSprite edge = sprite("metalborder-ctm", SpriteTransparencyLevel.TRANSPARENT);
|
||||
|
||||
begin(cutout);
|
||||
assertSame(cutout, select(ModelQuadFacing.POS_Z, base));
|
||||
assertSame(cutout, select(ModelQuadFacing.POS_Z, corner));
|
||||
assertSame(cutout, select(ModelQuadFacing.POS_Z, edge));
|
||||
assertSame(cutout, select(ModelQuadFacing.POS_Z, corner));
|
||||
}
|
||||
|
||||
@Test
|
||||
void cachedDemotionDoesNotLeakOntoAFaceWithABase() {
|
||||
final TextureAtlasSprite base = animated("hadesX32");
|
||||
final TextureAtlasSprite corner = sprite("metalborder", SpriteTransparencyLevel.OPAQUE);
|
||||
|
||||
begin(cutout);
|
||||
assertSame(solid, select(ModelQuadFacing.POS_X, corner));
|
||||
assertSame(cutout, select(ModelQuadFacing.POS_Z, base));
|
||||
assertSame(cutout, select(ModelQuadFacing.POS_Z, corner));
|
||||
assertSame(solid, select(ModelQuadFacing.POS_X, corner));
|
||||
}
|
||||
|
||||
@Test
|
||||
void opaqueOnlyFacesAreStillDemoted() {
|
||||
final TextureAtlasSprite stone = sprite("stone", SpriteTransparencyLevel.OPAQUE);
|
||||
|
||||
begin(cutout);
|
||||
for (ModelQuadFacing facing : ModelQuadFacing.VALUES) {
|
||||
assertSame(solid, select(facing, stone));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void vertexAlphaKeepsTranslucentAndPinsTheFace() {
|
||||
final TextureAtlasSprite frame = sprite("frame", SpriteTransparencyLevel.TRANSPARENT);
|
||||
|
||||
begin(translucent);
|
||||
assertSame(cutout, select(ModelQuadFacing.NEG_Y, frame));
|
||||
assertSame(translucent, selector.select(ModelQuadFacing.POS_Y, frame, true));
|
||||
assertSame(translucent, select(ModelQuadFacing.POS_Y, frame));
|
||||
assertSame(cutout, select(ModelQuadFacing.NEG_Y, frame));
|
||||
}
|
||||
|
||||
@Test
|
||||
void undemotableSpritesKeepTheBaseMaterial() {
|
||||
begin(cutout);
|
||||
assertSame(cutout, select(ModelQuadFacing.POS_X, null));
|
||||
assertSame(cutout, select(ModelQuadFacing.POS_Y, animated("animated")));
|
||||
assertSame(cutout, select(ModelQuadFacing.POS_Z, custom("custom")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shaderPackOverrideAndDisabledOptimizationKeepTheBaseMaterial() {
|
||||
final TextureAtlasSprite stone = sprite("stone", SpriteTransparencyLevel.OPAQUE);
|
||||
|
||||
selector.reset(cutout, true, true);
|
||||
assertSame(cutout, select(ModelQuadFacing.POS_X, stone));
|
||||
selector.reset(cutout, false, false);
|
||||
assertSame(cutout, select(ModelQuadFacing.POS_X, stone));
|
||||
}
|
||||
|
||||
@Test
|
||||
void resetReleasesPinnedFacesAndTheSpriteCache() {
|
||||
final TextureAtlasSprite base = animated("hadesX32");
|
||||
final TextureAtlasSprite corner = sprite("metalborder", SpriteTransparencyLevel.OPAQUE);
|
||||
|
||||
begin(cutout);
|
||||
assertSame(cutout, select(ModelQuadFacing.POS_Z, base));
|
||||
assertSame(cutout, select(ModelQuadFacing.POS_Z, corner));
|
||||
assertSame(solid, select(ModelQuadFacing.NEG_Z, corner));
|
||||
|
||||
begin(translucent);
|
||||
assertSame(cutout, select(ModelQuadFacing.POS_Z, corner));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user