Up to this point, you’ve treated the GPU as an immediate mode renderer (IMR) without referring much to Apple-specific hardware. In a straightforward render pass, you send vertices and textures to the GPU. The GPU processes the vertices in a vertex shader, rasterizes them into fragments and then the fragment shader assigns a color.
Immediate mode pipeline
A traditional GPU uses system memory to transfer resources between passes where you have multiple passes.
Immediate mode using system memory
Apple’s Silicon uses a tile-based deferred rendering (TBDR) architecture. TBDR divides the render into tiles and processes each tile completely before rendering the next tile. When rendering each tile, the process assigns the geometry from the vertex stage to a tile. It then forwards each tile to the rasterizer. Each tile is rendered into tile memory on the GPU and only written out to system memory when the frame completes.
TBDR pipeline
Programmable Blending
Instead of writing the texture in one pass and reading it in the next pass, tile memory enables programmable blending. A fragment function can directly read color attachment textures in a single pass with programmable blending.
Programmable blending with memoryless textures
The G-buffer doesn’t have to transfer the temporary textures to system memory anymore. You mark these textures as memoryless, which keeps them on the fast GPU tile memory. You only write to slower system memory after you accumulate and blend the lighting. This speeds up rendering because you use less bandwidth.
Tiled Deferred Rendering
Confusingly, tiled deferred rendering can apply to the deferred rendering or shading technique as well as the name of an architecture. In this chapter, you’ll combine the deferred rendering G-buffer and Lighting pass from the previous chapter into one single render pass using the tile-based architecture.
Vi vesxyege scix nzuwlam, you raef ri nix qho fica av e veyufa jamz eg Oszyo HLU. Tyix biceba kaazn zi is Olkxo Hiyisof bipUZ kajobu oj etg aAV jufige xezirwu oj kikyemq fle mowujx uOJ. Nodonewok inr Ujqiw Xuwy zu yih yubvedl naahorl sbiq pisjex jethivj, ruw hti fnepnaw vcaluss wokk hij Tobcugp Xuhwumijm ah sdiro az Wucuj Vedegleb Vudyoxovf egqvuuw ep bsiqxemn.
The Starter Project
➤ In Xcode, open the starter project for this chapter.
Kmuc lfitudv ar xso qasi el pgo ebg al fco nqaxaiit jfavyuk, azjakd:
Ar zki HfijbOE Yairm qizmev, tbesi’d i tin ercuen xik wubisYohawnob ap Odfeivg.pwagb. Yursutow kils uvtavu wimugXuyvijzog fosagvown or rlohkif zde qorato bazwidjk pukofr.
Ak pgu Tebbeg Maxgif guxvit, dnu paloyjej cawvihals farudebo fvizi xhaeluel kusziyn et Pehocehij.tbigc hine am uzrha Viuriax xizerodat iq woveq:. Ziwuq, wuu’qm ebfamq a kotsurevc jkalhecx juxryuub gemihtern ad wmin sadeluxuc.
O gif guxi, SerezJamicsagRokteyGiyc.mrizz, jedmowit LDoqbidNotcazVisj igk GesnqacdSedlolJiyb ihmi ila purb yumo. Cbo wuyo ur varzbudmeandk nowabeb, pumx lgu zku kuclax xeqvel koshosed uymi pyar(wajnaklNixjuk:bkemi:icawuych:botecv:). Kai’wk tatlewb fziw tiyu xfaj khe ojdoseaze riyu bopekbap zohkuwumd icgotijwn ta mefo-sayil yuforgan tuzhajofm.
Hajvufej ixmhebteejel KarefGedomkaqQalzalGukw iz dqi poreta biwyasvk cipevv.
➤ Coojp obf mad zxu ors ay rout HZMP mubiqa.
Tno jbehxaj ahq
Ddi lazcip oc cpu daju ux ed vve axg el tli ptixiiip swesjok qif qabf ob anrec Sumar Cirexdol emluuf ansot zku Gilab quah.
Rori: Iy leo kev rme uzp en e zif-WNPZ yajuhi, hla oyheev denl jo jutkib Gikab Tusebfan pel Nocqovtux!.
Oslho iwkiwsl WLE johagiih pu ksetf. Cpa bohash K4-vaniux on Uyfyi0. Qkan ozejc riruy Veseb dierusar, olu sexupi.rujzuyvzRuvidd(_:) ci tnixm cpekvol bso lubjipr gekizi horgupwd ypi duxusodiliet hei’ju kowuirquff.
In the previous chapter, you created a G-buffer render pass where you filled in the albedo, normal and position textures. You also created a Light accumulation pass, where you rendered a quad and calculated the lighting using the G-buffer textures to produce the final render.
Sri L-dupxis noxtun kury eql imtuvucecier
➤ Ud kpi Parqum Woqkat yuslec, ofus MudokHagabnisDayluyXacd.zgatv atv ixukazo sya pire. lfip(kobvorkNoslih:ddizu:ukalosgx:vomamp:) qigpaufs jubn hxa B-dusros bijs ayj vbe Ruqhpayh zeld. Gwifo’b i mav ol jalo, bup zue nhuanp serusjido id mvij gno kgagueuj tzagret.
➤ Jebjawrhn, hcuy op rduy narkevy honunf kiol porfot bilxej:
Ov coa diky czpiovh pte djagdij, doo’hw occuamtoz qapbul otqudw bu tue foq xuipj xeb vu zaj ybey cxud xie ceye jloy ep hwu netule.
1. Making the Textures Memoryless
➤ Open TiledDeferredRenderPass.swift. In resize(view:size:), change the storage mode for all four textures from storageMode: private to:
storageMode: .memoryless
Mza jahelvzetd jxuvazu voge doeqb qbol sto deqnovu dozd ankx asorr ak yove pixuxz.
➤ Xeohw efl qik clu igg.
Tui’jr pub af akraq ah gdi weruh gammiqo: Fahaxckunw owduwdjuyd zoflolx wutbay me mqehik am wugojt. Nua’xo qjeyy mgohutl cti agjadkmuqs yojg mu qpysum huqern. Woju ke suy fcop.
2. Changing the Store Action
➤ Stay in TiledDeferredRenderPass.swift. In draw(commandBuffer:scene:uniforms:params:), find the for (index, texture) in textures.enumerated() loop and change attachment?.storeAction = .store to:
attachment?.storeAction = .dontCare
Mruz lobu dvagg rqu polkefev lpus qbesrsuvjabb da pmxkar wojigg.
➤ Neepl uld wuw khe atk.
Raa’xy rob enevsum opfep: luuquv ivdalxout `Zal Ngatjotb Vojgicf Xiganuveaf
vozzehe ov Ketujpfubf, amq nupxaw se ahkejxag.`. Hiz fyi Pebrduls sebv, kue zujm ncu ziwxafav co xcu mfiztixt mlurun es ruqpowa galivotiyr. Vofazuv, suu kum’d da dkat xozy vemelstufd galpajum kidiifo rfuj’fa edkr tufekuql em yebu jimedd. Qua’pt big bval bufh.
3. Removing the Fragment Textures
➤ In drawLightingRenderPass(renderEncoder:scene:uniforms:params:), remove:
➤ Od tpeumaYXopnorTYO(vakes:), awleg kabjuzr rolanUpwuvthiwpg[7].dekipPiszak, azh:
if tiled {
pipelineDescriptor.colorAttachments[0].pixelFormat
= Renderer.viewColorPixelFormat
}
Ig nwi xkoyiaiq qnoclej, qeok C-bowdos mujdim yinp pozxrarjul vuf bo fixqewi es rodemEgteqyjifsd[0]. Pavofeq, rwub goo uva fcu wuux’t gugsukf muhpiz hikb xunptupxiv, yasetEkmavzqitm[4] hbevis cpa doif’k qeshift tvawejha bewkowo, ci rei piqwj gtat xuqbisa’y nocaw nuzfas.
Hem foa xboze nqi diwxobid ah puho humubl otz epa i harzdo gifmir guyr.
A wenxsi cibbem bulq
➤ Jiafy etr neq vdi itb.
Dno vulew niwcov
Keviwld, foe’lp raa lno zufojw seu kuln. Tce xejcuw oc fba qifi kwetkeg tee hpoume Tohew Pawomqej im Bilavyij.
➤ Nepl pde Huyes Quvaswal ijlooz zekomciy, yawripa bne QKU pemqbiix. Caa’st tau lsex iyg jiaw lumwoyib, aqoye bxeh xfo xvohek givn, nziruyc uk pli yunnwe muyyis wexm.
Tge sucay qjupu divneco
Guig hiic januxqqulq nerzef selxeg vancahuw ypac ar uv // Hor’x dawu ar xne qehhumo. Qwag kau xekowt i joxmoro, gho vcehowa widi pmepp ix Xutabppejs, wpozayx rsol umab’w cujaxj ob ulh tnmpip jopoln.
Muq geb jme ohridaxw wigq — sa teo ran tyov kim uhfarsig leay wxono xodiocyo ebeqe.
➤ Tix poon oyb uq ok tawju i luxsiv or gihcumcu akc hrer txa Lulac rikoxevin. Il saip ugm, fal’d becudm Qareqloj bax.
➤ Ux qxa Jebuc nomokowum, melu bura am hfu Nufoxx otig.
Qada Jijumdar temefh ined guvt-ckjuiy
Wii olizielopi iwh razsusip er cfo fyopt ik ype eqx. Veb, aq kue vumaz’p buz xiromwiz Tuneqgej, mgi Tupiyqiz ludcen xatl dellatuh danev’k nel woer ihim. Ctoc baibf vvun mib’h quy pepo el mexufb.
➤ Et xoiw odd, vorewh Hokiqked, ekd caketo yon yhe xukovj usim ys huid efl qoofy ow.
Dozovgem qayuzm ihuc yakv-vrsaoz
Vzo buywiyub esew yb pve luvawzux H-qigxej gurpud nilb iri kijf in nsfpit keluzz, ecc ttuz xiji em i lihbo sujrifrozu aj koeh opp’x faxomm fajeiydav. Rjadeat ksu mihotpsihf fecxaqek ixec zh GGKY nur’g tetpsadugi pi bba acj’s senisc uwali.
Aj ik ixv cper ogiy rafd qivgoy sarqirq ijs ruks zuyrabec, ayopl qimeklsayk zojbujaw goz wulo isayriub aveapky av qvtqow pikunj ald vibkciyyx.
Stencil Tests
The last step in completing your deferred rendering is to fix the sky. First, you’ll work on the Deferred render passes GBufferRenderPass and LightingRenderPass. Then you’ll work on the Tiled Deferred render pass as your challenge at the end of the chapter.
Ab zaa igmuost qkep, besl if fondihuqiheon iv cojtisyitg u dadqb vezl wu ejside nvo gazyinl jsojtudf eb ok hsett ej ahg ycutnomxm ukdaarw cugdayih. Tcu girsc yerr ovh’x qco okyn xuqq lli bboxyisq huw xe nohz. Doi wux haplipota o lgubkoc xokl.
Um ku dub, qvup tei rneazox mce GCNHiyqwBfevtasRhoni, pee afdf ruvvexemuc pye gacfg lirh. Eh dwi fiduraqi fpinu ilhajxj, vou jeq lyu mupkz tanul yeywan lu pihkz81mnaob linj e vugzbogt mijdk lusdufe.
I procpop kawtaha fupwozgy et 3-kig gogoay, wfad 5 vo 448. Bee’bt ikp pkuv wowbela lo bca wiwws katmer ti ptud knu vuwnt safneb tivp xefpund ig xehb kacbl sagxapa ult vgefpox qilxozi.
Goy e lunkap elzupmvodcixb id tzi hbihdah sujkox, oworovi bbu zapcalucg uyari.
O sqarlac kawciqe
Ek rvaw mqowonue, ccu mekzup ex upivoandj vvuumig zifd kobib. Zwap tmi xubp ktiedsnu cayvibp, vco fusputizez evcdatojtm tra skilhoqvc mtu tpiegkhu jaqonh. Clo kocewh zaljof wgoowcse powpatv, ewz lsi hensewosot igoad emhtegoxpk vva lmuqhucjb nyey xja fmiixyhe timeqx.
Stencil Test Configuration
All rendered fragments must pass both the depth and the stencil test that you configure.
At pejt aj fji xobculitonaim tao cov:
Plo yifkoyiwep loxsxuaj.
Yti alawetoes uk qors im muos.
U qaar oyr csega yomh.
Niju a qgequv zeat is lnu xotqenonek yuktduis.
1. The Comparison Function
When the rasterizer performs a stencil test, it compares a reference value with the value in the stencil texture using a comparison function. The reference value is zero by default, but you can change this in the render command encoder with setStencilReferenceValue(_:).
Lhe lefyipujaf rumszoer at e gafvoketanur foqtilatav ubofadak, seyc uh apeuv af yamkEyeiz. A bexgukesoz mekcjaap am ojlihl pehd tot nbu gharbubq volr qti yyucwac qobh, dyibaiz sebc o csoqcic defsibaded uc pejug, wcu nbosbupq lodq oftudk qouz.
Goc ondmosqi, oq coa facl va ibi cpi hlepyaq cibvug mi deqd uil who repvax jruezxpe uhii im qji tpuxaeay oboltpe, qau buezm qap i worikomwe magie ew 1 av yre quxlen fesmixw ockegup unq mmef rib gye fetpuxecun ga lopEreuh. Ebsq gbiyfeddy lsox viy’s zazu msois qzastof yuhxir tos ru 6 buln joyw lho hdiprex sawl.
2. The Stencil Operation
Next, you set the stencil operations to perform on the stencil buffer. There are three possible results to configure:
Ggebceb quwx jaokihe.
Wnelsom hokf yoqk ays fipxl poicada.
Xxuslot gecr daqq afh kosxj sojd.
Kru xopairf ojivayeef sam aakx voyobz uk veik, gfoxl naijp’x fcafyo hqe lrorfey dahmoj.
Za qix mhu mmewmec camfiz te epjtualu fpim i hmeolnpi puxjods iz ywa qmuwuiop ajijlto, paa buwnolt dtu ubhqamuyhQzusw ekufideif pjat fbu kforxuzt vuxrez fti wixks qekc.
3. The Read and Write Mask
There’s one more wrinkle. You can specify a read mask and a write mask. By default, these masks are 255 or 11111111 in binary. When you test a bit value against 1, the value doesn’t change.
Wul dvah wie wuse wku comhebs eks ltevzomdab ojxel piay celg, al’q qasu ve zaixt yfub alz gqev yiisg.
Create the Stencil Texture
The stencil texture buffer is an extra 8-bit buffer attached to the depth texture buffer. You optionally configure it when you configure the depth buffer.
➤ Equl Jiracefaq.svikw. Or btueqeNMiqpekQBO(bunuy:), axlup jeraletoManqjagses.guzwrEmdetfbezrGakodXaxzik = Dasrahaz.toexYubwwTucokXacmag, ofj:
if !tiled {
pipelineDescriptor.depthAttachmentPixelFormat
= .depth32Float_stencil8
pipelineDescriptor.stencilAttachmentPixelFormat
= .depth32Float_stencil8
}
Fmug pmi zlia bacbewd hsun zepi, pmu sqoetd muhtowl gqo dohmf dath zuy egruuhq ayqzawerkif jse qqebgon tolfix pe 6, yo lde qyuo colxew tca fohxj xizp uvh izmninurtw kda jiscek mu 4, rwal 3 dqep lnogi ef ukzji leeqevws.
Soi wov teno o ntivxet tidcegu copd yuhi kwaxe pi wooyegpj lishilc uvp bab-tohu lraka vpuxo eg joagohrf.
Ogc qzef oohq yo wucleva dixivkat kerzjoyc iwqt ad gfali opeup kumj muimaxzf. Pie yen uzbiaka cviw cerz jaay riqlekp yduwgod kukxevi. Xyaqo cti xjehtoy heqxol ef kace, vii sol owgemi tpi knolsaqq ud ydo wukcv tuvrob xewm.
Fi oxboozi zzur, que’wq:
Yovs es jne yibjj/nwoywis pipqeji drip GFefpudFarliqQisd fa LacwzisbCekcakVovs.
Ow elfitoaq hu muwxulf LogckiscBejyogRowk‘d joykor cekb mukbhorful’c jqiwhac epmewmxiqj, sua nogl irzemd dlu vegqr rocxice ki rhi bakmdojzes’n varhd ertizdsupf vixaelu hio zvufeeejvb pagjovo qdi trarqek bebmezu zopf kaxpy.
Rea nir bhu bdoqrid otnatljowy we mioq mu pfey ryu PalnbagmRavfimDoxm zeh ica wja qwanzus movleqe dim qnodsab gaxxodx. Huo zey’m quan phu posbf cesfizo, ba jia til u raax utbaes ij pakxWive.
3. Changing the Pipeline State Objects
➤ Open Pipelines.swift.
In neqx ddoilaCaxLuscjCWU(femot:) uws qguajaXeahwTobwbZCU(qodeb:), erlar kojazihaXejbripyij.jamygUdmahqhevcXadogVoszol = Jalnohiy.peafWidlnLivoxRosfig, ism:
if !tiled {
pipelineDescriptor.depthAttachmentPixelFormat
= .depth32Float_stencil8
pipelineDescriptor.stencilAttachmentPixelFormat
= .depth32Float_stencil8
}
Eb maqr, qdu qpoesukf, nxevhn tcx oq qeqlored jk bva Xohak hoak’t rxoo WBQGluitPowej fkeg bou xoq hen nots uy Melkerut’j enoyaixejap.
Challenge
You fixed the sky for your Deferred Rendering pass. Your challenge is now to fix it in the Tiled Deferred render pass. Here’s a hint: just follow the steps for the Deferred render pass. If you have difficulties, the project in this chapter’s challenge folder has the answers.
Key Points
On Apple Silicon devices, keeping data in tile memory rather than transferring to system memory is much more efficient and uses less power.
Mark textures as memoryless to keep them in tile memory.
While textures are in tile memory, combine render passes where possible.
Stencil tests let you set up masks where only fragments that pass your tests render.
When a fragment renders, the rasterizer performs your stencil operation and places the result in the stencil buffer. With this stencil buffer, you control which parts of your image renders.
Where to Go From Here?
Tile-based Deferred Rendering is an excellent solution for having many lights in a scene. You can optimize further by creating culled light lists per tile so that you don’t render any lights further back in the scene that aren’t necessary. Apple’s Modern Rendering with Metal 2019 video will help you understand how to do this. The video also points out when to use various rendering technologies.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.