diff --git a/banner.go b/banner.go index 43af004..9e81587 100644 --- a/banner.go +++ b/banner.go @@ -298,23 +298,23 @@ func findTextPositions(textData []*TextData, filename string) { } } -func genPerlinBG() *image.RGBA { +func genPerlinBG() (*image.RGBA, string) { palette, theme := getRandomThemePalette() img := image.NewRGBA(image.Rect(0, 0, config.BannerWidth, config.BannerHeight)) // noise params for interesting patterns - scale1 := 0.005 + rand.Float64()*0.025 // primary pattern scale (adjusted by lib) - scale2 := 0.02 + rand.Float64()*0.04 // secondary detail - scale3 := 0.06 + rand.Float64()*0.08 // fine detail + scale1 := 0.008 + rand.Float64()*0.015 // 0.008-0.023 (large patterns) + scale2 := 0.025 + rand.Float64()*0.035 // 0.025-0.06 (medium detail) + scale3 := 0.060 + rand.Float64()*0.040 // 0.060-0.100 (fine detail, reduced grain) // variation offsets offsetX := rand.Float64() * 5000 offsetY := rand.Float64() * 5000 // noise layer weights for different effects - weight1 := 0.4 + rand.Float64()*0.4 - weight2 := 0.2 + rand.Float64()*0.3 - weight3 := 0.1 + rand.Float64()*0.2 + weight1 := 0.4 + rand.Float64()*0.4 // 0.4-0.8 (large patterns) + weight2 := 0.15 + rand.Float64()*0.25 // 0.15-0.4 (medium detail) + weight3 := 0.05 + rand.Float64()*0.15 // 0.15-0.4 (fine detail, reduced grain) // normalize weights to sum to 1.0 totalWeight := weight1 + weight2 + weight3 @@ -322,8 +322,9 @@ func genPerlinBG() *image.RGBA { weight2 /= totalWeight weight3 /= totalWeight - gradientStrengthX := rand.Float64() * 0.4 - gradientStrengthY := rand.Float64() * 0.3 + // FIX: limit gradient strength to prevent overwhelming the noise + gradientStrengthX := rand.Float64() * 0.25 // old: 0.4 + gradientStrengthY := rand.Float64() * 0.2 // old: 0.3 gradientDirectionX := 1.0 gradientDirectionY := 1.0 @@ -338,8 +339,9 @@ func genPerlinBG() *image.RGBA { // randomize noise combination method combineMethod := rand.IntN(4) - useDistortion := rand.Float64() < 0.3 // 30% chance - distortionStrength := rand.Float64() * 0.1 + // fix: increase distortion chance and make it more visible + useDistortion := rand.Float64() < 0.4 // old: 30% + distortionStrength := 0.05 + rand.Float64()*0.15 // 0.05-0.2 (old: 0.0-0.1) log.Debugf("BG theme: %s / Scales: %.4f, %.4f, %.4f / Weights: %.3f, %.3f, %.3f", theme, scale1, scale2, scale3, weight1, weight2, weight3) @@ -354,8 +356,8 @@ func genPerlinBG() *image.RGBA { // optional distortion for more organic patterns if useDistortion { - baseX += math.Sin(float64(y)*0.01) * distortionStrength * 100 - baseY += math.Cos(float64(x)*0.01) * distortionStrength * 100 + baseX += math.Sin(float64(y)*0.015) * distortionStrength * 200 + baseY += math.Cos(float64(x)*0.015) * distortionStrength * 200 } // multi-octave noise with randomized scales @@ -390,28 +392,19 @@ func genPerlinBG() *image.RGBA { gradientY := (float64(y) / float64(config.BannerHeight)) * gradientStrengthY * gradientDirectionY // combined and normalized to [0, 1] range - noise := (combined + gradientX + gradientY + 1) / 2 - - // clamp to valid range - if noise < 0 { - noise = 0 - } - if noise > 1 { - noise = 1 - } + noise := min(max((combined+gradientX+gradientY+1)/2, 0), 1) pixelColor := palette.interpolate(noise) img.Set(x, y, pixelColor) } } - return img + return img, theme } func genBanner(textData []*TextData) error { fn := fmt.Sprintf("banner_%d.png", time.Now().UnixMicro()) - canvas := genPerlinBG() - + canvas, theme := genPerlinBG() findTextPositions(textData, fn) for _, td := range textData { @@ -428,7 +421,13 @@ func genBanner(textData []*TextData) error { } defer file.Close() - return png.Encode(file, canvas) + if err := png.Encode(file, canvas); err != nil { + return err + } + + log.Infof("Output '%s' with theme '%s'", fn, theme) + + return nil } // TODO: functions for banner rotation implementation