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
OpenTelemetry eBPF Instrumentationの舞台裏 / Behind the Scenes of OpenTelemetry eBPF Instrumentation
ymotongpoo
3
360
「図書館」という名前のままでいいのか -Code4Lib JAPANカンファレンス2026 アンカンファレンス報告- / Code4Lib JAPAN Conference 2026: Unconference Report
ykiyota
0
110
omasushiというライブラリを作った
polidog
PRO
0
150
GoにおけるFFIのこれまでとこれから
goccy
4
1.3k
2026-09-04 SRE Tech Talk #15 怠惰なTerraform / Lazy Terraform
masasuzu
0
230
コスト最適化の「めんどくさい」を AWS FinOps Agent でチョット楽にする
classmethod_kaz
0
280
Code4Lib JAPANカンファレンス2026 開会挨拶 / Code4Lib JAPAN Conference 2026: Opening Remarks
ykiyota
0
230
AIで実装は速くなった。なのにプロダクトは速くならない。職能の壁を越えて価値のフローを設計する
nwiizo
7
7.5k
作り直せるコードは迅速に 作り直せないDBは慎重に - AI時代のプロダクトエンジニアが「判断の不可逆性」で開発速度を変える話
kinosuke01
0
280
2026-09-11 【Snowflake World Tour Tokyo 2026】Snowflakeを起点に、AI Agentが自律稼働し続ける未来へ / Driving AI Agents with Snowflake
civitaspo
0
220
プロダクト思考 × 基盤思考を AIで実現する Compound Engineering
tkc66buzz
1
290
20260903 Tokyo Jazug Night #62 | Azure エンジニアよ、 その環境は本当にセキュアか?
olivia_0707
1
640
Featured
See All Featured
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
730
Leo the Paperboy
mayatellez
8
2.2k
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.5k
Evolving SEO for Evolving Search Engines
ryanjones
0
280
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
1
400
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
200
Chasing Engaging Ingredients in Design
codingconduct
0
300
Speed Design
sergeychernyshev
33
2.1k
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
430
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.8k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
320
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