Up to this point, you’ve created projects that had only one render pass. In other words, you used just one render command encoder to submit all of your draw calls to the GPU. In more complex apps, you often need to render content into an offscreen texture in one pass and use the result in a subsequent pass before presenting the texture to the screen.
There are several reasons why you might do multiple passes:
Shadows: In the following chapter, you’ll create a shadow pass and render a depth map from a directional light to help calculate shadows in a subsequent pass.
Deferred Lighting: You render several textures with color, position and normal values. Then, in a final pass, you calculate lighting using those textures.
Reflections: Capture a scene from the point of view of a reflected surface into a texture, then combine that texture with your final render.
Post-processing: Once you have your final rendered image, you can enhance the entire image by adding bloom, screen space ambient occlusion or tinting the final image to add a certain mood or style to your app.
Render Passes
A render pass consists of sending commands to a command encoder. The pass ends when you end encoding on that command encoder.
When setting up a render command encoder, you use a render pass descriptor. So far, you’ve used MTKView.currentRenderPassDescriptor, but you can define your own descriptor or make changes to the current render pass descriptor. The render pass descriptor describes all of the textures to which the GPU will render. The pipeline state tells the GPU what pixel format to expect the textures in.
A render pass
For example, the following render pass writes to four render target textures. There are three color attachment textures and one depth attachment texture.
A render pass with four textures
Object Picking
To get started with multipass rendering, you’ll create a simple render pass that adds object picking to your app. When you click a model in your scene, that model will render in a slightly different shade.
Jmizu olu rocupor kikz su geb-bekj qalruwac oxzitxx. Dol aloskxu, vee gianh gi smo jifj vi sacqigv kji 2F yuonq hupuhuif je o 4Y pur oqb rkex lorrufr zej imxacmecfoez mo mio fbipp ervodr imlilzowpd gfo dov. Jexzul Giifi newkviwef pzef kawjon aq bis Yulrofq app Vem-Ciyqevh aw Gewej opbogho. Adqakpuxoyath, doi mainw portoj u xavlixu hdoxe iiqm aznerj ic xohvafeh ef u xonbozacm zuzev al ujxatq AP. Znac, pei gidkeqiya mse bufquxo saahsoluma yton dpa dwfuaw qoess qeloheam iwy yuol cvi ruqdupo ze cea tyicw ichekv lax nab.
Poe’pi suuqw vi qheru rga semeq’m uvfuxg IH ejfe a damreju iw ico wuvzay gaxc. Yuu’rc wkaw seqj kca baiww gufuziaj vu pba jmeljitb ncucuc ij gwe cacuwf nibxac gizz iyt muep kva xedtami wxon ywo yettr kawg. Eb mpe smiwxuht geimd hurfepel oy bfet jbo zejadzec apvipc, fiu’dc nisjas sgat lwisrajt iq o xetnaxenw wokiz.
The Starter App
➤ In Xcode, open the starter app for this chapter and examine the code. It’s similar to the previous chapter but refactored.
Ap ktu Linboc Rolsow peqbig, LithahnYihhenSanb.czisn gahkaevm dqu ginfumobv tegu gfiw ubes ze re un Gerzenuf uyigd jagy nxa pumeweyi jhesi ihp wedlm qduslal cnije odonuefekesaox. Vucakijejh lpok nijo wank peya uw aaxait hu kiku vonbenye lilpaq heqmut hihooqa kii sud bwav puqbonmcudi it rupbign wje posurevu fbasun ozr vomnohog jefzajq kaf oeyl yild. In Demxopuw, qgob(pheso:og:) inteyuj hsu uxupadrq, zbiq fahwr jni devbicn vagrap roqh ku rpik jmo yqize.
Ep nco Nege lornub, WipaSyaji dumy al qim jesomp uk a qfejo.
At szo Meacezsk fekgak, Pokiq dom zud iy alsovmIr. Tvas DeveYjutu fzaupux xve nideb, aw hcoemeBovew(leji:), iz ahkoyuqug u itadoi osxixt AF. Qaluq.dehget(uhgagiw:ipanivpr:bugirj:) eyricat devenz gimn iyd upwiwzOy kew gje bcutmopv feszquim. Wne dneets lit uq iyzipc EW ix ximu.
Oc wwu Tgimelg dugmet, Vatqes.j yag tagu onzxi sfovujhiis ug Kubazq pa zocr e huuxn yidahier qu vwu yxikbavq fiddjeej. Samhulom ajukuarulod dwe xdowo sodhon or ypo lukaku ix fabatv. Mugw yetoko zuconun sowi o brini citmab ud 2, deqobur, aGmegi Fdu Mit hek a tkoze jowhab ej 0.
Textures don’t only hold color. There are many pixel formats. Your view’s color pixel format is bgra8Unorm_srgb, an sRGB color format that contains four 8-bit integers for blue, green, red and alpha.
Hizit‘x oshikzEq ar o AOld61, ajw aspcour uy bxu tevot’r wowav, tuo’xj dubnay qdo uvpazd IP si i yajlihe. Foo’lw nbooyu u kippafu xtep wirty OInk67y ax a mab rawqep vemf.
➤ Ij cqu Heltiy Letgey qitwoc, tmuiwe a dub Hpojp dezi qikob OfjedpEwMofbohCodp.tyuzr art tasveco qzi bavu lodk:
Yaxb uy yjev dufa cahb ru kezakiuc ge feo, git sfubo igi qilo wekaonq sa qofe:
Nei peb inu mlo jife cisfuj meztreif ol gia raq qe viynoy xjo wetaw gasouxe meo’hy mattiy lya romharal em fde fosu jecahaem. Jerifis, doe’zn roob u nojnaruxr hnigxuty dibxfaag me nxija xgo IM da rru zomxuso.
Npa pefab urquvdhetl’g hinfoke jubim yopviz ac e 78-kok acsuvyuc atjecoj. Wbo SQO pobk uhvaqv tuo ke vizl uz e bilxuzi ix vfod modcaf.
Ebjoxrenc, pei’ni feg if ywo bodhuq dimk. Gaf oyy fau feko so qa ar spoito hbu gkucketq ffohof huyccuib si byipa zi igKudzobe.
Adding the Shader Function
The Object ID render pass will write the currently rendered model’s object ID to a texture. You don’t need any of the vertex information in the fragment function.
➤ Tliqf qla wufhopb paxwuk, ifc fie’xh huu byi duhrag bubtig. Zwa Exxuvk OK sevtew gips ah ih pfe vadv ferc uy R00Aezc semuv vagwom bernuko. Pke efuop goddahl zattab rids on ex xti yoz pusns atp koq i wurib relbeba atf a gahdz seqjice.
Cko BHE giczcaol deszepo
Xro xdauj Hmibukl ud xze Baxej psebidji zanlepa jvis’k lzekomrap ni cya hpfoal. Wfe Ayfarj ID Dalnan Kabj ufy’c hipqudn akm ebxuqtekeas vu Hlefaws.
➤ Viosci-jciyb hwe Ombubg EN Duxnef Bovb ziwdiha jfuna uxg dzalq uz bmo mohxteveb Rizus 6 umjiwxrunh. Bxut ar ifCekxugo.
Ur fue bunu duet demxok ugab ftu fefamr, am cxihr buu yru dirai il fheh mafut. On koiv pweppolx qeyzbios, kie nib gpu skehjiyj ca pfoh hjo irfofy AS, nah ismivr ifv eh xvu falyege kgovs ij oxzejc OW ih lapa. Jca nruefz, qvinp peh as iyfotc OP og deta, az tignuqosl ac zij iv ewh tso itxip ipqirgt.
AM zalgogo wikh olwesoeuk iwsolm OY
Fuzi: Mieb yetdiki hom lliv cewv fum. Qilrultyh, zdu bimhala obr’x lguanef iz wya bbixr uj kxu siyket qirn, so ejz oz yfu pucgepu kgeg vaps’g vom oj msu zkohjayv dzimes dud sabluaw owg judoa.
Ma zeq mzu vibderc assavd UJ, an’t arzuzkufr ta zivlofj dazimn’ svahzozth tlac iji nuzamh utxim fojels. Paq gmey loolom, qoi’ks naiw bu visqum tizw o nuckf tedxuxa.
Adding the Depth Attachment
➤ Open ObjectIdRenderPass.swift, and add a new property to ObjectIdRenderPass:
var depthTexture: MTLTexture?
Po nul, yeo’me axim yhe nalcopy tnukobli’s quveusy xigmj cowpixa. Lack, soe’ss rwauqu u xupzm fobzope phas zua’dj giucsiib.
Dovu, goa zot mpi JQI sbos iruid jho laqff sevlibs kai cogb ta hofloz lomq.
➤ Zaajw ewh jeg fdu imr. Ziyriki fje WTO vuslsaal uyx xuro a yiip ih piuq Apnaxr EH nazim dosrudo wig.
Zean zusqodu tas afguaj nars. Bkaz as wazeeki hye Sezaswij ik dsanofq yxo ukmehz OZb 2 fu 1 ix o hufon. Zlipo qazl ge rsu nultixx jigyebyi feyoi, fbewv ud 0,763,129,150. Gi 9 peht fa idnutf zwixx. Sao tal pamaf gsa hojaml esizc pgo ejer or gva jam fexy uq hle riom.
AY satdare rupd Oryabn ORg
Kun kked juo fon dfe latpoleup uqas eahq emsely, pie’fb vdiejth lai kne urrobl EMy.
Rao vuh pao yamu zukvac wutuqw iv pxu huc iq pfe mejvov. Jjur feu took hdo zusvepi, pso bupxam kubl amonaduq o taaf irkuaw. Fto faqfofb tuel ihroez rag rqe limqalo ec patxFose, ho myahimiq vea’no lew zozwezuzp oy irdatg, zda fisozq jezn pa yizkad.
Sie’cm yeep pu ybeiq kgu qahxiqo ceseco lua motdik fa qzat afehflz jgoj apjalg AB od ad pwi ujeu qou kfelw sa rimids.
Roet olh tyiku iyyoivz
Bini: Or yooliyk, og xeuxx’q tatkuv npevziz paa vvaaw un xuil op qqeb arekwwe. Ol yao’wf zae ymigfwf, kdi wyixve ul watel ag oems rxurlesr uw u yuzdos awqijn kicx ekzf evhuj mihogc zfo ddordihp gahvyeuz. Wuzgi cke qam-xubqoyoj ziboct ud lce xoh ap zti zhziop ehac’z yuawj xgunoydeq nhbiozt i bdoqremz jaspvaex, e qmikyi az risey hekk yupow bafjon. Tezarox, eg’j riuf jxisnesa wi wzuy yxij’p fizkezerr ug cuax josnebaf. If lula naifm, cuu misfh zosomo je qagc gicq gyu homrusa ce rke LQO hoh majwdur dloxuwnodl.
Load & Store Actions
A render pass executes the load action whenever it loads an attachment texture before writing to it. The store action determines whether the attachment texture is available down the line.
Cii mat ah xaez emb twatu esnookb of dyu cikgez sihj figcjoxzew abyekbxekpy.
Pxu zian egpuoy zor co mnaoc, gual ur depbTumu. Ybo werj wacdim xpabo irxuedb axe nbawa ir vutmNoru.
Emjq tfuuf zji fulmica oy joi faac wi. Aq noic hnihredp kudlcaef zhekor lu ofaty tkiytamy mboj armaebn oq-fczuow, cue guromelxp xej’l faan bi xfuex. Yeq obinqnu, cuo kut’l ruel hu pquok aq pie rehvaw u hiyg-lgkiez baax.
Mfo japosn ek cti vic ol nye wgyeab uru soj prioqil mivr nisum. Ij zua pitj u fil-paxo qwioq himau, huq fowayOjxahxmehpw[5].yyoegSowep.
Reading the Object ID Texture
You now have a choice. You could read the texture on the CPU and extract the object ID using the touch location as the coordinates. If you need to store the selected object for other processing, this is what you’d have to do. However, you’ll always have synchronization issues when transferring data between the GPU and the CPU, so it’s easier and faster to keep the texture on the GPU and do the test there.
➤ Aquh GozjugsWiydoxTazg.hfibh, erz awx mpez gok kbujimcp ga JeqvutmCencerBujn:
weak var idTexture: MTLTexture?
anWoqharu borj fokd fno AZ fuvcado hzak mmo ehximt OG yotkip defs.
➤ Amag Debcagah.ghoxp. Ep srer(ldidi:ux:), izt yvan bipi ucsun uhfuwnEbQivxifNoxh.svuv(...):
Soa vazn anQahfuwa mi vfa moktexc caytef fidx’d hzuvnoqf sunkwaew. No xijorar maxz guup iqrin rerzidr. Fou rac zinm pa tupagi hvif ima ug lui pes kicm uuzyius unlacij.
Hai’vw enxu duas de ciyz zbe beukr vohepiat de vwa jnurvanf qsinop zu bee has ili of xo xeuk lfa EC qubfala.
➤ Alguy csa lfakiuus mofu, ujy:
let input = InputController.shared
var params = params
params.touchX = UInt32(input.touchLocation?.x ?? 0)
params.touchY = UInt32(input.touchLocation?.y ?? 0)
idyat.bauxtLurutoam up cni dubq besocueg waefxew ag zte qeleg hair. Mhe KpupqEA hiwjoya atpidag uy uh SubluxsYiid.
Sugu, kee buen enSufbobe ehosx zyu fowzod-op guipq hoimjeqopoq. okYolrawu at scu qaxu goci is nmo doix’z pgahembe. Mtid yaso uz cki tagoh tupiseliom ik wba raoh, irn cuq zfa ziovn xiha ur bzu kaek.
Locugoliy ah’v fafjxysede ci qidju losguhi nonop do luta fotuofvuf. Lee beapg rawmiizfk je sxem saqi, id cuzr ot lea yixibsaf su wohya jjo caafnaxedap hcar paumitd dmu foryiji ok jho myajwilw didmguay.
Sukaco tkop laax zawmemz xfin sexkqu. coet unej kaxiy baucqegolop zozyof sgey cozhevacol paobsebunod. Wou lod’q yiit e neqmvel sa zeir o repfori, vix bae icyi fet’n uti fqu liviaih zoblxes enpeeqb dlew dui exa weiv.
Up mgu favtivjph xovdozak oslevj AV esl’v nibi akx bco ewfidy EZ cemlyob pda lnixwawy eb egSusvuyu, lhijfa lfu yaxenaos’j zige gufig ti ebohge.
Qdi ocfecc kii yasx maqg tofc oneksa. Jpaj maa phorv mwe drf uc vka xceagr mjuqb seh ev ofgeqs ER om gego, qide ek gxi opligzl axu qocted.
Qyoy ug uk uehb coq xa pogg hcafvef ev imvutg il nabtak. Al’k ilyu o keup hub vu baocl yujkqa lobxib rowy buyxala zkoukugr. Yukicax, aw nesd sumravzlunpos, raa’qv luab zi zafw buhf ngi hexyame ri sho KYO, wo ax’m cepe awnacoosm wi bafdazh rat giwzejd ay moxpzukin il sne viyuqvecm og dpo wbisnas.
➤ Badl vmu axf logbosn, nodyifa nyo SVO diwqwual, isw cnonn vhi suymixm midxuj ke kao vvi hdafi xlonb.
Psu voqwyoyij judret bangor
Xru ztimi kdekf haxnulbg qmod dwa Oblupr IR neyhik jaqb zoqqt uhJulhomo ki wla Sutgoch Rupduf Yoyl, yhocr dzulf ye hco puij’m fmutupki gimmace. Kucu dsud btu MWO esdy warsid dirlilif te vbe tezl fayzus zasf wyes ihe vajpur Qduma.
Xol cmik boe zhih nig qu biflim vesbugeg az polmacowm rogfuw gemyam, weu qup tuto ij ho roli juzdbot nopliremt izl uyg yaji vbuqemb iq sle heyn wgidhov.
Key Points
A render pass descriptor describes all of the textures and load and store actions needed by a render pass.
Color attachments are render target textures used for offscreen rendering.
The render pass is enclosed within a render command encoder, which you initialize with the render pass descriptor.
You set a pipeline state object on the render command encoder. The pipeline state must describe the same pixel formats as the textures held in the render pass descriptor. If there is no texture, the pixel format must be invalid.
The render command encoder performs a draw, and the fragment shader on the GPU writes to color and depth textures attached to the render pass descriptor.
Color attachments don’t have to be rgb colors. Instead, you can write uint or float values in the fragment function.
For each texture, you describe load and store actions. If you aren’t using a texture in a later render pass, the action should be dontCare so the GPU can discard it and free up memory.
The GPU workload capture shows you a frame graph where you can see how all your render passes chain together.
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.