Upgrade to Pro — share decks privately, control downloads, hide ads and more …

作ってわかるレンダリングパイプライン〜CPUで3D描画〜

ta_ka_tsu
September 02, 2018

 作ってわかるレンダリングパイプライン〜CPUで3D描画〜

iOSDC 2018 発表資料

ta_ka_tsu

September 02, 2018
Tweet

More Decks by ta_ka_tsu

Other Decks in Technology

Transcript

  1. ϥελϥΠζɿϑϥάϝϯτͷ஋ P0 P1 P s t P = t s

    + t P0 + s s + t P1 = w0 P0 + w1 P1 (w0 + w1 = 1) AP = w0 AP0 + w1 AP1 AX ɿ఺ X ͷଐੑ஋
  2. ϥελϥΠζɿϑϥάϝϯτͷ஋ P0 P1 Q s1 t1 Q = t1 s1

    + t1 P0 + s1 s1 + t1 P1 = w0 P0 + w1 P1 + w2 P2 (w0 + w1 + w2 = 1) P P2 s2 t2 P = t2 s2 + t2 Q + s2 s2 + t2 P2 AP = w0 AP0 + w1 AP1 + w2 AP2
  3. ϐΫηϧૢ࡞ɿσϓεςετ Φϓγϣϯ ௨աͨ͠;஋Λ ্ॻ͖ 0.6 0.4 0.2 σϓεόοϑΝ 0.6 0.4

    0.2 0.6 0.4 0.2 0.6 0.4 0.2 0.5 0.5 0.5 0.5 0.5 0.5 0.6 0.5 0.5 0.6 0.5 0.5 0.6 0.4 0.5 0.6 0.4 0.2 0.5 0.5 0.5 0.5 0.5 σϓεόοϑΝ ϑϥά ϝϯτ ϑϥά ϝϯτ
  4. ࠞͥ߹ΘͤՄೳͳܕ protocol Addable { static func +(lhs:Self, rhs:Self) -> Self

    } protocol Scalable { static func *(scale:Float, value:Self) -> Self } protocol Blendable : Addable, Scalable { }
  5. ৭ͷ४උ struct Color4f : Blendable { let r: Float let

    g: Float let b: Float let a: Float }
  6. ௖఺ͷ४උ class Vertex3<T:Blendable> { var position : float3 var attribute

    : T . . . } class Vertex4<T:Blendable> { var position : float4 var attribute : T . . . }
  7. ϑϨʔϜόοϑΝͷ४උ protocol BufferPlane { associatedtype CellType var width: Int {

    get } var height: Int { get } subscript(x: Int, y: Int) -> CellType { get set } }
  8. class ColorBuffer : BufferPlane { let width: Int let height:

    Int subscript (x: Int, y: Int) -> Color4ui { . . . } } ϑϨʔϜόοϑΝͷ४උ
  9. class DepthBuffer : BufferPlane { let width: Int let height:

    Int subscript (x: Int, y: Int) -> Float { . . . } } ϑϨʔϜόοϑΝͷ४උ
  10. Ϗϡʔϙʔτͷ४උ class Viewport { let x: Int let y: Int

    let width: Int let height: Int . . . }
  11. ύΠϓϥΠϯͷ४උ class RenderPipeline<T:Blendable, U:Blendable> { var vertexBuffer : [Vertex4<T>]! var

    viewport: Viewport? var vertexShader : ((Vertex4<T>) -> Vertex4<U>)! var fragmentShader : ((Fragment<U>) -> Color4f?)! var colorBuffer : ColorBuffer! var depthBuffer : DepthBuffer? . . . }
  12. ௖఺ॲཧ let convertedVertices = vertexBuffer.map { (vertex:Vertex4<T>) -> Vertex3<U> in

    let v = vertexShader(vertex) // divide by w let pos = v.position.project() // Viewport Transformation let screenPosition = transform(position: pos, toViewport: vp) return Vertex3<U>(position: screenPosition, attribute: v.attribute) }
  13. ϓϦϛςΟϒΞηϯϒϦ var primitives: [Primitive<U>] . . . let numOfTriangles =

    convertedVertices.count / 3 primitives = (0..<numOfTriangles).map { Primitive<U>.triangle(convertedVertices[$0*3], convertedVertices[$0*3 + 1], convertedVertices[$0*3 + 2]) }.filter{ (primitive) -> Bool in if cullFace { return primitive.isCCW() } else { return true } }
  14. ϥελϥΠζ var result = [Fragment<U>]() . . .// minX, maxX,

    minY, maxYΛٻΊ͓ͯ͘ for py in minY..<maxY { for px in minX..<maxX { let p = float2(Float(px) + 0.5, Float(py) + 0.5) let (w1, w2, w3) = weight(v1: v1, v2: v2, v3: v3, of: p) ?? (-1, -1, -1) if w1 < 0 || w2 < 0 || w3 < 0 { continue } let eachZ = w1 * v1.position.z + w2 * v2.position.z + w3 * v3.position.z let eachAttr = w1 * v1.attribute + w2 * v2.attribute + w3 * v3.attribute result.append(Fragment(x: px, y: py, z: eachZ, attribute: eachAttr)) } }
  15. ϑϥά ϝϯτॲཧ // Fragment Processing let fragmentResults = fragments.map{ (fragment)

    -> Fragment<Color4f>? in if let color = fragmentShader(fragment) { return Fragment<Color4f>( x: fragment.x, y: fragment.y, z: fragment.z, attribute: color) } else { return nil } }.compactMap { $0 }
  16. ϐΫηϧૢ࡞ // Per Sampling Operation fragmentResults.forEach { (fragment) in if

    let depthBuffer = depthBuffer { if depthBuffer[fragment.x, fragment.y] > fragment.z { return } depthBuffer[fragment.x, fragment.y] = fragment.z } colorBuffer[fragment.x, fragment.y] = fragment.attribute.toColor4ui() }