Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
作ってわかるレンダリングパイプライン〜CPUで3D描画〜
Search
ta_ka_tsu
September 02, 2018
Technology
2.5k
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
作ってわかるレンダリングパイプライン〜CPUで3D描画〜
iOSDC 2018 発表資料
ta_ka_tsu
September 02, 2018
More Decks by ta_ka_tsu
See All by ta_ka_tsu
めくるめくシェーダーアートの世界/The World of Dazzling Shader Art
takatsu
10
6.6k
AVSpeechSynthesizerにひたすら読ませる
takatsu
0
820
Other Decks in Technology
See All in Technology
Does an AI Watermark Survive Translation?
machinetranslation
0
520
AIで実装は速くなった。なのにプロダクトは速くならない。職能の壁を越えて価値のフローを設計する
nwiizo
6
7k
[RSJ26] NarrativeFlow: Flow-Based Vision-Language-Action Model Using Robot Velocity Fields
keio_smilab
PRO
0
150
Driving AI Adoption Using In-House GPUs to Serve Qwen
po3rin
2
440
2026-09-04 SRE Tech Talk #15 怠惰なTerraform / Lazy Terraform
masasuzu
0
190
いま、生成AIにKaggleをどこまで 任せられるか — ROGIIコンペでの進め方とTips
k951286
3
1.4k
Where Is JetBrains AI Heading- — Central CLI, Air Alpha, and the Agentic Development Stack
x5gtrn
PRO
0
120
Genie Code ワークショップ 基礎編 / Genie-Code-Workshop-fundamental
databricksjapan
PRO
0
350
Bet AI Day 2026丨Agentは、「金融」という巨大産業の何を変えられるのか
layerx
PRO
0
740
Azure App Service / Container Apps の組み込み認証
kuniteru
0
190
少人数データチームのDevin活用実践事例
runandy16
2
430
KPIだけでは評価できないプロダクトが考えるべき Evalsという第二の評価系 / Beyond KPIs: Evals as a Second Evaluation Framework for Products #PdEConf
aki_iinuma
4
3.5k
Featured
See All Featured
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Prompt Engineering for Job Search
mfonobong
0
440
Claude Code のすすめ
schroneko
67
230k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.6k
Visualization
eitanlees
152
17k
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
230
Building Flexible Design Systems
yeseniaperezcruz
330
41k
How to make the Groovebox
asonas
2
2.4k
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.5k
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
840
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
3k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.5k
Transcript
࡞ͬͯΘ͔Δ ϨϯμϦϯά ύΠϓϥΠϯ d$16Ͱ%ඳըd iOSDC Japan 2018
!UB@LB@UTV ذෞݝࡏॅ ࣗݾհ
!UB@LB@UTV ذෞݝࡏॅ ࣗݾհ %$"%ܥϓϩάϥϚʔ
!UB@LB@UTV ذෞݝࡏॅ ࣗݾհ %$"%ܥϓϩάϥϚʔ %$".ܥϓϩάϥϚʔ
!UB@LB@UTV ذෞݝࡏॅ ࣗݾհ %$"%ܥϓϩάϥϚʔ %$".ܥϓϩάϥϚʔ ձࣾઃཱ
!UB@LB@UTV ذෞݝࡏॅ ࣗݾհ %$"%ܥϓϩάϥϚʔ %$".ܥϓϩάϥϚʔ ϑϦʔϥϯεˡ/PX ձࣾઃཱ
!UB@LB@UTV ذෞݝࡏॅ ࣗݾհ %$"%ܥϓϩάϥϚʔ %$".ܥϓϩάϥϚʔ ϑϦʔϥϯεˡ/PX ձࣾઃཱ
֓ཁ ཧղ ղ ࠶ߏங ϨϯμϦϯά ύΠϓϥΠϯͷ
ཧղ ϨϯμϦϯά ύΠϓϥΠϯͷ 6OEFSTUBOEJOH
σʔλ͔Βը૾ͳͲΛಘΔ͜ͱ ϨϯμϦϯά ύΠϓϥΠϯͱ ϨϯμϦϯάɿ ෳͷॲཧΛྻʹܨ͍ͩҰ࿈ͷॲཧ ύΠϓϥΠϯɿ %άϥϑΟοΫεΛܭࢉ͢Δ ॲཧํࣜͷͭ
ϨϯμϦϯά ύΠϓϥΠϯͰඳ͚Δͷ ɾ
ɾ ɾઢ ϨϯμϦϯά ύΠϓϥΠϯͰඳ͚Δͷ
ɾ ɾઢ ɾࡾ֯ܗ ϨϯμϦϯά ύΠϓϥΠϯͰඳ͚Δͷ
ɾ ɾઢ ɾࡾ֯ܗ ϙϦΰϯ ϓϦϛςΟϒ ϓϦϛςΟϒ
ɾʜͭ ɾઢʜͭ ɾࡾ֯ܗʜͭ ϓϦϛςΟϒ
ଐੑ ଐੑ ɾҐஔ
ଐੑ ɾ৭ ଐੑ ɾҐஔ
ଐੑ ɾ৭ ଐੑ ɾҐஔ ɾ๏ઢϕΫτϧ ɾʜ ɾςΫενϟ࠲ඪ
%σʔλ ύΠϓϥΠϯ ϨϯμϦϯά ϑϨʔϜόοϑΝ ϨϯμϦϯάύΠϓϥΠϯͷೖग़ྗ
ϨϯμϦϯάύΠϓϥΠϯͷೖग़ྗ ྻ ύΠϓϥΠϯ ϨϯμϦϯά ϑϨʔϜόοϑΝ
ϨϯμϦϯάύΠϓϥΠϯͷೖग़ྗ ྻ ύΠϓϥΠϯ ϨϯμϦϯά ϑϨʔϜόοϑΝ
ϨϯμϦϯάύΠϓϥΠϯͷೖग़ྗ ྻ 6OJGPSN ڞ௨σʔλ ύΠϓϥΠϯ ϨϯμϦϯά ϑϨʔϜόοϑΝ
ϨϯμϦϯάύΠϓϥΠϯͷೖग़ྗ ྻ ύΠϓϥΠϯ ϨϯμϦϯά ϑϨʔϜόοϑΝ ඳը໋ྩ %SBX$BMM 6OJGPSN ڞ௨σʔλ
%FDPNQPTJUJPO ղ ϨϯμϦϯά ύΠϓϥΠϯͷ
ϨϯμϦϯάύΠϓϥΠϯͷೖग़ྗ ྻ ϑϨʔϜόοϑΝ 6OJGPSN ڞ௨σʔλ ύΠϓϥΠϯ ϨϯμϦϯά
ϨϯμϦϯάύΠϓϥΠϯͷೖग़ྗ ྻ ϓϦϛςΟϒΞηϯϒϦ ॲཧ ϥελϥΠζ ϑϥάϝϯτॲཧ ϐΫηϧૢ࡞ 6OJGPSN ڞ௨σʔλ ϑϨʔϜόοϑΝ
ॲཧ ϓϦϛςΟϒΞηϯϒϦ ϥελϥΠζ ϑϥάϝϯτॲཧ ϐΫηϧૢ࡞ ϑϨʔϜόοϑΝ ྻ ॲཧ
ॲཧ ྻ ೖྗɿ ྻ ग़ྗɿ ॲཧ
ॲཧɿγΣʔμʔ γΣʔμʔ ڞ௨σʔλ ɾଐੑ" ɾҐஔ ɾଐੑ# ɾଐੑ$ ɾଐੑ%
ɾҐஔ ɾଐੑ&
ॲཧɿγΣʔμʔ ɾ৭ ɾҐஔ ɾ๏ઢϕΫτϧ ɾ৭ ɾҐஔ ଐੑ ଐੑ γΣʔμʔ
ॲཧɿΫϦοϐϯά ΫϦοϐϯάۭؒ .FUBMͰ −1 ≦ x ≦ 1 −1 ≦
y ≦ 1 0 ≦ z ≦ 1
ॲཧɿΫϦοϐϯά
ॲཧɿΫϦοϐϯά
ॲཧɿΫϦοϐϯά
ॲཧɿΫϦοϐϯά
ॲཧɿΫϦοϐϯά
ॲཧɿΫϦοϐϯά
ॲཧɿΫϦοϐϯά
ॲཧɿϏϡʔϙʔτม ΫϦοϐϯάۭؒ Ϗϡʔ Ϗϡʔϙʔτ Y Z
ॲཧɿϏϡʔϙʔτม ΫϦοϐϯάۭؒ Ϗϡʔ Ϗϡʔϙʔτ Y Z
ϓϦ ϛ ςΟϒ ΞηϯϒϦ ϥελϥΠζ ϑϥάϝϯτॲཧ ϐΫηϧૢ࡞ ϑϨʔϜόοϑΝ ྻ ॲཧ
ϓϦϛςΟϒΞηϯϒϦ
ϓϦϛςΟϒΞηϯϒϦ ྻ ೖྗɿ ϓϦϛςΟϒྻ ग़ྗɿ ϓϦϛςΟϒ ΞηϯϒϦ
ϓϦϛςΟϒΞηϯϒϦ V[0] V[1] V[2] V[3] V[4]
1PJOUT ϓϦϛςΟϒΞηϯϒϦ V[1] V[2] V[3] V[4] Point[0] Point[1] Point[2] Point[3]
Point[4] V[0]
-JOFT ϓϦϛςΟϒΞηϯϒϦ V[0] V[1] V[2] V[3] V[4] Line[0] Line[1]
-JOF4USJQ ϓϦϛςΟϒΞηϯϒϦ V[0] V[1] V[2] V[3] V[4] Line[0] Line[1] Line[2]
Line[3]
5SJBOHMFT ϓϦϛςΟϒΞηϯϒϦ V[0] V[1] V[2] V[3] V[4] Triangle[0]
5SJBOHMF4USJQ ϓϦϛςΟϒΞηϯϒϦ V[0] V[1] V[2] V[3] V[4] Triangle[0] Triangle[1] Triangle[2]
5SJBOHMF'BO ϓϦϛςΟϒΞηϯϒϦ -JOF-PPQ Triangle[0] Triangle[1] Triangle[2] Line[0] Line[1] Line[2] Line[3]
Line[4] V[0] V[1] V[2] V[3] V[4] V[4] V[0] V[1] V[2] V[3]
ϓϦϛςΟϒΞηϯϒϦɿΧϦϯά Φϓγϣϯ
ϓϦϛςΟϒΞηϯϒϦɿΧϦϯά Φϓγϣϯ
ϓϦϛςΟϒΞηϯϒϦɿΧϦϯά Φϓγϣϯ
ϓϦϛςΟϒΞηϯϒϦɿΧϦϯά Φϓγϣϯ ໘ͷ͖ʁ
0 2 1 ࣌ܭճΓ $8 ϓϦϛςΟϒΞηϯϒϦɿΧϦϯά Φϓγϣϯ 0 1 2
࣌ܭճΓ $$8 PS
ϥελϥΠζ ϓϦϛςΟϒΞηϯϒϦ ϑϥάϝϯτॲཧ ϐΫηϧૢ࡞ ϑϨʔϜόοϑΝ ྻ ॲཧ ϥελϥΠζ
ϥελϥΠζ ϓϦϛςΟϒྻ ೖྗɿ ϑϥάϝϯτྻ ग़ྗɿ ϥελϥΠζ
ϥελϥΠζ
ϥελϥΠζ
ϥελϥΠζ ϑϥάϝϯτ ɾ; ɾϐΫηϧ࠲ඪ ɾଐੑ" ɾଐੑ# ɾ
ϥελϥΠζ
ϥελϥΠζ
ϥελϥΠζɿϑϥάϝϯτͷ 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 ͷଐੑ
ϥελϥΠζ
ϥελϥΠζ
ϥελϥΠζɿϑϥάϝϯτͷ 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
ϑϥά ϝϯτ ॲཧ ϓϦϛςΟϒΞηϯϒϦ ϐΫηϧૢ࡞ ϑϨʔϜόοϑΝ ྻ ॲཧ ϥελϥΠζ ϑϥάϝϯτॲཧ
ϑϥάϝϯτॲཧ ৭ ϑϥάϝϯτྻ ग़ྗɿ ϑϥάϝϯτྻ ೖྗɿ ϑϥάϝϯτ ॲཧ
ϑϥάϝϯτॲཧ ϑϥά ϝϯτ ɾϐΫηϧ࠲ඪ ɾଐੑ" ɾଐੑ# ɾ; ɾ৭ ɾ ڞ௨σʔλ
ϑϥάϝϯτ γΣʔμʔ
ϑϥάϝϯτॲཧ ϑϥά ϝϯτ ɾϐΫηϧ࠲ඪ ɾଐੑ" ɾଐੑ# ɾ; ɾϐΫηϧ࠲ඪ ɾ৭ ɾ;
ɾ ڞ௨σʔλ ৭ ϑϥά ϝϯτ ϑϥάϝϯτ γΣʔμʔ
ϑϥάϝϯτॲཧɿϑϥάϝϯτγΣʔμʔ ϑϥάϝϯτγΣʔμʔ ɾϐΫηϧ࠲ඪ ɾςΫενϟ࠲ඪ ɾ৭ ςΫενϟ ڞ௨σʔλ ɾ;
ϐΫηϧ ૢ࡞ ϓϦϛςΟϒΞηϯϒϦ ϑϨʔϜόοϑΝ ྻ ॲཧ ϥελϥΠζ ϑϥάϝϯτॲཧ ϐΫηϧૢ࡞
ϐΫηϧૢ࡞ ϑϨʔϜόοϑΝ ग़ྗɿ ৭ ϑϥάϝϯτྻ ೖྗɿ ϐΫηϧૢ࡞ ΧϥʔόοϑΝ σϓεόοϑΝ εςϯγϧόοϑΝ
ϐΫηϧૢ࡞ɿσϓεςετ Φϓγϣϯ Λઌʹॻ͍ͨ߹ ਫ৭Λઌʹॻ͍ͨ߹
ϐΫηϧૢ࡞ɿσϓεςετ Φϓγϣϯ ௨աͨ͠;Λ ্ॻ͖ 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 σϓεόοϑΝ ϑϥά ϝϯτ ϑϥά ϝϯτ
ϐΫηϧૢ࡞ɿϒϨϯσΟϯά Φϓγϣϯ α × +(1 − α) × =
3FDPOTUSVDUJPO ࠶ߏங ϨϯμϦϯά ύΠϓϥΠϯͷ
Լ४උ
ࠞͥ߹ΘͤՄೳͳܕ protocol Addable { static func +(lhs:Self, rhs:Self) -> Self
} protocol Scalable { static func *(scale:Float, value:Self) -> Self } protocol Blendable : Addable, Scalable { }
৭ͷ४උ struct Color4f : Blendable { let r: Float let
g: Float let b: Float let a: Float }
৭ͷ४උ struct Color4ui { let r: UInt8 let g: UInt8
let b: UInt8 let a: UInt8 }
ͷ४උ class Vertex3<T:Blendable> { var position : float3 var attribute
: T . . . } class Vertex4<T:Blendable> { var position : float4 var attribute : T . . . }
ϑϥάϝϯτͷ४උ class Fragment<T:Blendable> { let x: Int let y: Int
let z: Float let attribute: T . . . }
ϑϨʔϜόοϑΝͷ४උ protocol BufferPlane { associatedtype CellType var width: Int {
get } var height: Int { get } subscript(x: Int, y: Int) -> CellType { get set } }
class ColorBuffer : BufferPlane { let width: Int let height:
Int subscript (x: Int, y: Int) -> Color4ui { . . . } } ϑϨʔϜόοϑΝͷ४උ
class DepthBuffer : BufferPlane { let width: Int let height:
Int subscript (x: Int, y: Int) -> Float { . . . } } ϑϨʔϜόοϑΝͷ४උ
Ϗϡʔͷ४උ CALayer
Ϗϡʔϙʔτͷ४උ class Viewport { let x: Int let y: Int
let width: Int let height: Int . . . }
ύΠϓϥΠϯͷ४උ 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? . . . }
ॲཧ ϓϦϛςΟϒΞηϯϒϦ ϥελϥΠζ ϑϥάϝϯτॲཧ ϐΫηϧૢ࡞ ϑϨʔϜόοϑΝ ྻ ॲཧ ͷ ࠶ߏங
ॲཧ 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) }
ϓϦ ϛ ςΟϒ ΞηϯϒϦ ϥελϥΠζ ϑϥάϝϯτॲཧ ϐΫηϧૢ࡞ ϑϨʔϜόοϑΝ ྻ ॲཧ
ϓϦϛςΟϒΞηϯϒϦ ͷ ࠶ߏங
ϓϦϛςΟϒΞηϯϒϦ enum Primitive<T:Blendable> { case point(Vertex3<T>) case line(Vertex3<T>, Vertex3<T>) case
triangle(Vertex3<T>, Vertex3<T>, Vertex3<T>) }
ϓϦϛςΟϒΞηϯϒϦ 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 } }
ϥελϥΠζ ϓϦϛςΟϒΞηϯϒϦ ϑϥάϝϯτॲཧ ϐΫηϧૢ࡞ ϑϨʔϜόοϑΝ ྻ ॲཧ ϥελϥΠζ ͷ ࠶ߏங
ϥελϥΠζ 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)) } }
ͷ ࠶ߏங ϑϥά ϝϯτ ॲཧ ϓϦϛςΟϒΞηϯϒϦ ϐΫηϧૢ࡞ ϑϨʔϜόοϑΝ ྻ ॲཧ
ϥελϥΠζ ϑϥάϝϯτॲཧ
ϑϥά ϝϯτॲཧ // 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 }
ͷ ࠶ߏங ϐΫηϧ ૢ࡞ ϓϦϛςΟϒΞηϯϒϦ ϑϨʔϜόοϑΝ ྻ ॲཧ ϥελϥΠζ ϑϥάϝϯτॲཧ
ϐΫηϧૢ࡞
ϐΫηϧૢ࡞ // 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() }
%&.0
ղઆɿ.BU$BQ .BUFSJBM$BQUVSFT
ղઆɿ.BU$BQ .BUFSJBM$BQUVSFT ςΫενϟ 1.0 1.0
ղઆɿ.BU$BQ .BUFSJBM$BQUVSFT ςΫενϟ 1.0 1.0 ୯Ґ๏ઢϕΫτϧ
ղઆɿ.BU$BQ .BUFSJBM$BQUVSFT ςΫενϟ 1.0 1.0 ୯Ґ๏ઢϕΫτϧ ʹͯ͠ Φϑηοτ
ղઆɿ.BU$BQ .BUFSJBM$BQUVSFT ςΫενϟ 1.0 1.0 ୯Ґ๏ઢϕΫτϧ
·ͱΊ
·ͱΊ ɾϨϯμϦϯάύΠϓϥΠϯ࡞ΕΔ
·ͱΊ ɾϨϯμϦϯάύΠϓϥΠϯ࡞ΕΔ ɾࣗͰ࡞ͬͯΈΔͱཧղ͕ਂ·Δ
·ͱΊ ɾϨϯμϦϯάύΠϓϥΠϯ࡞ΕΔ ɾࣗͰ࡞ͬͯΈΔͱཧղ͕ਂ·Δ ɾ(16͍͢͝
·ͱΊ ɾϨϯμϦϯάύΠϓϥΠϯ࡞ΕΔ ɾࣗͰ࡞ͬͯΈΔͱཧղ͕ਂ·Δ ɾ(16͍͢͝ ɾࠓͲ͖ͷεϚʔτϑΥϯͷ$16͍͢͝
·ͱΊ ɾϨϯμϦϯάύΠϓϥΠϯ࡞ΕΔ ɾࣗͰ࡞ͬͯΈΔͱཧղ͕ਂ·Δ ɾ(16͍͢͝ ɾϓϩάϥϛϯάָ͍͠ ɾࠓͲ͖ͷεϚʔτϑΥϯͷ$16͍͢͝
&OKPZ 1SPHSBNNJOH
ςΫενϟϚοϐϯάૉࡐɿ https://www.3dxo.com/textures إૉࡐɿ Θͨ͠ MatCapૉࡐɿ https://www.pixelfondue.com/blog/30matcaps