model batch untz untz untz

This commit is contained in:
a dinosaur 2024-09-06 23:07:53 +10:00
parent 54ed81b15d
commit 34ec6f71eb
3 changed files with 69 additions and 24 deletions

View File

@ -1,5 +1,4 @@
public struct Material {
public struct Material: Hashable {
public var ambient: Color<Float>
public var diffuse: Color<Float>
public var specular: Color<Float>

View File

@ -5,35 +5,67 @@ public struct ModelBatch {
private var _active = false
private var _cam: Camera!
private var _env: Environment!
private var _prev: ModelInstance!
private var _instances: [Instance]
internal init(_ renderer: Renderer) {
self._renderer = renderer
self._instances = Array()
}
//TODO: Sort, Blend
mutating func begin(camera: Camera, environment: Environment) {
public mutating func begin(camera: Camera, environment: Environment) {
self._active = true
self._cam = camera
self._env = environment
self._prev = nil
}
mutating func end() {
private mutating func flush() {
assert(self._instances.count > 0)
if self._instances.count == 1 {
let instance = self._instances.first!
self._renderer.draw(
model: instance.world,
color: instance.color,
mesh: self._prev.mesh,
material: self._prev.material,
environment: self._env,
camera: self._cam)
} else {
self._renderer.batch(
instances: self._instances,
mesh: self._prev.mesh,
material: self._prev.material,
environment: self._env,
camera: self._cam)
}
self._instances.removeAll(keepingCapacity: true)
self._prev = nil
}
public mutating func end() {
if !self._instances.isEmpty {
self.flush()
}
self._cam = nil
self._env = nil
self._active = false
}
mutating func draw(_ model: ModelInstance, position: SIMD3<Float>, color: Color<Float> = .white
public mutating func draw(_ model: ModelInstance, position: SIMD3<Float>, color: Color<Float> = .white
) {
self.draw(model, world: .translate(position), color: color)
}
mutating func draw(_ model: ModelInstance,
public mutating func draw(_ model: ModelInstance,
position: SIMD3<Float>, scale: Float, rotation: simd_quatf,
color: Color<Float> = .white
) {
self.draw(model, position: position, scale: .init(repeating: scale), rotation: rotation, color: color)
}
mutating func draw(_ model: ModelInstance,
public mutating func draw(_ model: ModelInstance,
position: SIMD3<Float>, scale: SIMD3<Float>, rotation: simd_quatf,
color: Color<Float> = .white
) {
@ -44,30 +76,33 @@ public struct ModelBatch {
self.draw(model, world: world, color: color)
}
mutating func draw(_ model: ModelInstance, world: simd_float4x4, color: Color<Float> = .white) {
public mutating func draw(_ model: ModelInstance, world: simd_float4x4, color: Color<Float> = .white) {
assert(self._active)
self._renderer.draw(
model: world,
color: color.linear,
mesh: model.mesh,
material: model.material,
environment: self._env,
camera: self._cam)
if self._prev == nil {
self._prev = model
} else if model != self._prev {
self.flush()
self._prev = model
}
self._instances.append(.init(
world: world,
color: color.linear))
}
internal struct Instance {
let model: simd_float4x4
let world: simd_float4x4
let color: Color<Float>
init(model: simd_float4x4, color: Color<Float> = .white) {
self.model = model
init(world: simd_float4x4, color: Color<Float> = .white) {
self.world = world
self.color = color
}
}
}
//TODO: delet
public struct ModelInstance {
public struct ModelInstance: Hashable {
let mesh: RendererMesh
let material: Material
}

View File

@ -452,8 +452,8 @@ public class Renderer {
for i in 0..<numInstances {
let instance = instances[i]
data[i] = VertexShaderInstance(
model: instance.model,
normalModel: instance.model.inverse.transpose,
model: instance.world,
normalModel: instance.world.inverse.transpose,
color: SIMD4(instance.color))
}
}
@ -487,10 +487,21 @@ public class Renderer {
}
}
public struct RendererMesh {
fileprivate let _vertBuf: MTLBuffer
fileprivate let _idxBuf: MTLBuffer
public struct RendererMesh: Hashable {
fileprivate let _vertBuf: MTLBuffer, _idxBuf: MTLBuffer
public let numIndices: Int
public static func == (lhs: Self, rhs: Self) -> Bool {
lhs._vertBuf.gpuAddress == rhs._vertBuf.gpuAddress && lhs._vertBuf.length == rhs._vertBuf.length &&
lhs._vertBuf.gpuAddress == rhs._vertBuf.gpuAddress && lhs._vertBuf.length == rhs._vertBuf.length &&
lhs.numIndices == rhs.numIndices
}
public func hash(into hasher: inout Hasher) {
hasher.combine(self._vertBuf.hash)
hasher.combine(self._idxBuf.hash)
hasher.combine(self.numIndices)
}
}
extension MTLClearColor {