feat: expanded perlin bg. gen. randomization
- wider scale ranges for more visible pattern variations - larger offset ranges for more unique starting points - randomized noise weights instead of fixed 0.6/0.3/0.1 ratios - randomized gradient strength & direction (30% chance of reverse for each axis) - randomized light-to-dark effects - multiple combination methods: - standard linear blend (cur.) - multiplicative blend (flowing, organic patterns) - maximum blend (sharper, more contrasted patterns) - turbulence (chaotic, cloud-like patterns) - 30% chance for additional subtle sine/cosine distortion
This commit is contained in:
parent
04d6693c37
commit
fb8c0f12d5
95
banner.go
95
banner.go
@ -5,6 +5,7 @@ import (
|
||||
"image"
|
||||
"image/color"
|
||||
"image/png"
|
||||
"math"
|
||||
"math/rand/v2"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@ -256,36 +257,96 @@ func genPerlinBG() *image.RGBA {
|
||||
img := image.NewRGBA(image.Rect(0, 0, config.BannerWidth, config.BannerHeight))
|
||||
|
||||
// noise params for interesting patterns
|
||||
scale1 := 0.01 + rand.Float64()*0.02 // primary pattern scale (adjusted by lib)
|
||||
scale2 := 0.03 + rand.Float64()*0.03 // secondary detail
|
||||
scale3 := 0.08 + rand.Float64()*0.05 // fine detail
|
||||
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
|
||||
|
||||
// variation offsets
|
||||
offsetX := rand.Float64() * 1000
|
||||
offsetY := rand.Float64() * 1000
|
||||
offsetX := rand.Float64() * 5000
|
||||
offsetY := rand.Float64() * 5000
|
||||
|
||||
log.Infof("Generating background with theme: %s, scales: %.4f, %.4f, %.4f", theme, scale1, scale2, scale3)
|
||||
// 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
|
||||
|
||||
// normalize weights to sum to 1.0
|
||||
totalWeight := weight1 + weight2 + weight3
|
||||
weight1 /= totalWeight
|
||||
weight2 /= totalWeight
|
||||
weight3 /= totalWeight
|
||||
|
||||
gradientStrengthX := rand.Float64() * 0.4
|
||||
gradientStrengthY := rand.Float64() * 0.3
|
||||
gradientDirectionX := 1.0
|
||||
gradientDirectionY := 1.0
|
||||
|
||||
// sometimes reverse gradient direction for variety
|
||||
if rand.Float64() < 0.3 {
|
||||
gradientDirectionX = -1.0
|
||||
}
|
||||
if rand.Float64() < 0.3 {
|
||||
gradientDirectionY = -1.0
|
||||
}
|
||||
|
||||
// randomize noise combination method
|
||||
combineMethod := rand.IntN(4)
|
||||
|
||||
useDistortion := rand.Float64() < 0.3 // 30% chance
|
||||
distortionStrength := rand.Float64() * 0.1
|
||||
|
||||
log.Debugf("BG theme: %s / Scales: %.4f, %.4f, %.4f / Weights: %.3f, %.3f, %.3f",
|
||||
theme, scale1, scale2, scale3, weight1, weight2, weight3)
|
||||
log.Debugf("Gradient: X=%.3f*%.0f, Y=%.3f*%.0f / Combine method: %d / Distortion %t (%.3f)",
|
||||
gradientStrengthX, gradientDirectionX, gradientStrengthY, gradientDirectionY,
|
||||
combineMethod, useDistortion, distortionStrength)
|
||||
|
||||
for y := range config.BannerHeight {
|
||||
for x := range config.BannerWidth {
|
||||
// multi-octave noise
|
||||
fx := (float64(x) + offsetX) * scale1
|
||||
fy := (float64(y) + offsetY) * scale1
|
||||
baseX := float64(x) + offsetX
|
||||
baseY := float64(y) + offsetY
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// multi-octave noise with randomized scales
|
||||
fx1 := baseX * scale1
|
||||
fy1 := baseY * scale1
|
||||
fx2 := baseX * scale2
|
||||
fy2 := baseY * scale2
|
||||
fx3 := baseX * scale3
|
||||
fy3 := baseY * scale3
|
||||
|
||||
// noise values at different scales
|
||||
noise1 := perlinNoise.Noise2D(fx, fy)
|
||||
noise2 := perlinNoise.Noise2D(fx/scale1*scale2, fy/scale1*scale2)
|
||||
noise3 := perlinNoise.Noise2D(fx/scale1*scale3, fy/scale1*scale3)
|
||||
noise1 := perlinNoise.Noise2D(fx1, fy1)
|
||||
noise2 := perlinNoise.Noise2D(fx2, fy2)
|
||||
noise3 := perlinNoise.Noise2D(fx3, fy3)
|
||||
|
||||
// combined noise layers with different weights
|
||||
combined := noise1*0.6 + noise2*0.3 + noise3*0.1
|
||||
// different combination methods for variety
|
||||
var combined float64
|
||||
switch combineMethod {
|
||||
case 0: // standard linear combination
|
||||
combined = noise1*weight1 + noise2*weight2 + noise3*weight3
|
||||
case 1: // multiplicative blend
|
||||
combined = (noise1*weight1)*(1+noise2*weight2)*(1+noise3*weight3) - 1
|
||||
case 2: // maximum blend (creates sharper patterns)
|
||||
values := []float64{noise1 * weight1, noise2 * weight2, noise3 * weight3}
|
||||
combined = math.Max(math.Max(values[0], values[1]), values[2])
|
||||
case 3: // turbulence (abs. values create more chaotic patterns)
|
||||
combined = math.Abs(noise1)*weight1 + math.Abs(noise2)*weight2 + math.Abs(noise3)*weight3
|
||||
}
|
||||
|
||||
// position-based gradient for a more dynamic look
|
||||
gradientX := float64(x) / float64(config.BannerWidth) * 0.2
|
||||
gradientY := float64(y) / float64(config.BannerHeight) * 0.1
|
||||
// randomized gradient with variable direction and strength
|
||||
gradientX := (float64(x) / float64(config.BannerWidth)) * gradientStrengthX * gradientDirectionX
|
||||
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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user