diff --git a/src/main/java/ru/bclib/mixin/client/TextureAtlasMixin.java b/src/main/java/ru/bclib/mixin/client/TextureAtlasMixin.java index fc6ba619..bdf3204a 100644 --- a/src/main/java/ru/bclib/mixin/client/TextureAtlasMixin.java +++ b/src/main/java/ru/bclib/mixin/client/TextureAtlasMixin.java @@ -2,6 +2,7 @@ package ru.bclib.mixin.client; import com.mojang.blaze3d.platform.NativeImage; import net.fabricmc.fabric.impl.client.texture.FabricSprite; +import net.fabricmc.loader.api.FabricLoader; import net.minecraft.client.renderer.texture.TextureAtlas; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.resources.ResourceLocation; @@ -18,71 +19,79 @@ import java.io.IOException; @Mixin(TextureAtlas.class) public class TextureAtlasMixin { + private static final int EMISSIVE_ALPHA = 253 << 24; private boolean bclib_modifyAtlas; @Inject(method = "*", at = @At("TAIL")) private void bclib_onAtlasInit(ResourceLocation resourceLocation, CallbackInfo info) { - bclib_modifyAtlas = resourceLocation.toString().equals("minecraft:textures/atlas/blocks.png"); + boolean hasOptifine = FabricLoader.getInstance().isModLoaded("optifabric"); + bclib_modifyAtlas = !hasOptifine && resourceLocation.toString().equals("minecraft:textures/atlas/blocks.png"); } @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) private void bclib_loadSprite(ResourceManager resourceManager, TextureAtlasSprite.Info spriteInfo, int atlasWidth, int atlasHeight, int maxLevel, int posX, int posY, CallbackInfoReturnable info) { + if (!bclib_modifyAtlas) { + return; + } + ResourceLocation location = spriteInfo.name(); - if (bclib_modifyAtlas && location.getPath().startsWith("block")) { - ResourceLocation emissiveLocation = new ResourceLocation( - location.getNamespace(), - "textures/" + location.getPath() + "_e.png" - ); - if (resourceManager.hasResource(emissiveLocation)) { - NativeImage sprite = null; - NativeImage emission = null; - try { - ResourceLocation spriteLocation = new ResourceLocation( - location.getNamespace(), - "textures/" + location.getPath() + ".png" - ); - Resource resource = resourceManager.getResource(spriteLocation); - sprite = NativeImage.read(resource.getInputStream()); - resource.close(); - - resource = resourceManager.getResource(emissiveLocation); - emission = NativeImage.read(resource.getInputStream()); - resource.close(); - } - catch (IOException e) { - BCLib.LOGGER.warning(e.getMessage()); - } - if (sprite != null && emission != null) { - int width = Math.min(sprite.getWidth(), emission.getWidth()); - int height = Math.min(sprite.getHeight(), emission.getHeight()); - for (int x = 0; x < width; x++) { - for (int y = 0; y < height; y++) { - int argb = emission.getPixelRGBA(x, y); - int alpha = (argb >> 24) & 255; - if (alpha > 127) { - int r = (argb >> 16) & 255; - int g = (argb >> 8) & 255; - int b = argb & 255; - if (r > 0 || g > 0 || b > 0) { - argb = (argb & 0x00FFFFFF) | (250 << 24); - sprite.setPixelRGBA(x, y, argb); - } + if (!location.getPath().startsWith("block")) { + return; + } + + ResourceLocation emissiveLocation = new ResourceLocation( + location.getNamespace(), + "textures/" + location.getPath() + "_e.png" + ); + if (resourceManager.hasResource(emissiveLocation)) { + NativeImage sprite = null; + NativeImage emission = null; + try { + ResourceLocation spriteLocation = new ResourceLocation( + location.getNamespace(), + "textures/" + location.getPath() + ".png" + ); + Resource resource = resourceManager.getResource(spriteLocation); + sprite = NativeImage.read(resource.getInputStream()); + resource.close(); + + resource = resourceManager.getResource(emissiveLocation); + emission = NativeImage.read(resource.getInputStream()); + resource.close(); + } + catch (IOException e) { + BCLib.LOGGER.warning(e.getMessage()); + } + if (sprite != null && emission != null) { + int width = Math.min(sprite.getWidth(), emission.getWidth()); + int height = Math.min(sprite.getHeight(), emission.getHeight()); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + int argb = emission.getPixelRGBA(x, y); + int alpha = (argb >> 24) & 255; + if (alpha > 127) { + int r = (argb >> 16) & 255; + int g = (argb >> 8) & 255; + int b = argb & 255; + if (r > 0 || g > 0 || b > 0) { + argb = (argb & 0x00FFFFFF) | EMISSIVE_ALPHA; + sprite.setPixelRGBA(x, y, argb); } } } - TextureAtlas self = (TextureAtlas) (Object) this; - FabricSprite result = new FabricSprite( - self, - spriteInfo, - maxLevel, - atlasWidth, - atlasHeight, - posX, - posY, - sprite - ); - info.setReturnValue(result); } + TextureAtlas self = (TextureAtlas) (Object) this; + FabricSprite result = new FabricSprite( + self, + spriteInfo, + maxLevel, + atlasWidth, + atlasHeight, + posX, + posY, + sprite + ); + info.setReturnValue(result); } } } 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 9687414d..46538f7e 100644 --- a/src/main/resources/assets/minecraft/shaders/core/rendertype_cutout.fsh +++ b/src/main/resources/assets/minecraft/shaders/core/rendertype_cutout.fsh @@ -24,19 +24,24 @@ vec3 rgbToHSV(vec3 color) { } vec3 hsvToRGB(vec3 color) { - vec4 k = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); - vec3 p = abs(fract(color.xxx + k.xyz) * 6.0 - k.www); - return color.z * mix(k.xxx, clamp(p - k.xxx, 0.0, 1.0), color.y); + vec4 k = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(color.xxx + k.xyz) * 6.0 - k.www); + return color.z * mix(k.xxx, clamp(p - k.xxx, 0.0, 1.0), color.y); +} + +// Value between 252 and 254 +bool isEmissive(float alpha) { + return 0.9883 < alpha && alpha < 0.9961; } void main() { vec4 tex = texture(Sampler0, texCoord0); if (tex.a < 0.1) { - discard; - } + discard; + } vec4 color = tex * ColorModulator; vec4 vertex = vertexColor; - if (tex.a < 0.99) { + if (isEmissive(tex.a)) { vec3 hsv = rgbToHSV(vertex.rgb); hsv.z = 1.0; vertex.rgb = hsvToRGB(hsv); 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 f00c54f9..7fe88bc4 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 @@ -26,20 +26,25 @@ vec3 rgbToHSV(vec3 color) { } vec3 hsvToRGB(vec3 color) { - vec4 k = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); - vec3 p = abs(fract(color.xxx + k.xyz) * 6.0 - k.www); - return color.z * mix(k.xxx, clamp(p - k.xxx, 0.0, 1.0), color.y); + vec4 k = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(color.xxx + k.xyz) * 6.0 - k.www); + return color.z * mix(k.xxx, clamp(p - k.xxx, 0.0, 1.0), color.y); +} + +// Value between 252 and 254 +bool isEmissive(float alpha) { + return 0.9883 < alpha && alpha < 0.9961; } void main() { vec4 tex = texture(Sampler0, texCoord0); if (tex.a < 0.1) { - discard; - } + discard; + } vec4 color = tex * ColorModulator; color.rgb = mix(overlayColor.rgb, color.rgb, overlayColor.a); vec4 vertex = vertexColor * lightMapColor; - if (tex.a < 0.99) { + if (isEmissive(tex.a)) { vec3 hsv = rgbToHSV(vertex.rgb); hsv.z = 1.0; vertex.rgb = hsvToRGB(hsv); 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 2293003e..0897b74f 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 @@ -25,20 +25,25 @@ vec3 rgbToHSV(vec3 color) { } vec3 hsvToRGB(vec3 color) { - vec4 k = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); - vec3 p = abs(fract(color.xxx + k.xyz) * 6.0 - k.www); - return color.z * mix(k.xxx, clamp(p - k.xxx, 0.0, 1.0), color.y); + vec4 k = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(color.xxx + k.xyz) * 6.0 - k.www); + return color.z * mix(k.xxx, clamp(p - k.xxx, 0.0, 1.0), color.y); +} + +// Value between 252 and 254 +bool isEmissive(float alpha) { + return 0.9883 < alpha && alpha < 0.9961; } void main() { vec4 tex = texture(Sampler0, texCoord0); if (tex.a < 0.1) { - discard; - } + discard; + } vec4 color = tex * ColorModulator; color.rgb = mix(overlayColor.rgb, color.rgb, overlayColor.a); vec4 vertex = vertexColor; - if (tex.a < 0.99) { + if (isEmissive(tex.a)) { vec3 hsv = rgbToHSV(vertex.rgb); hsv.z = 1.0; vertex.rgb = hsvToRGB(hsv); 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 19222825..cbe64a51 100644 --- a/src/main/resources/assets/minecraft/shaders/core/rendertype_solid.fsh +++ b/src/main/resources/assets/minecraft/shaders/core/rendertype_solid.fsh @@ -24,16 +24,21 @@ vec3 rgbToHSV(vec3 color) { } vec3 hsvToRGB(vec3 color) { - vec4 k = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); - vec3 p = abs(fract(color.xxx + k.xyz) * 6.0 - k.www); - return color.z * mix(k.xxx, clamp(p - k.xxx, 0.0, 1.0), color.y); + vec4 k = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(color.xxx + k.xyz) * 6.0 - k.www); + return color.z * mix(k.xxx, clamp(p - k.xxx, 0.0, 1.0), color.y); +} + +// Value between 252 and 254 +bool isEmissive(float alpha) { + return 0.9883 < alpha && alpha < 0.9961; } void main() { vec4 tex = texture(Sampler0, texCoord0); vec4 color = tex * ColorModulator; vec4 vertex = vertexColor; - if (tex.a < 0.99) { + if (isEmissive(tex.a)) { vec3 hsv = rgbToHSV(vertex.rgb); hsv.z = 1.0; vertex.rgb = hsvToRGB(hsv);