From b05f5a728f9d296d07be07ff68d17a64c2b31478 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Sun, 1 Aug 2021 14:05:41 +0300 Subject: [PATCH] Compat with Canvas emissive shaders, fixes --- .../java/ru/bclib/api/ModIntegrationAPI.java | 6 ++ .../java/ru/bclib/client/BCLibClient.java | 1 - .../bclib/client/models/CustomModelData.java | 23 ++++++++ .../client/render/EmissiveTextureInfo.java | 32 ++++++++++ .../bclib/mixin/client/ModelBakeryMixin.java | 56 +++++++++++++++++- .../SimpleReloadableResourceManagerMixin.java | 59 +++++++++++++++++++ .../bclib/mixin/client/TextureAtlasMixin.java | 5 ++ .../materialmaps/block/alpha_emission.json | 3 + .../bclib/materials/alpha_emission.json | 8 +++ .../shaders/material/alpha_emission.frag | 14 +++++ .../shaders/core/rendertype_cutout.fsh | 1 + .../shaders/core/rendertype_entity_cutout.fsh | 3 +- ...endertype_item_entity_translucent_cull.fsh | 3 +- .../shaders/core/rendertype_solid.fsh | 1 + src/main/resources/bclib.mixins.client.json | 1 + 15 files changed, 210 insertions(+), 6 deletions(-) create mode 100644 src/main/java/ru/bclib/client/models/CustomModelData.java create mode 100644 src/main/java/ru/bclib/client/render/EmissiveTextureInfo.java create mode 100644 src/main/java/ru/bclib/mixin/client/SimpleReloadableResourceManagerMixin.java create mode 100644 src/main/resources/assets/bclib/materialmaps/block/alpha_emission.json create mode 100644 src/main/resources/assets/bclib/materials/alpha_emission.json create mode 100644 src/main/resources/assets/bclib/shaders/material/alpha_emission.frag diff --git a/src/main/java/ru/bclib/api/ModIntegrationAPI.java b/src/main/java/ru/bclib/api/ModIntegrationAPI.java index 5c6b186c..b36eec68 100644 --- a/src/main/java/ru/bclib/api/ModIntegrationAPI.java +++ b/src/main/java/ru/bclib/api/ModIntegrationAPI.java @@ -1,12 +1,14 @@ package ru.bclib.api; import com.google.common.collect.Lists; +import net.fabricmc.loader.api.FabricLoader; import ru.bclib.integration.ModIntegration; import java.util.List; public class ModIntegrationAPI { private static final List INTEGRATIONS = Lists.newArrayList(); + private static final boolean HAS_CANVAS = FabricLoader.getInstance().isModLoaded("canvas"); /** * Registers mod integration @@ -38,4 +40,8 @@ public class ModIntegrationAPI { } }); } + + public static boolean hasCanvas() { + return HAS_CANVAS; + } } diff --git a/src/main/java/ru/bclib/client/BCLibClient.java b/src/main/java/ru/bclib/client/BCLibClient.java index ff803130..55f7c945 100644 --- a/src/main/java/ru/bclib/client/BCLibClient.java +++ b/src/main/java/ru/bclib/client/BCLibClient.java @@ -12,7 +12,6 @@ public class BCLibClient implements ClientModInitializer { ModIntegrationAPI.registerAll(); BaseBlockEntityRenders.register(); DataExchangeAPI.prepareClientside(); - PostInitAPI.postInit(true); } } diff --git a/src/main/java/ru/bclib/client/models/CustomModelData.java b/src/main/java/ru/bclib/client/models/CustomModelData.java new file mode 100644 index 00000000..0fcf50f9 --- /dev/null +++ b/src/main/java/ru/bclib/client/models/CustomModelData.java @@ -0,0 +1,23 @@ +package ru.bclib.client.models; + +import com.google.common.collect.Sets; +import net.minecraft.resources.ResourceLocation; + +import java.util.Set; + +public class CustomModelData { + private static final Set TRANSPARENT_EMISSION = Sets.newConcurrentHashSet(); + + public static void clear() { + TRANSPARENT_EMISSION.clear(); + } + + public static void addTransparent(ResourceLocation blockID) { + TRANSPARENT_EMISSION.add(blockID); + } + + public static boolean isTransparentEmissive(ResourceLocation rawLocation) { + String name = rawLocation.getPath().replace("materialmaps/block/", "").replace(".json", ""); + return TRANSPARENT_EMISSION.contains(new ResourceLocation(rawLocation.getNamespace(), name)); + } +} diff --git a/src/main/java/ru/bclib/client/render/EmissiveTextureInfo.java b/src/main/java/ru/bclib/client/render/EmissiveTextureInfo.java new file mode 100644 index 00000000..0623a9df --- /dev/null +++ b/src/main/java/ru/bclib/client/render/EmissiveTextureInfo.java @@ -0,0 +1,32 @@ +package ru.bclib.client.render; + +import com.google.common.collect.Sets; +import net.minecraft.resources.ResourceLocation; + +import java.util.Set; + +public class EmissiveTextureInfo { + private static final Set EMISSIVE_TEXTURES = Sets.newHashSet(); + private static final Set EMISSIVE_BLOCKS = Sets.newHashSet(); + + public static void clear() { + EMISSIVE_TEXTURES.clear(); + EMISSIVE_BLOCKS.clear(); + } + + public static void addTexture(ResourceLocation texture) { + EMISSIVE_TEXTURES.add(texture); + } + + public static void addBlock(ResourceLocation blockID) { + EMISSIVE_BLOCKS.add(blockID); + } + + public static boolean isEmissiveTexture(ResourceLocation texture) { + return EMISSIVE_TEXTURES.contains(texture); + } + + public static boolean isEmissiveBlock(ResourceLocation blockID) { + return EMISSIVE_BLOCKS.contains(blockID); + } +} diff --git a/src/main/java/ru/bclib/mixin/client/ModelBakeryMixin.java b/src/main/java/ru/bclib/mixin/client/ModelBakeryMixin.java index 1f1406ed..6b97d8ff 100644 --- a/src/main/java/ru/bclib/mixin/client/ModelBakeryMixin.java +++ b/src/main/java/ru/bclib/mixin/client/ModelBakeryMixin.java @@ -2,10 +2,13 @@ package ru.bclib.mixin.client; import com.google.common.collect.ImmutableList; import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.mojang.datafixers.util.Pair; import net.minecraft.client.color.block.BlockColors; import net.minecraft.client.renderer.block.BlockModelShaper; import net.minecraft.client.renderer.block.model.BlockModel; import net.minecraft.client.renderer.block.model.multipart.MultiPart; +import net.minecraft.client.resources.model.Material; import net.minecraft.client.resources.model.ModelBakery; import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.client.resources.model.UnbakedModel; @@ -14,6 +17,7 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.util.profiling.ProfilerFiller; import net.minecraft.world.item.Items; +import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -22,9 +26,13 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At.Shift; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import ru.bclib.api.ModIntegrationAPI; +import ru.bclib.client.render.EmissiveTextureInfo; import ru.bclib.interfaces.BlockModelProvider; import ru.bclib.interfaces.ItemModelProvider; +import java.util.Collection; +import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -68,13 +76,15 @@ public abstract class ModelBakeryMixin { if (defaultModel instanceof MultiPart) { states.forEach(blockState -> { ResourceLocation stateID = BlockModelShaper.stateToModelLocation(blockID, blockState); + topLevel.put(stateID, defaultModel); cache.put(stateID, defaultModel); }); } else { states.forEach(blockState -> { ResourceLocation stateID = BlockModelShaper.stateToModelLocation(blockID, blockState); - UnbakedModel model = provider.getModelVariant(stateID, blockState, cache); + UnbakedModel model = stateID.equals(defaultStateID) ? defaultModel : provider.getModelVariant(stateID, blockState, cache); + topLevel.put(stateID, model); cache.put(stateID, model); }); } @@ -85,8 +95,8 @@ public abstract class ModelBakeryMixin { if (!resourceManager.hasResource(storageID)) { ResourceLocation itemID = new ModelResourceLocation(blockID.getNamespace(), blockID.getPath(), "inventory"); BlockModel model = provider.getItemModel(itemID); - cache.put(itemID, model); topLevel.put(itemID, model); + cache.put(itemID, model); } } }); @@ -98,8 +108,8 @@ public abstract class ModelBakeryMixin { ResourceLocation itemID = new ModelResourceLocation(registryID.getNamespace(), registryID.getPath(), "inventory"); ItemModelProvider provider = (ItemModelProvider) item; BlockModel model = provider.getItemModel(registryID); - cache.put(itemID, model); topLevel.put(itemID, model); + cache.put(itemID, model); } }); @@ -110,4 +120,44 @@ public abstract class ModelBakeryMixin { topLevelModels.putAll(topLevel); unbakedCache.putAll(cache); } + + @Inject(method = "*", at = @At("TAIL")) + private void bclib_findEmissiveModels(ResourceManager resourceManager, BlockColors blockColors, ProfilerFiller profiler, int mipmap, CallbackInfo info) { + if (!ModIntegrationAPI.hasCanvas()) { + return; + } + + Map cacheCopy = new HashMap<>(unbakedCache); + Set> strings = Sets.newConcurrentHashSet(); + Registry.BLOCK.keySet().forEach(blockID -> { + Block block = Registry.BLOCK.get(blockID); + ImmutableList states = block.getStateDefinition().getPossibleStates(); + boolean addBlock = false; + + for (BlockState state: states) { + ResourceLocation stateID = BlockModelShaper.stateToModelLocation(blockID, state); + UnbakedModel model = cacheCopy.get(stateID); + if (model == null) { + continue; + } + Collection materials = model.getMaterials(cacheCopy::get, strings); + if (materials == null) { + continue; + } + for (Material material: materials) { + if (EmissiveTextureInfo.isEmissiveTexture(material.texture())) { + addBlock = true; + break; + } + } + if (addBlock) { + break; + } + } + + if (addBlock) { + EmissiveTextureInfo.addBlock(blockID); + } + }); + } } diff --git a/src/main/java/ru/bclib/mixin/client/SimpleReloadableResourceManagerMixin.java b/src/main/java/ru/bclib/mixin/client/SimpleReloadableResourceManagerMixin.java new file mode 100644 index 00000000..8fd47ccc --- /dev/null +++ b/src/main/java/ru/bclib/mixin/client/SimpleReloadableResourceManagerMixin.java @@ -0,0 +1,59 @@ +package ru.bclib.mixin.client; + +import net.minecraft.client.Minecraft; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.packs.PackType; +import net.minecraft.server.packs.resources.FallbackResourceManager; +import net.minecraft.server.packs.resources.Resource; +import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraft.server.packs.resources.SimpleReloadableResourceManager; +import net.minecraft.server.packs.resources.SimpleResource; +import org.spongepowered.asm.mixin.Final; +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.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import ru.bclib.BCLib; +import ru.bclib.api.ModIntegrationAPI; +import ru.bclib.client.render.EmissiveTextureInfo; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; + +@Mixin(SimpleReloadableResourceManager.class) +public class SimpleReloadableResourceManagerMixin { + @Final + @Shadow + private Map namespacedPacks; + + private Resource bclib_alphaEmissionMaterial; + + @Inject(method = "getResource", at = @At("HEAD"), cancellable = true) + private void bclib_getResource(ResourceLocation resourceLocation, CallbackInfoReturnable info) throws IOException { + if (!ModIntegrationAPI.hasCanvas()) { + return; + } + if (!resourceLocation.getPath().startsWith("materialmaps")) { + return; + } + if (!resourceLocation.getPath().contains("/block/")) { + return; + } + + String name = resourceLocation.getPath().replace("materialmaps/block/", "").replace(".json", ""); + ResourceLocation blockID = new ResourceLocation(resourceLocation.getNamespace(), name); + + if (!EmissiveTextureInfo.isEmissiveBlock(blockID)) { + return; + } + + ResourceManager resourceManager = this.namespacedPacks.get(resourceLocation.getNamespace()); + if (resourceManager != null) { + resourceLocation = BCLib.makeID("materialmaps/block/alpha_emission.json"); + info.setReturnValue(resourceManager.getResource(resourceLocation)); + } + } +} diff --git a/src/main/java/ru/bclib/mixin/client/TextureAtlasMixin.java b/src/main/java/ru/bclib/mixin/client/TextureAtlasMixin.java index a723c4ab..2b2bbff2 100644 --- a/src/main/java/ru/bclib/mixin/client/TextureAtlasMixin.java +++ b/src/main/java/ru/bclib/mixin/client/TextureAtlasMixin.java @@ -14,6 +14,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import ru.bclib.BCLib; +import ru.bclib.client.render.EmissiveTextureInfo; import java.io.IOException; @@ -26,6 +27,9 @@ public class TextureAtlasMixin { private void bclib_onAtlasInit(ResourceLocation resourceLocation, CallbackInfo info) { boolean hasOptifine = FabricLoader.getInstance().isModLoaded("optifabric"); bclib_modifyAtlas = !hasOptifine && resourceLocation.toString().equals("minecraft:textures/atlas/blocks.png"); + if (bclib_modifyAtlas) { + EmissiveTextureInfo.clear(); + } } @Inject(method = "load(Lnet/minecraft/server/packs/resources/ResourceManager;Lnet/minecraft/client/renderer/texture/TextureAtlasSprite$Info;IIIII)Lnet/minecraft/client/renderer/texture/TextureAtlasSprite;", at = @At("HEAD"), cancellable = true) @@ -91,6 +95,7 @@ public class TextureAtlasMixin { posY, sprite ); + EmissiveTextureInfo.addTexture(location); info.setReturnValue(result); } } diff --git a/src/main/resources/assets/bclib/materialmaps/block/alpha_emission.json b/src/main/resources/assets/bclib/materialmaps/block/alpha_emission.json new file mode 100644 index 00000000..ae85105c --- /dev/null +++ b/src/main/resources/assets/bclib/materialmaps/block/alpha_emission.json @@ -0,0 +1,3 @@ +{ + "defaultMaterial": "bclib:alpha_emission" +} diff --git a/src/main/resources/assets/bclib/materials/alpha_emission.json b/src/main/resources/assets/bclib/materials/alpha_emission.json new file mode 100644 index 00000000..914848b1 --- /dev/null +++ b/src/main/resources/assets/bclib/materials/alpha_emission.json @@ -0,0 +1,8 @@ +{ + "layers": [ + { + "vertexSource": "canvas:shaders/material/default.vert", + "fragmentSource": "bclib:shaders/material/alpha_emission.frag" + } + ] +} diff --git a/src/main/resources/assets/bclib/shaders/material/alpha_emission.frag b/src/main/resources/assets/bclib/shaders/material/alpha_emission.frag new file mode 100644 index 00000000..32ae9482 --- /dev/null +++ b/src/main/resources/assets/bclib/shaders/material/alpha_emission.frag @@ -0,0 +1,14 @@ +#include frex:shaders/api/fragment.glsl +#include frex:shaders/lib/math.glsl + +// Value near 254 +bool isEmissive(float alpha) { + return 0.9960 < alpha && alpha < 0.9962; +} + +void frx_startFragment(inout frx_FragmentData fragData) { + if (isEmissive(fragData.spriteColor.a)) { + fragData.emissivity = 1.0; + fragData.spriteColor.a = 1.0; + } +} diff --git a/src/main/resources/assets/minecraft/shaders/core/rendertype_cutout.fsh b/src/main/resources/assets/minecraft/shaders/core/rendertype_cutout.fsh index 263c0eaf..c14819e8 100644 --- a/src/main/resources/assets/minecraft/shaders/core/rendertype_cutout.fsh +++ b/src/main/resources/assets/minecraft/shaders/core/rendertype_cutout.fsh @@ -11,6 +11,7 @@ uniform vec4 FogColor; in float vertexDistance; in vec4 vertexColor; in vec2 texCoord0; +in vec4 normal; out vec4 fragColor; diff --git a/src/main/resources/assets/minecraft/shaders/core/rendertype_entity_cutout.fsh b/src/main/resources/assets/minecraft/shaders/core/rendertype_entity_cutout.fsh index fffb8d92..3e3e352f 100644 --- a/src/main/resources/assets/minecraft/shaders/core/rendertype_entity_cutout.fsh +++ b/src/main/resources/assets/minecraft/shaders/core/rendertype_entity_cutout.fsh @@ -9,10 +9,11 @@ uniform float FogEnd; uniform vec4 FogColor; in float vertexDistance; +in vec4 vertexColor; in vec4 lightMapColor; in vec4 overlayColor; -in vec4 vertexColor; in vec2 texCoord0; +in vec4 normal; out vec4 fragColor; diff --git a/src/main/resources/assets/minecraft/shaders/core/rendertype_item_entity_translucent_cull.fsh b/src/main/resources/assets/minecraft/shaders/core/rendertype_item_entity_translucent_cull.fsh index 62aeda6b..a2434029 100644 --- a/src/main/resources/assets/minecraft/shaders/core/rendertype_item_entity_translucent_cull.fsh +++ b/src/main/resources/assets/minecraft/shaders/core/rendertype_item_entity_translucent_cull.fsh @@ -11,7 +11,8 @@ uniform vec4 FogColor; in float vertexDistance; in vec4 vertexColor; in vec2 texCoord0; -in vec4 overlayColor; +in vec2 texCoord1; +in vec4 normal; out vec4 fragColor; diff --git a/src/main/resources/assets/minecraft/shaders/core/rendertype_solid.fsh b/src/main/resources/assets/minecraft/shaders/core/rendertype_solid.fsh index ade71952..95c1a52f 100644 --- a/src/main/resources/assets/minecraft/shaders/core/rendertype_solid.fsh +++ b/src/main/resources/assets/minecraft/shaders/core/rendertype_solid.fsh @@ -11,6 +11,7 @@ uniform vec4 FogColor; in float vertexDistance; in vec4 vertexColor; in vec2 texCoord0; +in vec4 normal; out vec4 fragColor; diff --git a/src/main/resources/bclib.mixins.client.json b/src/main/resources/bclib.mixins.client.json index 267fb2fb..bf98b192 100644 --- a/src/main/resources/bclib.mixins.client.json +++ b/src/main/resources/bclib.mixins.client.json @@ -4,6 +4,7 @@ "package": "ru.bclib.mixin.client", "compatibilityLevel": "JAVA_16", "client": [ + "SimpleReloadableResourceManagerMixin", "EnchantingTableBlockMixin", "BackgroundRendererMixin", "TextureAtlasMixin",