mirror of
				https://github.com/GayPizzaSpecifications/voxelotl-engine.git
				synced 2025-11-04 02:59:37 +00:00 
			
		
		
		
	technicolour icecream hellscape terrain
This commit is contained in:
		@ -24,7 +24,7 @@ class Game: GameDelegate {
 | 
				
			|||||||
  var camera = Camera(fov: 60, size: .one, range: 0.06...900)
 | 
					  var camera = Camera(fov: 60, size: .one, range: 0.06...900)
 | 
				
			||||||
  var player = Player()
 | 
					  var player = Player()
 | 
				
			||||||
  var projection: matrix_float4x4 = .identity
 | 
					  var projection: matrix_float4x4 = .identity
 | 
				
			||||||
  var world = World()
 | 
					  var world = World(generator: StandardWorldGenerator())
 | 
				
			||||||
  var cubeMesh: RendererMesh?
 | 
					  var cubeMesh: RendererMesh?
 | 
				
			||||||
  var renderChunks = [SIMD3<Int>: RendererMesh]()
 | 
					  var renderChunks = [SIMD3<Int>: RendererMesh]()
 | 
				
			||||||
  var chunkMeshGeneration: ChunkMeshGeneration!
 | 
					  var chunkMeshGeneration: ChunkMeshGeneration!
 | 
				
			||||||
@ -42,7 +42,7 @@ class Game: GameDelegate {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private func resetPlayer() {
 | 
					  private func resetPlayer() {
 | 
				
			||||||
    self.player.position = .init(repeating: 0.5) + .up * Float(Chunk.size)
 | 
					    self.player.position = .init(repeating: 0.5) + .up * Float(Chunk.size) * 1.6
 | 
				
			||||||
    self.player.velocity = .zero
 | 
					    self.player.velocity = .zero
 | 
				
			||||||
    self.player.rotation = .init(.pi, 0)
 | 
					    self.player.rotation = .init(.pi, 0)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,7 @@
 | 
				
			|||||||
struct StandardWorldGenerator: WorldGenerator {
 | 
					struct StandardWorldGenerator: WorldGenerator {
 | 
				
			||||||
  var noise: ImprovedPerlin<Float>!, noise2: SimplexNoise<Float>!
 | 
					  private var heightNoise: LayeredNoiseAlt<SimplexNoise<Float>>!
 | 
				
			||||||
 | 
					  private var terrainNoise: LayeredNoise<SimplexNoise<Float>>!
 | 
				
			||||||
 | 
					  private var colorNoise: LayeredNoise<ImprovedPerlin<Float>>!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public mutating func reset(seed: UInt64) {
 | 
					  public mutating func reset(seed: UInt64) {
 | 
				
			||||||
    var random: any RandomProvider
 | 
					    var random: any RandomProvider
 | 
				
			||||||
@ -10,29 +12,33 @@ struct StandardWorldGenerator: WorldGenerator {
 | 
				
			|||||||
    random = PCG32Random(seed: initialState)
 | 
					    random = PCG32Random(seed: initialState)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    self.noise = ImprovedPerlin<Float>(random: &random)
 | 
					    self.heightNoise = .init(random: &random, octaves: 200, frequency: 0.0002, amplitude: 2)
 | 
				
			||||||
    self.noise2 = SimplexNoise<Float>(random: &random)
 | 
					    self.terrainNoise = .init(random: &random, octaves: 10, frequency: 0.01, amplitude: 0.337)
 | 
				
			||||||
 | 
					    self.colorNoise = .init(random: &random, octaves: 150, frequency: 0.00366, amplitude: 2)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public func makeChunk(id chunkID: SIMD3<Int>) -> Chunk {
 | 
					  public func makeChunk(id chunkID: SIMD3<Int>) -> Chunk {
 | 
				
			||||||
    let chunkOrigin = chunkID &<< Chunk.shift
 | 
					    let chunkOrigin = chunkID &<< Chunk.shift
 | 
				
			||||||
    var chunk = Chunk(position: chunkOrigin)
 | 
					    var chunk = Chunk(position: chunkOrigin)
 | 
				
			||||||
    chunk.fill(allBy: { position in
 | 
					    for z in 0..<Chunk.size {
 | 
				
			||||||
      let fpos = SIMD3<Float>(chunkOrigin &+ position)
 | 
					      for x in 0..<Chunk.size {
 | 
				
			||||||
        let threshold: Float = 0.6
 | 
					        let height = self.heightNoise.get(SIMD2<Float>(chunkOrigin.xz &+ SIMD2<Int>(x, z)))
 | 
				
			||||||
        let value = fpos.y / 16.0
 | 
					        for y in 0..<Chunk.size {
 | 
				
			||||||
          + self.noise.get(fpos * 0.05) * 1.1
 | 
					          let ipos = SIMD3(x, y, z)
 | 
				
			||||||
          + self.noise.get(fpos * 0.10) * 0.5
 | 
					          let fpos = SIMD3<Float>(chunkOrigin &+ ipos)
 | 
				
			||||||
          + self.noise.get(fpos * 0.30) * 0.23
 | 
					          let height = fpos.y / 64.0 + height
 | 
				
			||||||
      return if value < threshold {
 | 
					          let value = height + self.terrainNoise.get(fpos)
 | 
				
			||||||
 | 
					          let block: BlockType = if value < 0 {
 | 
				
			||||||
            .solid(.init(
 | 
					            .solid(.init(
 | 
				
			||||||
          hue:        Float(180 + self.noise2.get(fpos * 0.05) * 180),
 | 
					              hue: Float(180 + self.colorNoise.get(fpos) * 180),
 | 
				
			||||||
          saturation: Float(0.5 + self.noise2.get(SIMD4(fpos * 0.05, 4)) * 0.5),
 | 
					              saturation: 0.7, value: 0.9).linear)
 | 
				
			||||||
          value:      Float(0.5 + self.noise2.get(SIMD4(fpos * 0.05, 9)) * 0.5).lerp(0.5, 1)).linear)
 | 
					 | 
				
			||||||
          } else {
 | 
					          } else {
 | 
				
			||||||
            .air
 | 
					            .air
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
    })
 | 
					          chunk.setBlock(internal: ipos, type: block)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    return chunk
 | 
					    return chunk
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
protocol WorldGenerator {
 | 
					public protocol WorldGenerator {
 | 
				
			||||||
  mutating func reset(seed: UInt64)
 | 
					  mutating func reset(seed: UInt64)
 | 
				
			||||||
  func makeChunk(id: SIMD3<Int>) -> Chunk
 | 
					  func makeChunk(id: SIMD3<Int>) -> Chunk
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -58,3 +58,51 @@ public extension LayeredNoise where Generator: CoherentNoise4D {
 | 
				
			|||||||
      $0 + $1 } * self._amplitudeAdjusted
 | 
					      $0 + $1 } * self._amplitudeAdjusted
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//MARK: - Experimental
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public struct LayeredNoiseAlt<Generator: CoherentNoise> {
 | 
				
			||||||
 | 
					  public typealias Scalar = Generator.Scalar
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public let octaves: Int
 | 
				
			||||||
 | 
					  public let frequency: Scalar
 | 
				
			||||||
 | 
					  public let amplitude: Scalar
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private let _generator: Generator
 | 
				
			||||||
 | 
					  private let _amplitudeAdjusted: Scalar
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public extension LayeredNoiseAlt where Generator: CoherentNoiseRandomInit {
 | 
				
			||||||
 | 
					  init<Random: RandomProvider>(random: inout Random, octaves: Int, frequency: Scalar, amplitude: Scalar = 1) {
 | 
				
			||||||
 | 
					    self.octaves   = octaves
 | 
				
			||||||
 | 
					    self.frequency = frequency
 | 
				
			||||||
 | 
					    self.amplitude = amplitude
 | 
				
			||||||
 | 
					    self._generator = Generator(random: &random)
 | 
				
			||||||
 | 
					    self._amplitudeAdjusted = amplitude / 2
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public extension LayeredNoiseAlt where Generator: CoherentNoise3D & CoherentNoise2D {
 | 
				
			||||||
 | 
					  func get(_ point: SIMD2<Scalar>) -> Scalar {
 | 
				
			||||||
 | 
					    let layerOffset: Int = 1
 | 
				
			||||||
 | 
					    return (1..<self.octaves).map { term in
 | 
				
			||||||
 | 
					      let mul = Scalar(1 + term)
 | 
				
			||||||
 | 
					      let point3D = SIMD3(point * frequency * mul, Scalar(term * layerOffset))
 | 
				
			||||||
 | 
					      return self._generator.get(point3D) / mul
 | 
				
			||||||
 | 
					    }.reduce(self._generator.get(point * frequency)) {
 | 
				
			||||||
 | 
					      $0 + $1 } * self._amplitudeAdjusted
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public extension LayeredNoiseAlt where Generator: CoherentNoise4D & CoherentNoise3D {
 | 
				
			||||||
 | 
					  func get(_ point: SIMD3<Scalar>) -> Scalar {
 | 
				
			||||||
 | 
					    let layerOffset: Int = 1
 | 
				
			||||||
 | 
					    return (1..<self.octaves).map { term in
 | 
				
			||||||
 | 
					      let mul = Scalar(1 + term)
 | 
				
			||||||
 | 
					      let point4D = SIMD4(point * frequency * mul, Scalar(term * layerOffset))
 | 
				
			||||||
 | 
					      return self._generator.get(point4D) / mul
 | 
				
			||||||
 | 
					    }.reduce(self._generator.get(point * frequency)) {
 | 
				
			||||||
 | 
					      $0 + $1 } * self._amplitudeAdjusted
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -3,22 +3,6 @@ import Foundation
 | 
				
			|||||||
public struct SimplexNoise<Scalar: BinaryFloatingPoint & SIMDScalar>: CoherentNoise2D, CoherentNoise3D, CoherentNoise4D, CoherentNoiseRandomInit, CoherentNoiseTableInit {
 | 
					public struct SimplexNoise<Scalar: BinaryFloatingPoint & SIMDScalar>: CoherentNoise2D, CoherentNoise3D, CoherentNoise4D, CoherentNoiseRandomInit, CoherentNoiseTableInit {
 | 
				
			||||||
  private let p: [Int16], pMod12: [Int16]
 | 
					  private let p: [Int16], pMod12: [Int16]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private let grad3: [SIMD3<Scalar>] = [
 | 
					 | 
				
			||||||
    .init(1, 1, 0), .init(-1,  1, 0), .init(1, -1,  0), .init(-1, -1,  0),
 | 
					 | 
				
			||||||
    .init(1, 0, 1), .init(-1,  0, 1), .init(1,  0, -1), .init(-1,  0, -1),
 | 
					 | 
				
			||||||
    .init(0, 1, 1), .init( 0, -1, 1), .init(0,  1, -1), .init( 0, -1, -1)
 | 
					 | 
				
			||||||
  ]
 | 
					 | 
				
			||||||
  private let grad4: [SIMD4<Scalar>] = [
 | 
					 | 
				
			||||||
    .init( 0,  1, 1, 1), .init( 0,  1,  1, -1), .init( 0,  1, -1, 1), .init( 0,  1, -1, -1),
 | 
					 | 
				
			||||||
    .init( 0, -1, 1, 1), .init( 0, -1,  1, -1), .init( 0, -1, -1, 1), .init( 0, -1, -1, -1),
 | 
					 | 
				
			||||||
    .init( 1,  0, 1, 1), .init( 1,  0,  1, -1), .init( 1,  0, -1, 1), .init( 1,  0, -1, -1),
 | 
					 | 
				
			||||||
    .init(-1,  0, 1, 1), .init(-1,  0,  1, -1), .init(-1,  0, -1, 1), .init(-1,  0, -1, -1),
 | 
					 | 
				
			||||||
    .init( 1,  1, 0, 1), .init( 1,  1,  0, -1), .init( 1, -1,  0, 1), .init( 1, -1,  0, -1),
 | 
					 | 
				
			||||||
    .init(-1,  1, 0, 1), .init(-1,  1,  0, -1), .init(-1, -1,  0, 1), .init(-1, -1,  0, -1),
 | 
					 | 
				
			||||||
    .init( 1,  1, 1, 0), .init( 1,  1, -1,  0), .init( 1, -1,  1, 0), .init( 1, -1, -1,  0),
 | 
					 | 
				
			||||||
    .init(-1,  1, 1, 0), .init(-1,  1, -1,  0), .init(-1, -1,  1, 0), .init(-1, -1, -1,  0)
 | 
					 | 
				
			||||||
  ]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  public init(permutation: [Int16]) {
 | 
					  public init(permutation: [Int16]) {
 | 
				
			||||||
    assert(permutation.count == 0x100)
 | 
					    assert(permutation.count == 0x100)
 | 
				
			||||||
    self.p = permutation
 | 
					    self.p = permutation
 | 
				
			||||||
@ -58,7 +42,7 @@ public struct SimplexNoise<Scalar: BinaryFloatingPoint & SIMDScalar>: CoherentNo
 | 
				
			|||||||
        return 0
 | 
					        return 0
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        t *= t
 | 
					        t *= t
 | 
				
			||||||
        return t * t * self.grad3[gradID].xy.dot(corner)
 | 
					        return t * t * SIMD2<Scalar>(grad3[gradID].xy).dot(corner)
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    let noise0 = cornerContribution(corner0, gradIndex0)
 | 
					    let noise0 = cornerContribution(corner0, gradIndex0)
 | 
				
			||||||
@ -125,7 +109,7 @@ public struct SimplexNoise<Scalar: BinaryFloatingPoint & SIMDScalar>: CoherentNo
 | 
				
			|||||||
        return 0
 | 
					        return 0
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        t *= t
 | 
					        t *= t
 | 
				
			||||||
        return t * t * self.grad3[gradID].dot(corner)
 | 
					        return t * t * SIMD3<Scalar>(grad3[gradID]).dot(corner)
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    let noise0 = cornerContribution(corner0, gradCorner0)
 | 
					    let noise0 = cornerContribution(corner0, gradCorner0)
 | 
				
			||||||
@ -197,7 +181,7 @@ public struct SimplexNoise<Scalar: BinaryFloatingPoint & SIMDScalar>: CoherentNo
 | 
				
			|||||||
        return 0
 | 
					        return 0
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        t *= t
 | 
					        t *= t
 | 
				
			||||||
        return t * t * self.grad4[gradID].dot(corner)
 | 
					        return t * t * SIMD4<Scalar>(grad4[gradID]).dot(corner)
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    let noise0 = cornerContribution(corner0, gradIndex0)
 | 
					    let noise0 = cornerContribution(corner0, gradIndex0)
 | 
				
			||||||
@ -212,3 +196,20 @@ public struct SimplexNoise<Scalar: BinaryFloatingPoint & SIMDScalar>: CoherentNo
 | 
				
			|||||||
  @inline(__always) fileprivate func perm(_ idx: Int) -> Int { Int(self.p[idx & 0xFF]) }
 | 
					  @inline(__always) fileprivate func perm(_ idx: Int) -> Int { Int(self.p[idx & 0xFF]) }
 | 
				
			||||||
  @inline(__always) fileprivate func permMod12(_ idx: Int) -> Int { Int(self.pMod12[idx & 0xFF]) }
 | 
					  @inline(__always) fileprivate func permMod12(_ idx: Int) -> Int { Int(self.pMod12[idx & 0xFF]) }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fileprivate let grad3: [SIMD3<Int16>] = [
 | 
				
			||||||
 | 
					  .init(1, 1, 0), .init(-1,  1, 0), .init(1, -1,  0), .init(-1, -1,  0),
 | 
				
			||||||
 | 
					  .init(1, 0, 1), .init(-1,  0, 1), .init(1,  0, -1), .init(-1,  0, -1),
 | 
				
			||||||
 | 
					  .init(0, 1, 1), .init( 0, -1, 1), .init(0,  1, -1), .init( 0, -1, -1)
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fileprivate let grad4: [SIMD4<Int16>] = [
 | 
				
			||||||
 | 
					  .init( 0,  1, 1, 1), .init( 0,  1,  1, -1), .init( 0,  1, -1, 1), .init( 0,  1, -1, -1),
 | 
				
			||||||
 | 
					  .init( 0, -1, 1, 1), .init( 0, -1,  1, -1), .init( 0, -1, -1, 1), .init( 0, -1, -1, -1),
 | 
				
			||||||
 | 
					  .init( 1,  0, 1, 1), .init( 1,  0,  1, -1), .init( 1,  0, -1, 1), .init( 1,  0, -1, -1),
 | 
				
			||||||
 | 
					  .init(-1,  0, 1, 1), .init(-1,  0,  1, -1), .init(-1,  0, -1, 1), .init(-1,  0, -1, -1),
 | 
				
			||||||
 | 
					  .init( 1,  1, 0, 1), .init( 1,  1,  0, -1), .init( 1, -1,  0, 1), .init( 1, -1,  0, -1),
 | 
				
			||||||
 | 
					  .init(-1,  1, 0, 1), .init(-1,  1,  0, -1), .init(-1, -1,  0, 1), .init(-1, -1,  0, -1),
 | 
				
			||||||
 | 
					  .init( 1,  1, 1, 0), .init( 1,  1, -1,  0), .init( 1, -1,  1, 0), .init( 1, -1, -1,  0),
 | 
				
			||||||
 | 
					  .init(-1,  1, 1, 0), .init(-1,  1, -1,  0), .init(-1, -1,  1, 0), .init(-1, -1, -1,  0)
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
				
			|||||||
@ -12,10 +12,10 @@ public class World {
 | 
				
			|||||||
  private var _generator: any WorldGenerator
 | 
					  private var _generator: any WorldGenerator
 | 
				
			||||||
  private var _chunkGeneration: ChunkGeneration
 | 
					  private var _chunkGeneration: ChunkGeneration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public init() {
 | 
					  public init(generator: any WorldGenerator) {
 | 
				
			||||||
    self._chunks = [:]
 | 
					    self._chunks = [:]
 | 
				
			||||||
    self._chunkDamage = []
 | 
					    self._chunkDamage = []
 | 
				
			||||||
    self._generator = TerrorTowerGenerator()
 | 
					    self._generator = generator
 | 
				
			||||||
    self._chunkGeneration = ChunkGeneration(queue: .global(qos: .userInitiated))
 | 
					    self._chunkGeneration = ChunkGeneration(queue: .global(qos: .userInitiated))
 | 
				
			||||||
    self._chunkGeneration.world = self
 | 
					    self._chunkGeneration.world = self
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user