#requires -Version 5
# One-shot helper: generates a subtle warm-tinted tileable noise texture
# at Assets/noise.png. Run only when you want to regenerate the texture.

Add-Type -AssemblyName System.Drawing

$here    = Split-Path -Parent $MyInvocation.MyCommand.Path
$outPath = Join-Path $here 'noise.png'

$size = 128
$bmp  = New-Object System.Drawing.Bitmap $size, $size, ([System.Drawing.Imaging.PixelFormat]::Format32bppArgb)
$rng  = New-Object System.Random 1337

# Lock bits for fast pixel access
$rect = New-Object System.Drawing.Rectangle 0, 0, $size, $size
$data = $bmp.LockBits($rect, [System.Drawing.Imaging.ImageLockMode]::WriteOnly,
    [System.Drawing.Imaging.PixelFormat]::Format32bppArgb)
$bytes = New-Object byte[] ($data.Stride * $size)

function Clamp([double]$v, [double]$lo, [double]$hi) {
    if ($v -lt $lo) { return $lo }
    if ($v -gt $hi) { return $hi }
    return $v
}

for ($y = 0; $y -lt $size; $y++) {
    for ($x = 0; $x -lt $size; $x++) {
        $offset = ($y * $data.Stride) + ($x * 4)
        # Cool dark grain to overlay on a navy backdrop -- gives subtle metallic noise
        $n = ($rng.NextDouble() - 0.5) * 2.0  # -1.0 .. 1.0
        $bytes[$offset]     = [byte](Clamp (110 + ($n * 50)) 0 255)   # B
        $bytes[$offset + 1] = [byte](Clamp (105 + ($n * 50)) 0 255)   # G
        $bytes[$offset + 2] = [byte](Clamp (95  + ($n * 50)) 0 255)   # R
        $bytes[$offset + 3] = 28                                       # A (~11%)
    }
}

[System.Runtime.InteropServices.Marshal]::Copy($bytes, 0, $data.Scan0, $bytes.Length)
$bmp.UnlockBits($data)
$bmp.Save($outPath, [System.Drawing.Imaging.ImageFormat]::Png)
$bmp.Dispose()

"Wrote: $outPath ($((Get-Item $outPath).Length) bytes, ${size}x${size})"
