Maybe its doing something

This commit is contained in:
2025-10-28 16:08:08 +01:00
parent d56daa5779
commit a8a45271e6
18 changed files with 285 additions and 58 deletions

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -36,6 +36,10 @@ public final class TierTextureBakeProvider implements DataProvider {
private record TierTiles(BufferedImage side, BufferedImage top, BufferedImage bottom) {}
// Tuning knobs for tier tint appearance
private static final float TINT_SATURATION_BOOST = 0.15f; // +15% saturation
private static final float TINT_LIGHTNESS_BOOST = 0.12f; // +12% lightness to counter multiply darkening
private final PackOutput out;
private final ExistingFileHelper ef;
// Tinting removed: always use GT casing tiles + overlay
@@ -76,13 +80,18 @@ public final class TierTextureBakeProvider implements DataProvider {
// Fallback to plain overlay if tiles are missing
IBG.LOGGER.warn("Missing casing tiles for tier {} — rendering overlay only", tier);
}
BufferedImage overlay = tryReadPng("ibg", "textures/block/" + key + ".png");
if (overlay != null) {
int tierRgb = tilesOpt.map(TierTextureBakeProvider::deriveCasingMidRGB)
.orElse(GTValues.VC[tierId]);
applyTierTintForFirstMatchingBone(overlay, geo, tierRgb, "tier_tint");
g.drawImage(overlay, 0, 0, null);
} else {
IBG.LOGGER.debug("Overlay texture missing for key {} ({}): {}", key, tier,
"assets/ibg/textures/block/" + key + ".png");
}
g.dispose();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -148,13 +157,248 @@ public final class TierTextureBakeProvider implements DataProvider {
return Optional.empty();
}
// Tier-color tinting removed
// --- tier-color tinting on a specific bone region ---
/**
* Multiply-blend the tier color over the UV rectangles of the first matching
* bone.
* Returns true if any bone matched and was tinted.
*/
private static void applyTierTintForFirstMatchingBone(BufferedImage atlas, JsonObject geo, int tierRgb,
String boneName) {
var geos = geo.getAsJsonArray("minecraft:geometry");
if (geos == null)
return;
for (var ge : geos) {
var bones = ge.getAsJsonObject().getAsJsonArray("bones");
if (bones == null)
continue;
for (var bEl : bones) {
var bone = bEl.getAsJsonObject();
if (!bone.has("name"))
continue;
if (!boneName.equals(bone.get("name").getAsString()))
continue;
tintBoneUVMultiply(atlas, bone, tierRgb);
return;
}
}
}
/**
* Multiply the given atlas pixels inside the bone's UV rectangles by the
* provided tier color.
*/
private static boolean tintBoneUVMultiply(BufferedImage atlas, JsonObject bone, int tierRgb) {
var cubes = bone.getAsJsonArray("cubes");
if (cubes == null || cubes.size() == 0)
return false;
int w = atlas.getWidth();
int h = atlas.getHeight();
boolean didAny = false;
for (var cEl : cubes) {
var cube = cEl.getAsJsonObject();
if (cube.has("uv") && cube.get("uv").isJsonObject()) {
var uv = cube.getAsJsonObject("uv");
for (var e : uv.entrySet()) {
var f = e.getValue().getAsJsonObject();
if (!f.has("uv") || !f.has("uv_size"))
continue;
int u = f.getAsJsonArray("uv").get(0).getAsInt();
int v = f.getAsJsonArray("uv").get(1).getAsInt();
int us = f.getAsJsonArray("uv_size").get(0).getAsInt();
int vs = f.getAsJsonArray("uv_size").get(1).getAsInt();
didAny |= multiplyRect(atlas, clampRect(w, h, u, v, us, vs), tierRgb);
}
} else if (cube.has("uv") && cube.get("uv").isJsonArray() && cube.has("size")) {
var size = cube.getAsJsonArray("size");
int sx = size.get(0).getAsInt();
int sy = size.get(1).getAsInt();
int u = cube.getAsJsonArray("uv").get(0).getAsInt();
int v = cube.getAsJsonArray("uv").get(1).getAsInt();
didAny |= multiplyRect(atlas, clampRect(w, h, u, v, sx, sy), tierRgb);
}
}
return didAny;
}
private static int[] clampRect(int atlasW, int atlasH, int u, int v, int us, int vs) {
int x0 = us >= 0 ? u : u + us;
int y0 = vs >= 0 ? v : v + vs;
int rw = Math.abs(us);
int rh = Math.abs(vs);
if (x0 < 0) {
rw += x0;
x0 = 0;
}
if (y0 < 0) {
rh += y0;
y0 = 0;
}
if (x0 >= atlasW || y0 >= atlasH)
return new int[] { 0, 0, 0, 0 };
if (x0 + rw > atlasW)
rw = atlasW - x0;
if (y0 + rh > atlasH)
rh = atlasH - y0;
if (rw <= 0 || rh <= 0)
return new int[] { 0, 0, 0, 0 };
return new int[] { x0, y0, rw, rh };
}
private static boolean multiplyRect(BufferedImage atlas, int[] rect, int tierRgb) {
int x0 = rect[0], y0 = rect[1], rw = rect[2], rh = rect[3];
if (rw <= 0 || rh <= 0)
return false;
return multiplyRect(atlas, x0, y0, rw, rh, tierRgb);
}
private static boolean multiplyRect(BufferedImage atlas, int x0, int y0, int rw, int rh, int rgb) {
int tr = (rgb >> 16) & 0xFF;
int tg = (rgb >> 8) & 0xFF;
int tb = (rgb) & 0xFF;
for (int y = y0; y < y0 + rh; y++) {
for (int x = x0; x < x0 + rw; x++) {
int argb = atlas.getRGB(x, y);
int a = (argb >>> 24) & 0xFF;
if (a == 0)
continue; // skip fully transparent
int r = (argb >> 16) & 0xFF;
int g = (argb >> 8) & 0xFF;
int b = (argb) & 0xFF;
r = (r * tr) / 255;
g = (g * tg) / 255;
b = (b * tb) / 255;
atlas.setRGB(x, y, (a << 24) | (r << 16) | (g << 8) | b);
}
}
return true;
}
// --- representative casing color derivation ---
private static int deriveCasingMidRGB(TierTiles tiles) {
int rgb = sampleRepresentativeRGB(tiles.bottom);
if (rgb == 0) rgb = sampleRepresentativeRGB(tiles.top);
if (rgb == 0) rgb = sampleRepresentativeRGB(tiles.side);
if (rgb == 0) rgb = 0x808080;
// Push saturation first for color punch, then lift lightness to offset multiply darkening
rgb = adjustSaturation(rgb, TINT_SATURATION_BOOST);
return adjustLightness(rgb, TINT_LIGHTNESS_BOOST);
}
private static int sampleRepresentativeRGB(BufferedImage img) {
if (img == null) return 0;
int w = img.getWidth(), h = img.getHeight();
if (w <= 0 || h <= 0) return 0;
int x0 = Math.max(0, w / 8), y0 = Math.max(0, h / 8);
int x1 = Math.min(w, w - x0), y1 = Math.min(h, h - y0);
long sumH = 0, sumS = 0, sumL = 0, n = 0;
long sumR = 0, sumG = 0, sumB = 0, nRaw = 0;
for (int y = y0; y < y1; y++) {
for (int x = x0; x < x1; x++) {
int argb = img.getRGB(x, y);
int a = (argb >>> 24) & 0xFF;
if (a < 16) continue;
int r = (argb >> 16) & 0xFF;
int g = (argb >> 8) & 0xFF;
int b = (argb) & 0xFF;
sumR += r;
sumG += g;
sumB += b;
nRaw++;
float[] hsl = rgbToHsl(r, g, b);
float S = hsl[1], L = hsl[2];
if (S >= 0.08f && S <= 0.80f && L >= 0.25f && L <= 0.75f) {
sumH += (int) (hsl[0] * 360f);
sumS += (int) (S * 100f);
sumL += (int) (L * 100f);
n++;
}
}
}
if (n > 0) {
float H = (sumH / (float) n) / 360f;
float S = (sumS / (float) n) / 100f;
float L = (sumL / (float) n) / 100f;
if (L < 0.55f) L = 0.55f;
else if (L > 0.65f) L = 0.65f;
return hslToRgb(H, S, L);
} else if (nRaw > 0) {
int r = (int) (sumR / nRaw);
int g = (int) (sumG / nRaw);
int b = (int) (sumB / nRaw);
return (r << 16) | (g << 8) | b;
}
return 0;
}
private static int adjustLightness(int rgb, float deltaL) {
int r = (rgb >> 16) & 0xFF, g = (rgb >> 8) & 0xFF, b = rgb & 0xFF;
float[] hsl = rgbToHsl(r, g, b);
hsl[2] = clamp01(hsl[2] + deltaL);
return hslToRgb(hsl[0], hsl[1], hsl[2]);
}
private static int adjustSaturation(int rgb, float deltaS) {
int r = (rgb >> 16) & 0xFF, g = (rgb >> 8) & 0xFF, b = rgb & 0xFF;
float[] hsl = rgbToHsl(r, g, b);
hsl[1] = clamp01(hsl[1] + deltaS);
return hslToRgb(hsl[0], hsl[1], hsl[2]);
}
private static float[] rgbToHsl(int r8, int g8, int b8) {
float r = r8 / 255f, g = g8 / 255f, b = b8 / 255f;
float max = Math.max(r, Math.max(g, b));
float min = Math.min(r, Math.min(g, b));
float h, s, l = (max + min) / 2f;
if (max == min) {
h = 0f;
s = 0f;
} else {
float d = max - min;
s = l > 0.5f ? d / (2f - max - min) : d / (max + min);
if (max == r) h = (g - b) / d + (g < b ? 6f : 0f);
else if (max == g) h = (b - r) / d + 2f;
else h = (r - g) / d + 4f;
h /= 6f;
}
return new float[] { h, s, l };
}
private static int hslToRgb(float h, float s, float l) {
float r, g, b;
if (s == 0f) {
r = g = b = l;
} else {
float q = l < 0.5f ? l * (1f + s) : l + s - l * s;
float p = 2f * l - q;
r = hueToRgb(p, q, h + 1f / 3f);
g = hueToRgb(p, q, h);
b = hueToRgb(p, q, h - 1f / 3f);
}
int R = Math.round(r * 255f), G = Math.round(g * 255f), B = Math.round(b * 255f);
return (R << 16) | (G << 8) | B;
}
private static float hueToRgb(float p, float q, float t) {
if (t < 0f) t += 1f;
if (t > 1f) t -= 1f;
if (t < 1f / 6f) return p + (q - p) * 6f * t;
if (t < 1f / 2f) return q;
if (t < 2f / 3f) return p + (q - p) * (2f / 3f - t) * 6f;
return p;
}
private static float clamp01(float v) {
return v < 0f ? 0f : (v > 1f ? 1f : v);
}
// --- casing underlay path (tiling GT tiles into UV regions) ---
private static void paintTile(Graphics2D g, BufferedImage tile, int x, int y, int w, int h) {
int tw = tile.getWidth();
int th = tile.getHeight();
if (tw <= 0 || th <= 0 || w <= 0 || h <= 0) return;
if (tw <= 0 || th <= 0 || w <= 0 || h <= 0)
return;
var oldClip = g.getClip();
g.setClip(x, y, w, h);
@@ -185,16 +429,20 @@ public final class TierTextureBakeProvider implements DataProvider {
h += y0;
y0 = 0;
}
if (x0 >= atlasW || y0 >= atlasH || w <= 0 || h <= 0) return;
if (x0 + w > atlasW) w = atlasW - x0;
if (y0 + h > atlasH) h = atlasH - y0;
if (x0 >= atlasW || y0 >= atlasH || w <= 0 || h <= 0)
return;
if (x0 + w > atlasW)
w = atlasW - x0;
if (y0 + h > atlasH)
h = atlasH - y0;
paintTile(g, tile, x0, y0, w, h);
}
private void paintCasingFromGeo(Graphics2D g, TierTiles tiles, JsonObject geo) {
var geos = geo.getAsJsonArray("minecraft:geometry");
if (geos == null) return;
if (geos == null)
return;
JsonObject description = geos.get(0).getAsJsonObject().getAsJsonObject("description");
int atlasW = description.get("texture_width").getAsInt();
@@ -202,12 +450,15 @@ public final class TierTextureBakeProvider implements DataProvider {
for (var ge : geos) {
var bones = ge.getAsJsonObject().getAsJsonArray("bones");
if (bones == null) continue;
if (bones == null)
continue;
for (var bEl : bones) {
var bone = bEl.getAsJsonObject();
if (!bone.has("name") || !"base".equals(bone.get("name").getAsString())) continue;
if (!bone.has("name") || !"base".equals(bone.get("name").getAsString()))
continue;
var cubes = bone.getAsJsonArray("cubes");
if (cubes == null) continue;
if (cubes == null)
continue;
for (var cEl : cubes) {
var cube = cEl.getAsJsonObject();
@@ -239,5 +490,4 @@ public final class TierTextureBakeProvider implements DataProvider {
}
}
}
// All tinting helpers removed
}

View File

@@ -15,19 +15,6 @@
"name": "bb_main",
"pivot": [0, 0, 0],
"cubes": [
{
"origin": [-6, 4.44975, -3.5],
"size": [6, 7, 7],
"pivot": [-3, 7.94975, 0],
"rotation": [45, 0, 0],
"uv": {
"north": {"uv": [44, 14], "uv_size": [6, 7]},
"east": {"uv": [32, 34], "uv_size": [7, 7]},
"south": {"uv": [0, 45], "uv_size": [6, 7]},
"west": {"uv": [37, 14], "uv_size": [7, 7]},
"up": {"uv": [6, 45], "uv_size": [6, 7]}
}
},
{
"origin": [-6, 12.24264, 5.41422],
"size": [6, 4, 4],
@@ -91,19 +78,6 @@
"down": {"uv": [2, 59], "uv_size": [2, -3]}
}
},
{
"origin": [17.93, 5.2916, -3.60607],
"size": [6, 4.7, 7],
"pivot": [20.93, 7.6416, -0.10607],
"rotation": [45, 0, 0],
"uv": {
"north": {"uv": [26, 45], "uv_size": [6, 5]},
"east": {"uv": [12, 45], "uv_size": [7, 5]},
"south": {"uv": [45, 37], "uv_size": [6, 5]},
"west": {"uv": [19, 45], "uv_size": [7, 5]},
"up": {"uv": [39, 33], "uv_size": [6, 7]}
}
},
{
"origin": [18, 8.8636, -0.42929],
"size": [-3, 1, 1],
@@ -609,18 +583,6 @@
"up": {"uv": [59, 50], "uv_size": [2, 2]},
"down": {"uv": [56, 61], "uv_size": [2, -2]}
}
},
{
"origin": [12.71802, 14.65202, 1.7184],
"size": [2, 2, 2],
"uv": {
"north": {"uv": [41, 60], "uv_size": [2, 2]},
"east": {"uv": [49, 60], "uv_size": [2, 2]},
"south": {"uv": [51, 60], "uv_size": [2, 2]},
"west": {"uv": [54, 60], "uv_size": [2, 2]},
"up": {"uv": [60, 54], "uv_size": [2, 2]},
"down": {"uv": [60, 58], "uv_size": [2, -2]}
}
}
]
},
@@ -644,18 +606,33 @@
]
},
{
"name": "led",
"pivot": [-7, 3, -7],
"name": "tier_tint",
"pivot": [-3, 7.94975, 0],
"cubes": [
{
"origin": [-7.6, 1.4, -7.32],
"size": [2, 2, 2],
"origin": [-6, 4.44975, -3.5],
"size": [6, 7, 7],
"pivot": [-3, 7.94975, 0],
"rotation": [45, 0, 0],
"uv": {
"north": {"uv": [60, 58], "uv_size": [2, 2]},
"east": {"uv": [60, 60], "uv_size": [2, 2]},
"south": {"uv": [0, 61], "uv_size": [2, 2]},
"west": {"uv": [2, 61], "uv_size": [2, 2]},
"up": {"uv": [16, 61], "uv_size": [2, 2]}
"north": {"uv": [44, 14], "uv_size": [6, 7]},
"east": {"uv": [32, 34], "uv_size": [7, 7]},
"south": {"uv": [0, 45], "uv_size": [6, 7]},
"west": {"uv": [37, 14], "uv_size": [7, 7]},
"up": {"uv": [6, 45], "uv_size": [6, 7]}
}
},
{
"origin": [17.93, 5.2916, -3.60607],
"size": [6, 4.7, 7],
"pivot": [20.93, 7.6416, -0.10607],
"rotation": [45, 0, 0],
"uv": {
"north": {"uv": [26, 45], "uv_size": [6, 5]},
"east": {"uv": [12, 45], "uv_size": [7, 5]},
"south": {"uv": [45, 37], "uv_size": [6, 5]},
"west": {"uv": [19, 45], "uv_size": [7, 5]},
"up": {"uv": [39, 33], "uv_size": [6, 7]}
}
}
]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB