add perlin noise
This commit is contained in:
parent
c25daba2ed
commit
eddb3f9709
3 changed files with 115 additions and 15 deletions
100
common/perlinnoise.go
Normal file
100
common/perlinnoise.go
Normal file
|
@ -0,0 +1,100 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"math"
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
const (
|
||||
perlinYwrapb = 4
|
||||
perlinYwrap = 1 << perlinYwrapb
|
||||
perlinZwrapb = 8
|
||||
perlinZwrap = 1 << perlinZwrapb
|
||||
perlinSize = 4095
|
||||
perlinOctaves = 4
|
||||
perlinAmpFalloff = 0.5
|
||||
)
|
||||
|
||||
type perlinNoise struct {
|
||||
perlin []float64
|
||||
}
|
||||
|
||||
func NewPerlinNoise() *perlinNoise {
|
||||
perlin := &perlinNoise{perlin: nil}
|
||||
perlin.perlin = make([]float64, perlinSize+1)
|
||||
|
||||
for i, _ := range perlin.perlin {
|
||||
perlin.perlin[i] = rand.Float64()
|
||||
}
|
||||
return perlin
|
||||
}
|
||||
|
||||
func (p *perlinNoise) Noise(x, y, z float64) float64 {
|
||||
if x < 0 {
|
||||
x = -x
|
||||
}
|
||||
|
||||
if y < 0 {
|
||||
y = -y
|
||||
}
|
||||
|
||||
if z < 0 {
|
||||
z = -z
|
||||
}
|
||||
|
||||
xi, yi, zi := int(math.Floor(x)), int(math.Floor(y)), int(math.Floor(z))
|
||||
xf, yf, zf := x-float64(xi), y-float64(yi), z-float64(zi)
|
||||
|
||||
var rxf, ryf, n1, n2, n3 float64
|
||||
var r float64
|
||||
var ampl float64 = 0.5
|
||||
|
||||
for o := 0; o < perlinOctaves; o++ {
|
||||
of := xi + (yi << perlinYwrapb) + (zi << perlinZwrapb)
|
||||
|
||||
rxf = scaledCosin(xf)
|
||||
ryf = scaledCosin(yf)
|
||||
|
||||
n1 = p.perlin[of&perlinSize]
|
||||
n1 += rxf * (p.perlin[(of+1)&perlinSize] - n1)
|
||||
n2 = p.perlin[(of+perlinYwrap)&perlinSize]
|
||||
n2 += rxf * (p.perlin[(of+perlinYwrap+1)&perlinSize] - n2)
|
||||
n1 += ryf * (n2 - n1)
|
||||
|
||||
of += perlinZwrap
|
||||
n2 = p.perlin[of&perlinSize]
|
||||
n2 += rxf * (p.perlin[(of+1)&perlinSize] - n2)
|
||||
n3 = p.perlin[(of+perlinYwrap)&perlinSize]
|
||||
n3 += rxf * (p.perlin[(of+perlinYwrap+1)&perlinSize] - n3)
|
||||
n2 += ryf * (n3 - n2)
|
||||
|
||||
n1 += scaledCosin(zf) * (n2 - n1)
|
||||
|
||||
r += n1 * ampl
|
||||
ampl *= perlinAmpFalloff
|
||||
xi <<= 1
|
||||
xf *= 2
|
||||
yi <<= 1
|
||||
yf *= 2
|
||||
zi <<= 1
|
||||
zf *= 2
|
||||
|
||||
if xf >= 1.0 {
|
||||
xi += 1
|
||||
xf -= 1
|
||||
}
|
||||
if yf >= 1.0 {
|
||||
yi += 1
|
||||
yf -= 1
|
||||
}
|
||||
if zf >= 1.0 {
|
||||
zi += 1
|
||||
zf -= 1
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func scaledCosin(x float64) float64 {
|
||||
return 0.5 * (1.0 - math.Cos(x*math.Pi))
|
||||
}
|
Loading…
Reference in a new issue