diff --git a/shaders/shiny_card.frag b/shaders/shiny_card.frag index 0ef22c7..0ac5e45 100644 --- a/shaders/shiny_card.frag +++ b/shaders/shiny_card.frag @@ -287,16 +287,22 @@ void main() { // Highlight uses stretched UVs so glare spans the full widget area. float highlightDistance = length(uv - (center + (uTilt * 0.35))); float specularMask = pow(max(0.0, 1.0 - highlightDistance * 2.6), 3.2); - vec3 specular = vec3(specularMask) * uSpecular * (0.4 + 0.6 * tiltMag); + bool isHolographicSilver = uStyle < 0.5; bool isCrackedIce = uStyle >= 0.5 && uStyle < 1.5; - float sparkleGridScale = isCrackedIce ? 7.0 : 18.0; + bool isSilverMosaic = uStyle >= 1.5 && uStyle < 2.5; + + float prismaticGain = isHolographicSilver ? 1.10 : (isCrackedIce ? 1.00 : (isSilverMosaic ? 1.30 : 1.55)); + float sparkleGain = isHolographicSilver ? 1.00 : (isCrackedIce ? 0.55 : (isSilverMosaic ? 0.80 : 0.70)); + float specularGain = isHolographicSilver ? 1.00 : (isCrackedIce ? 1.35 : (isSilverMosaic ? 1.15 : 1.50)); + + float sparkleGridScale = isCrackedIce ? 7.0 : (isSilverMosaic ? 14.0 : 18.0); // Sparkle grid uses aspect-corrected coordinates to avoid stretching. vec2 sparkleGrid = aspectUV * sparkleGridScale; vec2 grid = floor(sparkleGrid); - float rarityThreshold = isCrackedIce ? 0.965 : 0.83; + float rarityThreshold = isCrackedIce ? 0.965 : (isSilverMosaic ? 0.88 : 0.83); float rarity = step(rarityThreshold, hash(grid + 0.31)); vec3 sparkle = vec3(0.0); @@ -318,12 +324,12 @@ void main() { shapeMask = sparkleShapeMask(cell, grid); } - float sparklePower = isCrackedIce ? 4.8 : 3.2; - float sparkleIntensity = isCrackedIce ? 0.25 : 1.0; + float sparklePower = isCrackedIce ? 4.8 : (isSilverMosaic ? 3.8 : 3.2); + float sparkleIntensity = isCrackedIce ? 0.25 : (isSilverMosaic ? 0.55 : 1.0); float sparkleChroma = isCrackedIce ? 0.20 : 0.35; float sparkleMask = pow(alignment, sparklePower) * twinkle * rarity * shapeMask; vec3 sparkleColor = mix(vec3(1.0), rainbow(sparkleHash + dot(uTilt, vec2(0.2, -0.15)), 0.55, 1.0), sparkleChroma); - sparkle = sparkleColor * sparkleMask * uSparkle * sparkleIntensity; + sparkle = sparkleColor * sparkleMask * uSparkle * sparkleIntensity * sparkleGain; } } @@ -347,6 +353,12 @@ void main() { float directional = 0.5 + 0.5 * dot(normal2d, tiltDir); float tiltLighting = mix(0.86, 1.20, pow(directional, 1.2)); chromaAdjusted *= tiltLighting; + + float edgeSpec = pow(1.0 - directional, 2.2); + vec3 specular = vec3(specularMask) * (0.3 + 0.7 * edgeSpec) * uSpecular * (0.35 + 0.65 * tiltMag) * specularGain; + + float prismaticPhase = dot(aspectUV, vec2(3.6, -2.1)) + dot(uTilt, vec2(0.9, -0.7)) + uTime * 0.04; + vec3 prismaticTint = rainbow(prismaticPhase, 0.72, 1.0) * uPrismatic * prismaticGain * (0.08 + 0.14 * edgeSpec); float microStrength = isCrackedIce ? 0.08 : 0.18; @@ -354,7 +366,7 @@ void main() { float microMask = 0.5 + 0.5 * sin(dot(aspectUV, vec2(137.0, 57.0)) + noise(aspectUV * 14.0) * 4.0 + dot(uTilt, vec2(9.0, 4.0)) * 2.0); vec3 microShimmer = rainbow(noise(aspectUV * 10.0) + dot(uTilt, vec2(0.4, -0.3)) * 0.3, 0.65, 1.0) * microMask * uDiffraction * microStrength; - vec3 styleColor = chromaAdjusted + microShimmer + (specular * 0.15) + sparkle; + vec3 styleColor = chromaAdjusted + microShimmer + prismaticTint + (specular * 0.22) + sparkle; vec3 mappedColor = styleColor / (1.0 + styleColor * 0.3); float luma = dot(mappedColor, vec3(0.299, 0.587, 0.114)); vec3 vibrantColor = mix(vec3(luma), mappedColor, 1.4);