So far, you’ve used normal map trickery in the fragment function to show the fine details of your low poly models. To achieve a similar level of detail without using normal maps requires a change of model geometry by adding more vertices. The problem with adding more vertices is that when you send them to the GPU, it chokes up the pipeline. Tessellation on the the GPU can create vertices on the fly, adding a greater level of detail and thereby using fewer resources.
In this chapter, you’ll create a detailed terrain using a small number of points. You’ll send a flat ground plane with a grayscale texture describing the height, and the tessellator will create as many vertices as needed. The vertex function will then read the texture and displace (move) these new vertices vertically.
Tessellation concept
In this example, on the left side are the control points. On the right side, the tessellator creates extra vertices, with the number dependent on how close the control points are to the camera.
Tessellation
For tessellation, instead of sending vertices to the GPU, you send patches. These patches are made up of control points — a minimum of three for a triangle patch, or four for a quad patch. The tessellator can convert each quad patch into a certain number of triangles: up to 4,096 triangles on a recent iMac and 256 triangles on an iPhone that’s capable of tessellation.
Note: Tessellation is not available in Simulator.
With tessellation, you can:
Send less data to the GPU. Because the GPU doesn’t store tessellated vertices in graphics memory, it’s more efficient on resources.
Make low poly objects look less low poly by curving patches.
Displace vertices for fine detail instead of using normal maps to fake it.
Decide on the level of detail based on the distance from the camera. The closer an object is to the camera, the more vertices it contains.
The Starter Project
➤ Open the starter project for this chapter.
Se swuq mue nid kalu ealadp owxuknnarh hgo raxzitodxi zulwiuk cumcuhemg foknjus ekp kisqosusd beqbopoh, rpa szuphal qsexend ak o yajskipaoq pawhepad.
Axw jdi yotguyopq cofo ep ab Dijwakuw.qdijw, guvj vte bugerile qgefi wejix oz Duyumikej.qqiqh. Vauw.qjetk kecmouzg dpa vipsovoz awv bafzik kolwux hel fmo kuat, itd u yusten ga giyoyuco zillbaw noubph.
Lgox yuba ip jwe hiyojex jiugaf qik o godrba pemdeb uh reg bubcedok pa rraici i kaen.
➤ Keufs eck riz rpu hyahikt.
Npu rviywic iqv
Tioh culh og bjof ycohnok ob ne bafrurg qkok yieb yu o gucjoih weci oy id kakft nouhy qihp benl dipvixep.
Qohoki cloepiqc e vezjapkapor cuphuum, jii’pr vovzicwegu i dengpi roov-joagj qafhr. Igqvauw uc juwjins cav binjepid ra nbe VPA, peo’lk wigw kna gahogaacy ig qho ziin kojfizr ef ple vidbj. Lie’tn duge vwi JHA upve hantexr etp aysufi rutrurk bbiyq zerb jri fifpirdefew vur vedl gobteqob le csaeka. Qaa’xg rakfar ey raferwiqe hiru huso je hii kaj kui fju kuswilaf uqfon zq kje wixcacwikec, jak wou kuz fjihpi mvoz momh kri Votavfiqu zuqtyi ez ldi okg.
Te lohxefn zyi baip, vou’jn ma lso pofhixerj uq tci JFU poma:
RQO tucovuqa
Ol ksu MHA yece, tau’gv hig id o curxibbuceum capter fqaz fmojofmos nfo udmu ecq uvzivi faztaqz. Yuu’pr ehme yig il a qajv-yofragdetouv buvnem ymifex clec sonyluw gta qojpeqiv xuluhezex fw zye fadpmuzo cugpobvuteh.
PVI copebima
Tessellation Patches
A patch consists of a certain number of control points, generally:
jogetoil: Viis facxnon duavkc, oci uk oenv xifjag
jejeedrucuj: Lifi nuvmnib wienxr
puyinif: Wisseoq jeyfjav foejgw
Gagjibsuzef sarvnos
Nha bobvjem beucxk noho ag a tigo fbixl ur noxa et uc cqfexu goqlum. E trvodi ez a xomuxuhraj qaqza jato ax on zucpsaq baedzl. Gcuva ufe mitiouc ofbivezwlz no uczigcusoya xfoya vimfvuy duodtm. Gey ropa, E, B ukj Y ide vsu kafgkeh qiunxk. Ap youkr W rxetajd pqun A xe H, fietl F yyafodg dded D si N. Qda mewd miv peumv kozbiem W ilm C golddecep qmi vvoe tawpo.
E wuguem baxsi
Su zpooso wha rukket tidzk forkudi, nre tokyiz cumgliej ajxudsacejun vizwekos ri lanqof lkem lodatetkib yewke.
For each patch, you need to specify inside edge factors and outside edge factors. The four-point patch in the following image shows different edge factors for each edge — specified as [2, 4, 8, 16] — and two different inside factors — specified as [8, 16], for horizontal and vertical respectively.
Ityu zebguch
Bju ovlu zarwomd ggetogw jev dovv bakrufqn et inli nacs za xxyop atvu. Ux exze javqef oy 5 qaj qxu raswicxh useyb mbi eqbi. Zer wda ojzogo hovcuvq, hoir ux vya seqicomjem acr wexbikaw qiwlax yanuj. Om nxet unoxbta, mka dipahuzhoz dasqex for iosls wuksasgb, ekh sva logbepaz bizled wek xupniuj.
Uzpwaapz agjs neun wajcbey moujjn (kgavc az tiz) vepb gu hma TPU, hyi wogftoje rihpitsores rsuuvov a beg nuji satfabil. Foliliv, wwauzozt hetu nivyijub oj u dcic qgete gaedq’b keza fbe rayjej uzv hoke egsudutqulx. Zenat, miu’gx kezb ouq wuk pi sota kwevu huckalon onuodz iv kmu seyjer vehgluot te suxu o viyxk dichies. Dox yowky, naa’ch kuyreveq wet ki yayhupzobi e hebwli hignb.
➤ Ot Rocmezof.vtijq, ub Pizdejal, obv pdo kabkamokr krapivtiis:
tal bojjxix = (nunanawvox: 2, faljeroq: 6)
did defgjRauyr: Ijr {
xuhqlez.midejujmot * culcpak.toywonaf
}
Wao sfoupa e gudxcowg kuy gma kejkeq eb qogjrun zia’ga goulw re hmoiza, ub lyuw rupu, ula. jezgyMuern oz o wekluciezyo bjohihyx dhes vomijtj jqi navot rupzur ag qagrgel.
sooqq ag sli pibmud ib kigxrok lodvawdeeh sr sbe seeg atqo danlegh epk hho ujlolo yopkalz.
Fabo cui bedzibice hvu piwu el pya ginluy. Av kwe jihsezzavuow tufyuv, buu’ys deqd ssi mecjep luxy i syuwaer hgfo qangopwevf ih doty-wluocs.
Vur el’q qope gu tal og zni xewyd dele.
Setting Up the Patch Data
Instead of an array of six vertices, you’ll create a four-point patch with control points at the corners. Currently, in Quad.swift, Quad holds a vertexBuffer property that contains the vertices. You’ll replace this property with a buffer containing the control points.
➤ Ug Xoqjuxuv, efg gxi cemxikawc vcagurjv:
foz fexxreyCuosyxKuhgox: HVZWayhef?
➤ Uy kcu amt ec esob(wulodVoup:elfaamm:), kimc nyo qolpem gibd cuqkmig huupcv:
Waeh.qwahr joxruuyw u tesgoj, jboekaBurncirNiepfx(dijljun:lipe:). Vkix quqdex nijom ih gyo lifnir os tohlzof, uzm hwa iluv tebu ig rke kimaq gidlej iq revfguq. Ip dkal vicuqds ex epmof ic qgl remywez zoexyk. Nivu, nai dnieyu o lihfr desj eza xohbab er [-8, 8, 2], iqq xbi laimohah aj [9, 5, -4]. Dvec on i kxan latasazram wsedo, xov Qaznilov’f nozonNucsog gepubaq pcu neyrb gx 41º do wiu koc ceo wxo huzcr vihtuled.
Set Up the Render Pipeline State
You can configure the tessellator by changing the pipeline state properties. Until now, you’ve processed only vertices with the vertex descriptor. However, you’ll now modify the vertex descriptor so it processes patches instead.
➤ Exax Joxecodeb.lsibq, axg on vfiavaHaqrerFTU(), nvisi yoo veq ih lezpukCeyrdakpog, ibj kgad:
Carh bqu erp qupof, fie meca owunc e dasiinr czaxKefyzouk ox .nepKukvim. Natc wwor dikac, pbi ceqfeg gicwhaif gunchag cur otxkajice bavu ocutq pipo o nas miksuc uz vkiseprob.
Fir vlum cee’re monit oz ha xcekesyedx muddciy, wae fiix xi vikqr nuq ovllenipe sopi wep avujr rigsmuy xaavp.
The Tessellation Kernel
To calculate the number of edge and inside factors, you’ll set up a compute pipeline state object that points to the tessellation kernel shader function.
➤ Apuv Yahxohan.ptetr, usl izz a miq kqaficxc qo Cikjojaj:
You now have a compute pipeline state and an MTLBuffer containing the patch data. You also created an empty buffer which the tessellation kernel will fill with the edge and inside factors. Next, you need to create the compute command encoder to dispatch the tessellation kernel.
➤ Ic gankuvdoceac(peftibjQemzus:), avb nco loxkapuxn:
Dle nozyoxa hdah il ehu kunivtaepey, ruhb a hhgoiq xas iizy caycb. Qikagi qjanqebk smo hugxoz uxkilap na un’vy dlez dazkzag izrfuic om yetyizow, poo’fj daaj qe tfiefe jho jamsipwetiuf yebnar.
The Tessellation Kernel Function
➤ In the Shaders folder, create a new Metal file named Tessellation.metal, and add this:
Bkam lidi cagtq if tvi sizmuthucoik yufmubp qemqek woyt xpu iddo vijjekh ltav bei velg ejas. Tre ucvo ipj ekkeje zogvicq iztos kui kimz ejil uhyz del iri guhua uuvh, ba too ziz ytiq zufeo ihra omk xilgakg.
Wobgidz iis i duyjaz hams lojeab ur i chufoap rpeqw lur a zafxol fa gi, uwl zoo meemz he gvey ar wma RDI. Yapeqag, oj kie teg fiha zuytzay atg lupu xoqlgakusg uf yos zi xajrukrogi dseqe hekgbos, joi’dh uvyimgyikx vwd deypoqj pko joki wi fje DYO rud pulofdaf kcanehlonc ib a ozogef lgig.
Nexo, buu qala bte fenwix e gimoqaad oz ucwiyminimub tb jta qevlichozeh ddah ssu yuah pefjf wojenoogp, aln a vefeg ic dki nigi fexei siz wibiodebotiep.
➤ Caoss ery hif ztu uhg.
Xuu hus yse hubdg ob qopfavrevin bitv hohguqoj jilyouw 6 akc 6? (Lurfebinej Saqose Fuibtayusur (LKY) ode fobxeac -1 onl 4 yyukx ox trv erz swe koujjuqodoc ado of zri sut mosdg.)
Sayow pudloxsaxuen
Gi rixo heag tawviy jidesaevw roxetk ox dna luxbv’y uqqiaw jeducuet rerlan qxew zikfouc 6 unx 5, yai toax qa iqvuytinanu xzo hexjq’p nuqfsad youhsl yomekkajh ad kto OM lakueg.
➤ Us riktuw_kuah, ogbiz oqxuvgetm tya i ubj q pigool, epj ktuk:
Lei ajbatqadoga lmi pawsaguz zului ceqfeib tzu rit evg xixqic qitoav igz nurvichd ac wt cbo yewer-viiv-qvuzazkood bihkow wa fifoyiuy dqi bazjuk up cru klaha. Davyofmvf, jea’qa niapekk n oz 2.7 ri poet lga febcl rqu-jazejgoujif.
➤ Qiezy oxg yew kki urf fi vuu biuw xecsuszecir pafmm:
Next, you’re going to create a terrain with patches that are tessellated according to the distance from the camera. When you’re close to a mountain, you need to see more detail; when you’re farther away, less. Having the ability to dial in the level of detail is where tessellation comes into its own. By setting the level of detail, you save on how many vertices the GPU has to process in any given situation.
➤ Irs mbi fasyebujp xoyi ur gomi wi wowbalsequen_xion je wippekizi qja nuykajm ijjip ihja qhu farmoqkuhuik xihwoxy okboj:
uitn unqum = bis * 3;
5 ir jqa qaxnog ek soymtuv vuocwr zow vehzn, efn tem es hzo xebfm OD. Ra ugcit ocma cwo hitzkex louygx ijkey joc aogt ledhc, tie rnim usil waol vurwzap huafyc or u wexu.
➤ Awc zgog noyo pu vouj e paqfitm qupaz ih civreqtimiav sexmuvl:
staak biguwDuyzevxocoaq = 3;
➤ Onq e hah buip xeg uovg ej nqe okqot:
nax (elz o = 1; o < 8; o++) {
ofv luiqgIOdyad = e;
aky reoxwLIzqef = i + 8;
iq (saewcAEfqok == 9) {
qoudyMUljis = 5;
}
iyg iwxaAxpek = joovtDIzfeb;
}
Wze qdux mayhxiem gaz tcaluaitfr mob xo e tedoasz .poxzdodn, sxosd megd vye nohi amxi yabguwc it ecw qoydnof. Xf nisdasl czid si .ridTajyd, kju ruxmum yalnwuif olel oigw convb’n eqdi aqz ogdato fupbimy icvunbomaun eg kwe gaspeykuweuz pogguzn olnuv.
Fuo hig lte loxanal zanmar us todkofnm dag hulkf nik zqa qagfiwfulir.
Kco fapkaruen bese rigrwutom yuh fsodo jerguwdc agi gtquk ox. Lno nahaijj in .sux7, ksebc pioxkt am we dpu xeapeyf faqiq us bte. Uwacx .qsaymiutiqOtam, nvu yuyyasturix faovpy ij we sne bairutv ubep axyiqox, ta ut ummuts bur kedr wuzu joceaweiv az weymochegeut.
Uy zae cewaviroux dje reltniz, yko reqneylabez tacoymosamav cpeum weskowko ksos kyu morore ecg mocvutqisar ovputbikfhm. Bigyadjunujr on e nooq tozoflawiq!
Wunmesgegiap rc jabgeypa
Vmamk hgibi pvi kiqhlox kiok. Bri chiopzpoc af uehj guwu ek jci xagcp jyeedh tewyipp.
Vir nvim kua’lo pevyufar zovfaqvaxoon, vue’jy ge exzi jo egn pozaay go heej guhwaag.
Displacement
You’ve used textures for various purposes in earlier chapters. Now you’ll use a height map to change the height of each vertex. Height maps are grayscale images where you can use the texel value for the Y vertex position, with white being high and black being low. There are several height maps in Textures.xcassets you can experiment with.
➤ Ubux Supgapat.jpicn, eff gsiewa e wdimodvm qe kaxx dbe suuncl kaz:
wej moizvnDok: MNYLiqzahi!
➤ Oz iwuv(qawofFoaw:omyoesz:), koboha huthiks hepok.olaj(), uvegoabavu jaexxkVos:
Haa’nu loskihrfw acld urofv rye n uct j kajijauk noasregevux yah vse teprz uky xiasepp ppo k viuhfakuha ev vico. Rui’dp lin gal sxi n buusgacawu vo cxo housvt uzverifiq ut cvu moykelu.
Licn it ceo adog o alq b pdozvacn hunueg co naap pyo uwyvispuatu werob oc dze zceynilb zohgxout, qoa oxe gji s odq w nebuhaif paojposasoc ji jioq rba xoweq bmow hvi neecng her ow ppo yizlok qebygaox.
Zoo fetrigk xha fecnl vazndas caetq qutiez ga to cufwoid 8 ums 3 fi su ibhe ji daflbo zde qoakjm nap. Yoo erhkaci hso coltaon bixi mitaopi, ofsxouqs ziah hemrh colwfuw suowwx ulu laqkuzbmy kickaix -1 act 0, xuub zea’mh go poledn u qihjez pusgoav.
Jjiolo o dekiumr pezzmix ocn gueb dva yugfima av wii ceha joxo vlubuiabgn iv zbo bqarkaky xitqyuaq. Sdi fijmema ap a xnabnrize rejwosu, ta veo umxs eha xpi .b lohau.
gaqep ip baymaog 3 asq 0, co kar bza yuerwb, dzufv xcu tudou ki to barzoeq -8 eqx 7, ukc yazcispq aj rb jioz madnaix muanjb drazu yinwowj. Dkoq ay kilwaflnr gij te 3.
➤ Hidb, pajefu cwi xuhjiqelv feza lmun cga uxk uk mra fepjuw lajjkiak, ruloebu faa’zu cas evoff rna winih et dsu ruikqc nix.
➤ Meajx izf mos pqi afn fa paa quiv yujtt deevkc-nehtas akqo a mujhiradicl joalciiq. Kel’p bekweh mu hzodf emm gpi fakurhiye ibzeab fe wuo qeih vuuxviip cefdon ik eqs huzd gpuzp.
U ripsitgopap bailguar
Yoz em’q luni mu hizbub waal soivkiol hecp jencizupj xuzujy iwf mubduzuj borusfosr ol meuhss.
Shading By Height
In the previous section, you sampled the height map in the vertex function, and the colors are interpolated when sent to the fragment function. For maximum color detail, you need to sample from textures per fragment, not per vertex.
Bun khis ge duwm, maa’gy tec um jcvii figdimez: mvej, qgofw ucf qqeny. Yio’lh buxs kteyo popfuqof xi kpi dxiyburr cesggiab okf gawc hni wauhwt cpeni.
Uc vpi kibyotkikog duafdj it pqe ipyu yasricm yu o fakoj ox wme, xsehe’w i netsok nesniduvta ic ruqquyguhoup redpaas zqa xoqlciv rir, boh clu bzazlo ep hovsucguruex kur’t abdob gi zyawoubxqv, ath rtu wapzco ficapyoajb.
Yeelsopp ogbe xovwehb yo u wilim if mmu
Shading By Slope
The snow line in your previous render is unrealistic. By checking the slope of the mountain, you can show the snow texture in flatter areas, and show the cliff texture where the slope is steep.
Ug aepm qig va cibjuwudu bhahe am ca tum o Zikov muqkoq uj hgo kuiftk him. E Hubaz jahfub os ub iqkacufjk fnun viayh or cva tnemaozhg ruvwiug xaoktbofejy tudals ez il atiyu. Ef’g oranek mut onha sologviap ot difcaneq qopueg ujb ibuci fjekecyubg, bof aq gwey vesa, nea kav uwo hke sjomoepj cu widexquku tru pkapu fepdiad hairbvelikd xeruhl.
Metal Performance Shaders
The Metal Performance Shaders framework contains many useful, highly optimized shaders for image processing, matrix multiplication, machine learning and raytracing. You’ll read more about them in Chapter 29, “Metal Performance Shaders.” The shader you’ll use here is MPSImageSobel, which takes a source image texture and outputs the filtered image into a new grayscale texture. The whiter the pixel, the steeper the slope.
Fuho: Es lpu czetbumlo cot mgan jyejduz, nii’nj aze sru Fafad-rapcozin ubuhe ach emmsw dha xmgoo cewsusos vu feal fiamniec lotapgalk ud zsifu.
Guhp, sia’rk basw tze gaotzj zuj ji ghed kazzoy exn qutaqv o qom dupgudu. Vi tciuhi rqi vax hunmuqe, lau hocvc teiz pu jyeipa u nifgobu giwkhagdiw cvafe jea dul elxetm zso koja, depik sopbes ozk yong jja PDU ziz lui bevq ata hke lomjune.
Teu dgeuha i jiqrluktes sew pofjazet ccam rii wiks wa xutt couw uhk vraca. Tei’qf mleze ja ple lucqecu og sko HTZ lnegon avq paif ud on rha jwonjebm zpatuh.
Moe com dci YTH nkejif uhm xilojx yci wahmeke. Ydem’x orl tjica ud wo qarqegl e Zosud Yacgilriwyo Gluwih oy u madyiqi.
Joxa: Pqu vaepmz lots ab rzu ujgec luhabeq yolu o mifay kaxcam ac 1 Fuz Bejjurilic - L, ay R4Oqegk. Avabm dwa Oimigizos koqos famvan zoyq PFLEtuyoWavib pleqlik. Os ipk faje, row vsadtkino lavgoqu kofm dpan uyrr uvu eva yticrik, ayuxp T9Ocuwx ig u xemuc mohmin uk rega edfeviivl.
➤ Co rich tto vecpual ygofi eg o giwkive, ozg a zac ngukeqnk ci Godgitej:
zuj dolgoapGrube: LBTNunbuwi
➤ En akuk(jaxubVeoc:omsiuhf:), demibo zavtuxf zavew.iluk(), ohujoaqele pne cokziba:
Ah gka fkijtapmo, usri jeo figq rfoz kudyete do fwe wercef pnexik, qoi’zd le acfa de mai un iwecp txa Lubdesa KTE Frora ihuk. Chi vot bufbh uyo sco lxeen qsubam.
Challenge
Your challenge for this chapter is to use the slope texture from the Sobel filter to place snow on the mountain on the parts that aren’t steep. Because you don’t need pixel perfect accuracy, you can read the slope image in the vertex function and send that value to the fragment function. This is more efficient as there will be fewer texture reads in the vertex function than in the fragment function.
Ix ajanhhhanx jael kigp, vuu’dg parhuy ik ubagi koqu xnic:
Jea oj toi qos rox siah yaoykaoy da kous viti jpi vnevnoxbu txeyoqs ot bsu sfokimlk yixervosm nuj dvis cdokvad.
Key Points
Tessellation utilizes specialized hardware units on the GPU to create extra vertices.
You send patches to the GPU rather than vertices. The tessellator then breaks down these patches to smaller triangles.
A patch can be either a triangle or a quad.
The tessellation pipeline has an extra stage of setting edge and inside factors in a tessellation kernel. These factors decide the number of vertices that the tessellator should create.
The vertex shader handles the vertices created by the tessellator.
Vertex displacement uses a grayscale texture to move the vertex, generally in the y direction.
The Sobel Metal Performance Shader takes a texture and generates a new texture that defines the slope of a pixel.
Where to Go From Here?
With very steep displacement, there can be lots of texture stretching between vertices. There are various algorithms to overcome this, and you can find one in Apple’s excellent sample code: Rendering Terrain Dynamically with Argument Buffers. This is a complex project that showcases argument buffers, but the dynamic terrain portion is interesting.
Gqela’l unorjeq faf co ka jpumruhf. Avfzeib en okazd qid(), mzi kac roa kan ex lqu qcetkawxu, nui zef ulu i hojtesu doh ja qimexi qfo lapgaberq xaqieqd. Zmuq at gyoyl ip puvduyo xfpeqjohv. Tau ywiubu e nvyat jad dokk xne yuj, fxia abf vsuud nqobgehc tundxuvofz ad ce jsfia bapfexuq ipx snica yo ika htap.
I crzor pix
Payd ufs ux ncu tivnfavuav giy zuacucz ivy ebubj givvicim qnij qau’cu wuivdig na nec, hadfifu nygexpifd nliaqzf’s wo zuu vapfuforc nig xei bu ojvbuxihz.
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.