mirror of
				https://github.com/GayPizzaSpecifications/voxelotl-engine.git
				synced 2025-11-04 10:59:39 +00:00 
			
		
		
		
	fix significant oversights in noise & random
This commit is contained in:
		@ -1,13 +1,15 @@
 | 
			
		||||
public protocol CoherentNoise {
 | 
			
		||||
  associatedtype Scalar: FloatingPoint & SIMDScalar
 | 
			
		||||
 | 
			
		||||
  init()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public protocol CoherentNoiseRandomInit: CoherentNoise {
 | 
			
		||||
  init<Random: RandomProvider>(random: inout Random)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public protocol CoherentNoiseTableInit: CoherentNoise {
 | 
			
		||||
  init(permutation: [Int16])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public protocol CoherentNoise2D: CoherentNoise {
 | 
			
		||||
  func get(_ point: SIMD2<Scalar>) -> Scalar
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,3 @@
 | 
			
		||||
 | 
			
		||||
public struct LayeredNoise<Generator: CoherentNoise> {
 | 
			
		||||
  public typealias Scalar = Generator.Scalar
 | 
			
		||||
 | 
			
		||||
@ -7,47 +6,55 @@ public struct LayeredNoise<Generator: CoherentNoise> {
 | 
			
		||||
  public let amplitude: Scalar
 | 
			
		||||
 | 
			
		||||
  private let _generators: [Generator]
 | 
			
		||||
 | 
			
		||||
  init(octaves: Int, frequency: Scalar, amplitude: Scalar) {
 | 
			
		||||
    self.octaves   = octaves
 | 
			
		||||
    self.frequency = frequency
 | 
			
		||||
    self.amplitude = amplitude
 | 
			
		||||
    self._generators = Array(repeating: .init(), count: octaves)
 | 
			
		||||
  }
 | 
			
		||||
  private let _amplitudeAdjusted: Scalar
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public extension LayeredNoise where Generator: CoherentNoiseRandomInit {
 | 
			
		||||
  init<Random: RandomProvider>(random: inout Random, octaves: Int, frequency: Scalar, amplitude: Scalar) {
 | 
			
		||||
  init<Random: RandomProvider>(random: inout Random, octaves: Int, frequency: Scalar, amplitude: Scalar = 1) {
 | 
			
		||||
    self.octaves   = octaves
 | 
			
		||||
    self.frequency = frequency
 | 
			
		||||
    self.amplitude = amplitude
 | 
			
		||||
    self._generators = Array(repeating: Generator(random: &random), count: octaves)
 | 
			
		||||
    self._generators = (0..<octaves).map { _ in Generator(random: &random) }
 | 
			
		||||
    self._amplitudeAdjusted = amplitude / 2
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public extension LayeredNoise where Generator: CoherentNoiseTableInit {
 | 
			
		||||
  init(permutation table: [Int16], octaves: Int, frequency: Scalar, amplitude: Scalar = 1) {
 | 
			
		||||
    self.octaves   = octaves
 | 
			
		||||
    self.frequency = frequency
 | 
			
		||||
    self.amplitude = amplitude
 | 
			
		||||
    self._generators = Array(repeating: Generator(permutation: table), count: octaves)
 | 
			
		||||
    self._amplitudeAdjusted = amplitude / 2
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public extension LayeredNoise where Generator: CoherentNoise2D {
 | 
			
		||||
  func get(_ point: SIMD2<Scalar>) -> Scalar {
 | 
			
		||||
    zip(self._generators, 0..<self.octaves).map { layer, term in
 | 
			
		||||
    zip(self._generators[1...], 1..<self.octaves).map { layer, term in
 | 
			
		||||
      let mul = Scalar(1 + term)
 | 
			
		||||
      return layer.get(point * frequency * mul) / mul
 | 
			
		||||
    }.reduce(0) { $0 + $1 } * amplitude
 | 
			
		||||
      return layer.get(point * self.frequency * mul) / mul
 | 
			
		||||
    }.reduce(self._generators[0].get(point * self.frequency)) {
 | 
			
		||||
      $0 + $1 } * self._amplitudeAdjusted
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public extension LayeredNoise where Generator: CoherentNoise3D {
 | 
			
		||||
  func get(_ point: SIMD3<Scalar>) -> Scalar {
 | 
			
		||||
    zip(self._generators, 0..<self.octaves).map { layer, term in
 | 
			
		||||
    zip(self._generators[1...], 1..<self.octaves).map { layer, term in
 | 
			
		||||
      let mul = Scalar(1 + term)
 | 
			
		||||
      return layer.get(point * frequency * mul) / mul
 | 
			
		||||
    }.reduce(0) { $0 + $1 } * amplitude
 | 
			
		||||
      return layer.get(point * self.frequency * mul) / mul
 | 
			
		||||
    }.reduce(self._generators[0].get(point * self.frequency)) {
 | 
			
		||||
      $0 + $1 } * self._amplitudeAdjusted
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public extension LayeredNoise where Generator: CoherentNoise4D {
 | 
			
		||||
  func get(_ point: SIMD4<Scalar>) -> Scalar {
 | 
			
		||||
    zip(self._generators, 0..<self.octaves).map { layer, term in
 | 
			
		||||
    zip(self._generators[1...], 1..<self.octaves).map { layer, term in
 | 
			
		||||
      let mul = Scalar(1 + term)
 | 
			
		||||
      return layer.get(point * frequency * mul) / mul
 | 
			
		||||
    }.reduce(0) { $0 + $1 } * amplitude
 | 
			
		||||
      return layer.get(point * self.frequency * mul) / mul
 | 
			
		||||
    }.reduce(self._generators[0].get(point * self.frequency)) {
 | 
			
		||||
      $0 + $1 } * self._amplitudeAdjusted
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,8 @@
 | 
			
		||||
import Foundation
 | 
			
		||||
 | 
			
		||||
public struct ImprovedPerlin<Scalar: BinaryFloatingPoint & SIMDScalar>: CoherentNoise2D, CoherentNoise3D, CoherentNoiseRandomInit {
 | 
			
		||||
public struct ImprovedPerlin<Scalar: BinaryFloatingPoint & SIMDScalar>: CoherentNoise2D, CoherentNoise3D, CoherentNoiseRandomInit, CoherentNoiseTableInit {
 | 
			
		||||
  private let p: [Int16]
 | 
			
		||||
 | 
			
		||||
  public init() {
 | 
			
		||||
    self.init(permutation: defaultPermutation)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public init(permutation: [Int16]) {
 | 
			
		||||
    assert(permutation.count == 0x100)
 | 
			
		||||
    self.p = permutation
 | 
			
		||||
@ -90,19 +86,3 @@ public struct ImprovedPerlin<Scalar: BinaryFloatingPoint & SIMDScalar>: Coherent
 | 
			
		||||
    return u + v
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
internal let defaultPermutation: [Int16] = [
 | 
			
		||||
  151,160,137,91,90,15,131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,
 | 
			
		||||
  8, 99,37,240,21,10,23,190, 6,148,247,120,234,75, 0,26,197,62,94,252,219,203,
 | 
			
		||||
  117,35, 11,32,57,177,33, 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,
 | 
			
		||||
  165,71,134,139,48, 27,166,77,146,158,231,83,111,229,122, 60,211,133,230,220,
 | 
			
		||||
  105,92,41,55,46,245,40,244,102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,
 | 
			
		||||
  187,208, 89, 18,169,200,196,135,130,116,188,159, 86,164,100,109,198,173,186,
 | 
			
		||||
  3,64,52,217,226,250,124,123, 5,202, 38,147,118,126,255,82,85,212,207,206,59,
 | 
			
		||||
  227,47,16,58,17,182,189,28,42,223,183,170,213,119,248,152, 2,44,154,163, 70,
 | 
			
		||||
  221,153,101,155,167, 43,172,9,129,22,39,253, 19, 98,108,110, 79,113,224,232,
 | 
			
		||||
  178,185, 112,104,218,246,97,228,251, 34,242,193,238,210,144, 12,191,179,162,
 | 
			
		||||
  241, 81,51,145,235,249,14,239,107,49,192,214, 31,181,199,106,157,184,84,204,
 | 
			
		||||
  176,115,121,50,45,127, 4,150,254,138,236,205,93,222,114,67,29,24,72,243,141,
 | 
			
		||||
  128,195,78,66,215,61,156,180
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
import Foundation
 | 
			
		||||
 | 
			
		||||
public struct SimplexNoise<Scalar: BinaryFloatingPoint & SIMDScalar>: CoherentNoise2D, CoherentNoise3D, CoherentNoise4D, CoherentNoiseRandomInit {
 | 
			
		||||
public struct SimplexNoise<Scalar: BinaryFloatingPoint & SIMDScalar>: CoherentNoise2D, CoherentNoise3D, CoherentNoise4D, CoherentNoiseRandomInit, CoherentNoiseTableInit {
 | 
			
		||||
  private let p: [Int16], pMod12: [Int16]
 | 
			
		||||
 | 
			
		||||
  private let grad3: [SIMD3<Scalar>] = [
 | 
			
		||||
@ -19,10 +19,6 @@ public struct SimplexNoise<Scalar: BinaryFloatingPoint & SIMDScalar>: CoherentNo
 | 
			
		||||
    .init(-1,  1, 1, 0), .init(-1,  1, -1,  0), .init(-1, -1,  1, 0), .init(-1, -1, -1,  0)
 | 
			
		||||
  ]
 | 
			
		||||
 | 
			
		||||
  public init() {
 | 
			
		||||
    self.init(permutation: defaultPermutation)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public init(permutation: [Int16]) {
 | 
			
		||||
    assert(permutation.count == 0x100)
 | 
			
		||||
    self.p = permutation
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user