mirror of
https://github.com/GayPizzaSpecifications/voxelotl-engine.git
synced 2025-08-03 13:11:33 +00:00
2d improved perlin
This commit is contained in:
@ -1,6 +1,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public struct ImprovedPerlin<T: BinaryFloatingPoint & SIMDScalar>: CoherentNoise3D {
|
public struct ImprovedPerlin<T: BinaryFloatingPoint & SIMDScalar>: CoherentNoise2D, CoherentNoise3D {
|
||||||
private let p: [Int16]
|
private let p: [Int16]
|
||||||
|
|
||||||
public init(permutation: [Int16]) {
|
public init(permutation: [Int16]) {
|
||||||
@ -12,6 +12,31 @@ public struct ImprovedPerlin<T: BinaryFloatingPoint & SIMDScalar>: CoherentNoise
|
|||||||
self.p = (0..<0x100).map { Int16($0) }.shuffled(using: &random)
|
self.p = (0..<0x100).map { Int16($0) }.shuffled(using: &random)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func get(_ point: SIMD2<T>) -> T {
|
||||||
|
// Find unit square
|
||||||
|
let idx = SIMD2(Int(floor(point.x)), Int(floor(point.y))) & 0xFF
|
||||||
|
// Find relative point in square
|
||||||
|
let inner = point - SIMD2(floor(point.x), floor(point.y))
|
||||||
|
|
||||||
|
// Compute fade curves for each axis
|
||||||
|
let u = inner.x.smootherStep()
|
||||||
|
let v = inner.y.smootherStep()
|
||||||
|
|
||||||
|
// Compute hash of the coordinates of the 4 square corners
|
||||||
|
let a = idx.y + perm(idx.x), b = idx.y + perm(idx.x + 1)
|
||||||
|
let aa = perm(a), ab = perm(a + 1)
|
||||||
|
let ba = perm(b), bb = perm(b + 1)
|
||||||
|
|
||||||
|
// Add blended results
|
||||||
|
return v.mlerp(
|
||||||
|
u.mlerp(
|
||||||
|
grad(perm(aa), inner),
|
||||||
|
grad(perm(ba), .init(inner.x - 1, inner.y))),
|
||||||
|
u.mlerp(
|
||||||
|
grad(perm(ab), .init(inner.x, inner.y - 1)),
|
||||||
|
grad(perm(bb), inner - .init(repeating: 1))))
|
||||||
|
}
|
||||||
|
|
||||||
public func get(_ point: SIMD3<T>) -> T {
|
public func get(_ point: SIMD3<T>) -> T {
|
||||||
// Find unit cube containg point
|
// Find unit cube containg point
|
||||||
let idx = SIMD3(Int(floor(point.x)), Int(floor(point.y)), Int(floor(point.z))) & 0xFF
|
let idx = SIMD3(Int(floor(point.x)), Int(floor(point.y)), Int(floor(point.z))) & 0xFF
|
||||||
@ -45,10 +70,13 @@ public struct ImprovedPerlin<T: BinaryFloatingPoint & SIMDScalar>: CoherentNoise
|
|||||||
u.mlerp(
|
u.mlerp(
|
||||||
grad(perm(ab + 1), .init(inner.x, inner.y - 1, inner.z - 1)),
|
grad(perm(ab + 1), .init(inner.x, inner.y - 1, inner.z - 1)),
|
||||||
grad(perm(bb + 1), inner - .init(repeating: 1)))))
|
grad(perm(bb + 1), inner - .init(repeating: 1)))))
|
||||||
|
}
|
||||||
|
|
||||||
@inline(__always) func perm(_ x: Int) -> Int { Int(self.p[x & 0xFF]) }
|
@inline(__always) fileprivate func perm(_ x: Int) -> Int { Int(self.p[x & 0xFF]) }
|
||||||
|
|
||||||
func grad(_ hash: Int, _ point: SIMD3<T>) -> T {
|
@inline(__always) fileprivate func grad(_ hash: Int, _ point: SIMD2<T>) -> T { grad(hash, SIMD3(point, 0)) }
|
||||||
|
|
||||||
|
fileprivate func grad(_ hash: Int, _ point: SIMD3<T>) -> T {
|
||||||
// Convert low 4 bits of hash code into 12 gradient directions
|
// Convert low 4 bits of hash code into 12 gradient directions
|
||||||
let low4 = hash & 0xF
|
let low4 = hash & 0xF
|
||||||
var u = low4 < 8 ? point.x : point.y
|
var u = low4 < 8 ? point.x : point.y
|
||||||
@ -58,4 +86,3 @@ public struct ImprovedPerlin<T: BinaryFloatingPoint & SIMDScalar>: CoherentNoise
|
|||||||
return u + v
|
return u + v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
Reference in New Issue
Block a user