From b8b101119c66cfc67f16c842dbec11e1cc5ae3d4 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Thu, 17 Apr 2025 15:31:57 -0500 Subject: [PATCH] [Bug][Sprite] Use floats for variant shader recolor comparison (#5668) * Use float values for comparison * Remove unused colorInt --- src/pipelines/glsl/spriteFragShader.frag | 36 ++++++++---------------- src/pipelines/glsl/spriteShader.vert | 1 - src/pipelines/sprite.ts | 8 +++--- src/utils.ts | 5 +++- 4 files changed, 20 insertions(+), 30 deletions(-) diff --git a/src/pipelines/glsl/spriteFragShader.frag b/src/pipelines/glsl/spriteFragShader.frag index 3765e595b70..03f8c8c27bc 100644 --- a/src/pipelines/glsl/spriteFragShader.frag +++ b/src/pipelines/glsl/spriteFragShader.frag @@ -31,9 +31,9 @@ uniform vec2 texSize; uniform float yOffset; uniform float yShadowOffset; uniform vec4 tone; -uniform ivec4 baseVariantColors[32]; +uniform vec4 baseVariantColors[32]; uniform vec4 variantColors[32]; -uniform ivec4 spriteColors[32]; +uniform vec4 spriteColors[32]; uniform ivec4 fusionSpriteColors[32]; const vec3 lumaF = vec3(.299, .587, .114); @@ -69,7 +69,6 @@ float hue2rgb(float f1, float f2, float hue) { vec3 rgb2hsl(vec3 color) { vec3 hsl; - float fmin = min(min(color.r, color.g), color.b); float fmax = max(max(color.r, color.g), color.b); float delta = fmax - fmin; @@ -152,34 +151,23 @@ vec3 hsv2rgb(vec3 c) { void main() { vec4 texture = texture2D(uMainSampler[0], outTexCoord); - ivec4 colorInt = ivec4(texture*255.0); - for (int i = 0; i < 32; i++) { - if (baseVariantColors[i][3] == 0) + if (baseVariantColors[i].a == 0.0) break; - // abs value is broken in this version of gles with highp - ivec3 diffs = ivec3( - (colorInt.r > baseVariantColors[i].r) ? colorInt.r - baseVariantColors[i].r : baseVariantColors[i].r - colorInt.r, - (colorInt.g > baseVariantColors[i].g) ? colorInt.g - baseVariantColors[i].g : baseVariantColors[i].g - colorInt.g, - (colorInt.b > baseVariantColors[i].b) ? colorInt.b - baseVariantColors[i].b : baseVariantColors[i].b - colorInt.b - ); - // Set color threshold to be within 3 points for each channel - bvec3 threshold = lessThan(diffs, ivec3(3)); - - if (texture.a > 0.0 && all(threshold)) { + if (texture.a > 0.0 && all(lessThan(abs(texture.rgb - baseVariantColors[i].rgb), vec3(1.0/255.0)))) { texture.rgb = variantColors[i].rgb; break; } } for (int i = 0; i < 32; i++) { - if (spriteColors[i][3] == 0) + if (spriteColors[i][3] == 0.0) break; - if (texture.a > 0.0 && colorInt.r == spriteColors[i].r && colorInt.g == spriteColors[i].g && colorInt.b == spriteColors[i].b) { - vec3 fusionColor = vec3(float(fusionSpriteColors[i].r) / 255.0, float(fusionSpriteColors[i].g) / 255.0, float(fusionSpriteColors[i].b) / 255.0); - vec3 bg = vec3(spriteColors[i].rgb) / 255.0; + if (texture.a > 0.0 && all(lessThan(abs(texture.rgb - spriteColors[i].rgb), vec3(1.0/255.0)))) { + vec3 fusionColor = vec3(fusionSpriteColors[i].rgb) / 255.0; + vec3 bg = spriteColors[i].rgb; float gray = (bg.r + bg.g + bg.b) / 3.0; - bg = vec3(gray, gray, gray); + bg = vec3(gray); vec3 fg = fusionColor; texture.rgb = mix(1.0 - 2.0 * (1.0 - bg) * (1.0 - fg), 2.0 * bg * fg, step(bg, vec3(0.5))); break; @@ -192,7 +180,7 @@ void main() { vec4 color = texture * texel; if (color.a > 0.0 && teraColor.r > 0.0 && teraColor.g > 0.0 && teraColor.b > 0.0) { - vec2 relUv = vec2((outTexCoord.x - texFrameUv.x) / (size.x / texSize.x), (outTexCoord.y - texFrameUv.y) / (size.y / texSize.y)); + vec2 relUv = (outTexCoord.xy - texFrameUv.xy) / (size.xy / texSize.xy); vec2 teraTexCoord = vec2(relUv.x * (size.x / 200.0), relUv.y * (size.y / 120.0)); vec4 teraCol = texture2D(uMainSampler[1], teraTexCoord); float floorValue = 86.0 / 255.0; @@ -265,8 +253,8 @@ void main() { if ((spriteY >= 0.9 && (color.a == 0.0 || yOverflow))) { float shadowSpriteY = (spriteY - 0.9) * (1.0 / 0.15); - if (distance(vec2(spriteX, shadowSpriteY), vec2(0.5, 0.5)) < 0.5) { - color = vec4(vec3(0.0, 0.0, 0.0), 0.5); + if (distance(vec2(spriteX, shadowSpriteY), vec2(0.5)) < 0.5) { + color = vec4(vec3(0.0), 0.5); } else if (yOverflow) { discard; } diff --git a/src/pipelines/glsl/spriteShader.vert b/src/pipelines/glsl/spriteShader.vert index 33743384b47..84e73834f49 100644 --- a/src/pipelines/glsl/spriteShader.vert +++ b/src/pipelines/glsl/spriteShader.vert @@ -11,7 +11,6 @@ attribute float inTintEffect; attribute vec4 inTint; varying vec2 outTexCoord; -varying vec2 outtexFrameUv; varying float outTexId; varying vec2 outPosition; varying float outTintEffect; diff --git a/src/pipelines/sprite.ts b/src/pipelines/sprite.ts index d97cae1662b..0aa9409617a 100644 --- a/src/pipelines/sprite.ts +++ b/src/pipelines/sprite.ts @@ -101,7 +101,7 @@ export default class SpritePipeline extends FieldSpritePipeline { flatSpriteColors.splice( flatSpriteColors.length, 0, - ...(c < spriteColors.length ? spriteColors[c] : emptyColors), + ...(c < spriteColors.length ? spriteColors[c].map(x => x / 255.0) : emptyColors), ); flatFusionSpriteColors.splice( flatFusionSpriteColors.length, @@ -110,7 +110,7 @@ export default class SpritePipeline extends FieldSpritePipeline { ); } - this.set4iv("spriteColors", flatSpriteColors.flat()); + this.set4fv("spriteColors", flatSpriteColors.flat()); this.set4iv("fusionSpriteColors", flatFusionSpriteColors.flat()); } } @@ -146,7 +146,7 @@ export default class SpritePipeline extends FieldSpritePipeline { if (c < baseColors.length) { const baseColor = Array.from(Object.values(rgbHexToRgba(baseColors[c]))); const variantColor = Array.from(Object.values(rgbHexToRgba(variantColors[variant][baseColors[c]]))); - flatBaseColors.splice(flatBaseColors.length, 0, ...baseColor); + flatBaseColors.splice(flatBaseColors.length, 0, ...baseColor.map(c => c / 255.0)); flatVariantColors.splice(flatVariantColors.length, 0, ...variantColor.map(c => c / 255.0)); } else { flatBaseColors.splice(flatBaseColors.length, 0, ...emptyColors); @@ -160,7 +160,7 @@ export default class SpritePipeline extends FieldSpritePipeline { } } - this.set4iv("baseVariantColors", flatBaseColors.flat()); + this.set4fv("baseVariantColors", flatBaseColors.flat()); this.set4fv("variantColors", flatVariantColors.flat()); } diff --git a/src/utils.ts b/src/utils.ts index 2f05e2724ff..ce9966c0d7f 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -405,8 +405,11 @@ export function deltaRgb(rgb1: number[], rgb2: number[]): number { return Math.ceil(Math.sqrt(2 * drp2 + 4 * dgp2 + 3 * dbp2 + (t * (drp2 - dbp2)) / 256)); } +// Extract out the rgb values from a hex string +const hexRegex = /^([\da-f]{2})([\da-f]{2})([\da-f]{2})$/i; + export function rgbHexToRgba(hex: string) { - const color = hex.match(/^([\da-f]{2})([\da-f]{2})([\da-f]{2})$/i) ?? ["000000", "00", "00", "00"]; + const color = hex.match(hexRegex) ?? ["000000", "00", "00", "00"]; return { r: Number.parseInt(color[1], 16), g: Number.parseInt(color[2], 16),