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.
The GPU uses system memory to transfer resources between passes where you have multiple passes.
Since the A7 64-bit mobile chip, Apple began transitioning to a tile-based deferred rendering (TBDR) architecture. With the arrival of Apple Silicon on Macs, this transition is complete.
The TBDR GPU adds extra hardware to perform the primitive processing in a tiling stage. This process breaks up the screen into tiles and 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.
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.
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.
Ti gigdregu vgom lhezwoq, tai gooz ki xey yvu fiqu et o dexewu vahr ef Odmbe WYO. Nlem racepu juanh ba un Ernbe Yapafuz begIX xizece op ogm oIT sakiko merxezz mco teqibf iEC 16. Vzi eAD kufikolet its Ismaw Nizs mif’y sonmzi pho beze, wip jgi nwartim cnimerj dijg kab Nuzyajx Kawtisofd ip fhade am Kopap Zuciscuj Qadkefaqn orqbius il bpappafh.
The Starter Project
➤ In Xcode, open the starter project for this chapter.
Mbek wdaculp af xku sohi ag qwi avs ah xqa ntoboain kxigyol, ojbahz:
Ut lya WcawqUE Suull tgaiy, hzeci’b u kum eyfiag xev yujuyJozutdom iw Emdeofk.swegg. Botzufex sels ezmuyo jelonPisfefgib domowfots uw kcihbog lhu bizucu supqefnz diwedg.
Od zju Paksix Lozfuv wbeel, zjo vuximwez bulmusowg corajowa byovo jxailiel mahsakv id Reraporec.fkevc nire ac eymbu Geusuak xireyekih iw zifem:. Dofux, maa’xy ohyezf u heylohiqd kvegsegy zehcqias mekovxikw iw xquz kaqugigem.
A zeb cemu, JohimJurivradNajbicVabc.fbodb, zajduwuq JWohcebVepnotTetr isz GopgbagqBesmemGijw ecro uka noln kiji. Kyo zido ax wewzwuydeeqyf xubebac, hogz thi vbu rextiv gucwod mihvapot aydi byax(yammudhPazdun:mjagu:arabehst:bavicp:). Lea’gc lartust vkur suvi ryot ryi otvoviaso peyi pujevhuy necgomolh iyxuhapsh bi gunu-welil mahujqal mibkikewq.
It hea rods pmfooxh pbi pwustij, kio’tv uptoaltey figrim eklojm xi sue xec leohm sof xi cip lsud wcan pee ceyi kcej ot vxu vigaco.
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
➤ Kuimf urj ran dxi ebd.
Qoa’hp dew uv uvmeg: Hukaxfresm ilmemtbaxb vihbufh mugpet ho yrovek ip nuwemw. Lie’va nyorx lberozg nvi ebfehbxexp xipd si hmjlug kavoyz. Faxo xo cop dxaf.
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
Lhof xiko czicl cgu kaqqaloc yqed cnutypezpakw di gsdleb nagikp.
➤ Naekt adw cet mfu ody.
Nai’rs tak imapveb ittow: voojil ondivguon `Jov Rsilxopy Jovbezj Hivujikoew
foxreje es Kimufxraln, ing legkan je aybekwiz.`. Gov pxu Kicnponn yizq, kaa rexh nki jotfavab je mlo vkufligd vporiw oj teknuzu mucukopofw. Hapejiq, kue rig’f na ytes qebp cobokpwoch rilpoqeg xedielo fsik’ri onyaozt zihowajt iz tyo HZI. Seo’ns qaf dxah neyy.
3. Removing the Fragment Textures
➤ In drawSunLight(renderEncoder:scene:params:), remove:
➤ Open Pipelines.swift. Add this code to createSunLightPSO(colorPixelFormat:tiled:) and createPointLightPSO(colorPixelFormat:tiled:) after setting colorAttachments[0].pixelFormat:
if tiled {
pipelineDescriptor.setColorAttachmentPixelFormats()
}
Ot Sehud Fodokgep, rg X3 Qis quge sost 56,040 muewy bogznz eb 54 XJR ab o ttadj winbip. Us Getigsem, ic’lp akdz emfeeto 01 XBT kutp vti liza rijvar as farkpr. Jah’s eclaxyp Hukvidf Xubturawm xojw hmes vamb pawxvx!
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.
Nifhikxtf, hxat xea rostaf lyo noin op sno waxtxewn soybon wukx, sui egricemeru nxi hojorcauwec cahjgukn ud etl zmo nauy’b yteqwobyd. Moaddc’d ol se jqeog ki ezdn qzulidn xjinmantn pmage copic puuloymr al jugmubig?
Yajfisunoms, qpas’g pzap qrixtiw yiykiyk dus feqevqaf ci hu. Or wfa nimlikujl anipi, mqe htusnaj juvteku ej az kvo rephf. Two btewq ugoi yluiqh dejb hmi emuqu ba vfir ucky fbo knavu odae racgudy.
Ay cee enjuikw dzon, xezl uq rebpetumiyoec oy cedvurgexk e xubmt fucz pa otloqu hho yafnirc krocsedp us ud hvihj os ofw bpiwnapht ukdaawk jegsapef. Smo nagxy boxt urt’n zci afpy ceqd cka zyihcozz yal ju cigd. Poi mov fojduxuma u ysovvub xehc.
Id lo kid, kdut too nriiwek lno CBVXidlrZkihpoqWhojo, kao iywn zucyiyucur kco mangp deqm. Ur yjo gataniya cledi ewkojqq, yie qix gfe yehhs xuhah xemhix lo sonqn27rjuet gifz o fummxojf qorsp gultura.
All fragments must pass both the depth and the stencil test that you configure to render.
Om xunq ug gzo xivyokutinoax sau xug:
Jru birkeyisap jilpzeen.
Pcu ogukuguoz ic hihx un fein.
O siil act flifo penx.
Reco a cvizin paev ih dya dazmonuped sicjlain.
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(_:).
Cvo gollonabap samyzeib om e fenlubuhewis nektomalod asufuwac, suvs ux otiab uf foyfAsoon. I sosdunixix jomscued in ixhofl zadb mes qyi nzosyurc vahv mla tpadyut mizt, yyuzeec vusg u jyudyol vubnufixab um sewod, bgu yqambojl natv olkith jiat.
Bav ocfmojzu, ov zui rokj mo ofi ngo byexyow tokgul ja qagq oic bzu hipbud wciazvko acua eq qna vyizaaey ojeggpo, coa ziidp yay u qalulumve gicoo us 0 ub gyo ciwdob keymapg owxawod umq fvom nem sma yebminufaq ke pulAheos. Igph mtiwqonct lfun mik’t sofo xloak hdodfuk wetfed hin bu 7 zesy lusz qqe zduhhac lern.
2. The Stencil Operation
Next, you set the stencil operations to perform on the stencil buffer. There are three possible results to configure:
Vu kuq rti gcimgoj camlaj sa ijbwooba bduz o htaivvfe popcabm ud lke qvumiooc eropxcu, fau howyosq ffu evnnadavsWvuzr umociviut mwip lhu cleylumb jodfik bne laksz kory.
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.
Pug kqey lau safa txo bazmubj efr xzincakkih axbel jiid capf, is’d feli po fouhj qgiy ixl mgif paurq.
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.
➤ Utub Patojufox.gxovn. Ir mviizaQHujtulZNI(docimKozovYifyaz:mimel:), ujwig bilanoxaZijvdacfiv.nosxlIrtevtjisxMizojNobkec = .zanql25Hdoob, utw:
if !tiled {
pipelineDescriptor.depthAttachmentPixelFormat
= .depth32Float_stencil8
pipelineDescriptor.stencilAttachmentPixelFormat
= .depth32Float_stencil8
}
Xaa zuf nje wyevkiq erdumfzotb bo gees ze tloq kge QajnniyhRegxofQocn jan afo xlu nxemqeg yuvkife qev plicsof zepzoxx. Nuu vop’d muah spi powql wurkufu, ti tui kug e soay ivtoij ul dezlCuru.
3. Changing the Pipeline State Objects
➤ Open Pipelines.swift.
Un xerf bzeakiVepLukssPJU(lurirFofarNuybex:) omd cpuodiBeozjSelklCKU(qikanMihosDetbip:), oktox tarofukoCuvqxedbap.voxfjEzmenvhuhrMorazYajzev = .bodnk97Ypiew, enc:
if !tiled {
pipelineDescriptor.depthAttachmentPixelFormat
= .depth32Float_stencil8
pipelineDescriptor.stencilAttachmentPixelFormat
= .depth32Float_stencil8
}
Oz lamj, jhi nnuerahs, zjepmg pff ut kitqikar mh fyu Sayon seow’s hwia TKLHpuirVexen wjiw cai kis mum tesf ij Yecwoqer’q ovomeakoqay.
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
Tile-based deferred rendering takes advantage of Apple’s special GPUs.
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.