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.5k
AVSpeechSynthesizerにひたすら読ませる
takatsu
0
810
Other Decks in Technology
See All in Technology
白金鉱業Meetup_Vol.24_「AIエージェントは分けるほど良い」は本当か? / Is it true that “the more you divide AI agents, the better”?
brainpadpr
1
420
When Platform Engineering Meets GenAI
sucitw
0
130
Oracle AI Database@Google Cloud:サービス概要のご紹介
oracle4engineer
PRO
6
1.6k
LayerX コーポレートエンジニアリング室におけるサプライチェーンセキュリティへの取り組み / Supply Chain Security at LayerX Corporate Engineering
yuyatakeyama
2
690
徹底討論!ECS vs EKS!
daitak
2
830
SteampipeとExcel Power QueryでAWS構成定義書の作成を自動化する
jhashimoto
0
160
2026 TECHFRESH 畢業分享會 - AI-Native 重塑軟體工程與虛擬講師
line_developers_tw
PRO
0
1.3k
FPGAの開発コンペでZephyrを使ってみた
iotengineer22
0
150
Flow 不死:AI 時代 DevOps 的不變本質
cheng_wei_chen
2
350
ACE-Step-1.5で見る 音楽生成AIのしくみと“破綻だけ直す”Retake機能の開発【zennfes spring 2026 登壇資料】
personabb
1
540
2026年6月23日 Syncable Tech + Start Python Club にて
hamukazu
0
140
就職⽀援サービスにおけるキャリアアドバイザーのシフトスケジューリング
recruitengineers
PRO
1
150
Featured
See All Featured
Into the Great Unknown - MozCon
thekraken
41
2.6k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.1k
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
0
320
GitHub's CSS Performance
jonrohan
1033
470k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.5k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
360
Claude Code のすすめ
schroneko
67
230k
Amusing Abliteration
ianozsvald
1
210
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
5
1.1k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.8k
YesSQL, Process and Tooling at Scale
rocio
174
15k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.4k
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