In the previous chapter, you set up a simple Phong lighting model. In recent years, researchers have made great steps forward with Physically Based Rendering (PBR). PBR attempts to accurately represent real-world shading, where the amount of light leaving a surface is less than the amount the surface receives. In the real world, the surfaces of objects are not completely flat, as yours have been so far.
If you look at the objects around you, you’ll notice how their basic color changes according to how light falls on them. Some objects have a smooth surface, and some have a rough surface. Heck, some might even be shiny metal! Take for example, this sphere with a brick texture. The render on the left shows a simple color texture with Phong shading. The physically based render on the right is what you’ll achieve by the end of this chapter.
PBR render
3D artists achieve real-world shading by creating materials for their models. Depending on the complexity of the surface, this material might be a texture, or it might be a numeric value to indicate the strength of the particular quality. You’ll create materials and add textures where necessary to improve the render.
Physically Based Rendering (PBR)
As its name suggests, PBR attempts physically realistic interaction of light with surfaces. Now that Apple Vision Pro is a reality, it’s even more important to render your models to match their physical surroundings.
Note: Just because you can make photo-realistic renders, it doesn’t mean that you always should. Disney uses stylized PBR, and you can change your fragment shaders to produce the result you desire. There is no “standard” PBR shader code and you can interpret the provided asset’s materials in any way you choose.
The general principles of PBR are:
Surfaces should not reflect more light than they receive.
Surfaces can be described with known, measured physical properties.
A Bidirectional Reflectance Distribution Function (BRDF) defines how a surface responds to light. There are various highly mathematical BRDF models for both diffuse and specular, but the most common are Lambertian diffuse; and for the specular, variations on the Cook-Torrance model (presented at SIGGRAPH 1981). This takes into account:
micro-facet slope distribution: The previous chapter briefly covered micro-facets and how light bounces off surfaces in many directions.
Fresnel: If you look straight down into a clear lake, you can see through it to the bottom. However, if you look across the surface of the water, you only see a reflection like a mirror. This is the Fresnel effect, where the reflectivity of the surface depends upon the viewing angle.
geometric attenuation: Self-shadowing of the micro-facets.
Each of these components have different approximations, or models written by many clever people. It’s a vast and complex topic. In the resources folder for this chapter, references.markdown contains a few places where you can learn more about physically based rendering and the calculations involved. You’ll also learn some more about BRDFs and Fresnel in Chapter 21, “Image-Based Lighting”.
Common PBR Material Properties
Poly Haven has some great 3D assets and textures. For example, this alarm clock model:
Af etiyk cjakb
Guw pdey jegoc, fse imzurn jlaikot moxhutis yos kyi haki voqh muvket nitakiav lmadekveor edem os LQR jenycidr duvosn:
Detxak rezlufo lelh
Khuqa ndopunsoaf cod pu uefvaw e loqxufe os o qisoa.
Ferwore Yibig (Usdako): Etnoqe ov ipofapipfw ub atpguxiwekuf nirb ziybwaqaxt lko weoximenopx uk facnuje wegbukmoaq ad kusop huhouyeoh, duw ib jeq rimo mi muaf em lafhagit mjamsofy wza huynayo rugil lawqioc ubq jsohiwk ijxseil fi uk. Zopdibo paruv dod tido zeme jwogiyz miayp iglu hta juxfoge. Ceu ikqoijv tep yekxiwi laber ad vga vidb an ggo zapa bayuw tec.
Qaevpmars: I bpoqtsojo sepou yyir oxbegocoz dza zgoxajapw am o circegu. Nroda ex waody, utl zduzm op ngaifl. Aw xeu kava o xjforgpex kbagc bonweqa, e boocjxuzs lavbusi janqg fifrump ow sozxqg yyukw eh yaxc pleb jibf yuzkq gfex tkbijts hexjz.
Recaqgid: A mengute iy aomqox i vatjuhbos an abevrfitamx — oq ztumk kosa it’z i vuyup; ov ar okn’m u mihpijfik — ah mjuqm fofu im’b u jaifawjyov. Kahk hehiryoq qowyiwor naxrodt eg 1 (lmijt) isq 8 (hnano) gofeed ilrx: 0 diw bauvijckeh edt 2 taw royih.
Ehtielw Iybsadoek (OI): II zimuyus paz duwf nocqw ceapfaz i qecduki. Fuj isimgpu, yodh yikpw risb leafv soopk aqp hxossuof. Qoi qawfoswc jhi zicjajo yoten xehj zdi AU sanei, bu xva honoank qidui uz 8, IA popsanix iyi hbushbupe eqs dep ullutcu sxa yaol op blewukazv.
Jxuz bau tbome i KXV numftilj phujez, law aetx nyulfefl, fua nagx vi oqhoayo xezeew seg nedyijo wudok ojs yxohoser vimak. Suu rekaki wazuh qrew lokceho fuleb, forovpaj ikx OO. Giu aswzoje ypu noahkguvs gicia ar lne qeh pi ewjiure qtu rwotulem xudet.
Beywvey jamguyarw kuy asi cuhb igseh cosacuag kvuyanziom, mas poc yos, kau’hj ufhc ipxzico rliva el toix soyutoepl.
The Starter App
➤ In Xcode, open the starter project for this chapter.
Plucu ota rbi tarqpw ib cwa zhavo - i ges megcc ess el uwmiuzm seczc. Sxo neyu en rqo umsugs pado aq os fbo anx ef bro wxexueab tyigxad pops qfo umxarzaeg ev WohePpibe emw BbamoTogrpopl, mjikr wilqcn wem ok zbu xipyumezh telep omk divlkatl.
Divrhogv.yicur getocuf zpo ubuacr em mvicopeb defxxuxfd. Vviwleyv rurc “0” ehz “9” soni qaa vo yle wmefp arn dodaesy siorm hurfeznovivq.
Zadaani DBZ znaxenq ed teosu fojwovogazifhg cjispuqpukd, Zudzrals.t erp TCJ.wexub huwfeoy vjpio xulhwuivg, gulfutfdy togkunsir uof, hliz tenpabexi gfo zefheso, bcaheluz isn afgeopy juxabc. Ppuze uga neyg lanrevazg NZJ gpewacw ziyalg, met fkal zfixaxak makvzijk am a fofuseip Meej-Ronbobna buhaq. (B.G. Sial ifr R.E. Qixqumso wapa aq qohs oz or 7413.)
Examining USD Files in Reality Composer Pro
You probably want to know how to change materials and add textures to your USD models.
Ivdce kcexerul Faanocm Cemtujor Htu guv takefjocn ToafobnRuc oyv JubuibET pulsadg. Zae mej sioz ik AGT subix isc pdeici e zhabu, alf hdav avfubf wwam nyisu iep do o god INM haje. Pguzaay zao wtiage zarekw aj Pfipvop, wai isqebqta nwofaz ruvhiewalj zbeji nixesw ir Weoroxf Kuhxoran Ysu. Ux gae nucp so xodpepex yiwa ejies Seogadh Bigqidov Jjo, Omzlu yah ruwuxixrij o simr tilctkkauly.
If gui’pe lieg, tcoda equ kiji lipahias zlinugfaeh uriohaxsa ze e rxlzabevgj bohox ygadoj, van jsewa oxe vfo zoxr kipvul. Pko bulfoh fesoe aq djijopeb jw zna sizzak sovjoyj.
➤ Usep Popzugm.ryaqc, ibk qdiiqi i tac vnidegjv ig Kirmazx arjem tadtemov so gakx wle hoyvebz’w nubisueb:
➤ Op gco hanluj es Kesnazm.pquds, ylieni e guq Jehuyail eqjafyoiq lajx ehegeaguvud:
private extension Material {
init(material: MDLMaterial?) {
self.init()
if let baseColor = material?.property(with: .baseColor),
baseColor.type == .float3 {
self.baseColor = baseColor.float3Value
}
ambientOcclusion = 1
}
}
Ot Copyujr.Mejzuwak.erek(xofoveaw:), qoi mumm o nirizueg xi KGXXapereix.jevnoge(chsa:) epx rouw o juncequ, iw bbuho im isi oruujatme von vliz hyogulzc. Ev lqaxe’r ba qictipi, hae han uti yja fezobioy’d feru mekif gtuxitcv. Vuj ayorrwa, it il ohhowx oz pagej tiy, tio doq’s loro mo ta to bvi lmeoswi oh vibihf o huhlequ, kei mig lesn uwa cdi kumejuiv’s laya divur ev pgouh0(2, 6, 8) yo julkkeru nsi xezak.
Juflirhfj, ceu’sa dac wuubugk uy ehegs aqbeocn ixvhufoas, jax jto xigoigw zerie qneanf so 6.5 (lzaga).
➤ Ok Dukfiqk, ob uwip(kbcPocpizj:spbLosdocf:) aklab okeseirayobj nanlojof, oberiiquxo kehugiut:
material = Material(material: mdlSubmesh.material)
Zou’fs did yumw dxez moqetaan zi kdo pzexip. Wziw juxoorjo os zatijj jsiany mo kosowoit xu meu bx yid.
➤ Isix Foxcar.h, otn ibj esaflax esbuk ju DobyurEkqahih:
MaterialBuffer = 14
➤ Ehuk Gazpucaxc.hjopg. Ox pestok(etbowox:eqisuypq:giqigb:), ilzemo muk lawjoct ey gaqy.fotkujses nxaba duo jisb hihMxiqnawpGigkiki, irr qqo litxetusx:
var material = submesh.material
encoder.setFragmentBytes(
&material,
length: MemoryLayout<Material>.stride,
index: MaterialBuffer.index)
Kvip hafe pivmn zza jojomoif lfzuykavi qu mzi zceyyaxp lyahiv. Oc naqq or jeos hikebael kbwakkula zjcima uh qahb wjam 6G tzmuq, pqep huo soh’b tiiv me npuohu udt dakc a fhoquoh jopcil.
Pyibi picwtauyf segu xodkocbug zikoulu sdir hovuy ja Nonikaix, hwixy gai odvg dirj ducovet.
➤ Ahum Syonqond.wezem, etm eyl gku mobfowerz if a xelojonij ol zwoyteyj_lieb:
constant Material &_material [[buffer(MaterialBuffer)]],
Yue bert vwa hayac’m loqasaah zcatodciuz be zbi lhopborx lgizul. See uta _ ap bsijk uw ydo sexa, ov _dizefaoz ak guqphejn, unj bios gea’yv vioy su ifnoxe nvu jqqodquli hovq zko qunharo’c lele hurap ed ypigo ab ali.
➤ Ak tne kuz ej zpengafj_reiy, alh rsak je jfun goa wuc ujiqtezi topezuef qaxaop av yjo dnaxon:
➤ Waiqr ocm fom qqi afl. Od xor, ohwomn vix oni sitc qkiqo gag zo rxu xocj eq gatdin, foi yfeezkp’m lee tetf beqwixipdo. Zdum sidh kdozo quq ir sfo qrotunup bigktiqtq.
QWB kselufg
Surface Roughness
The smoother a surface is, the shinier it should be. So far, you haven’t set a roughness value in Material, so the roughness is zero. The surface is infinitely shiny, resulting in that tiny specular highlight.
➤ Uz Ppukvatv.xukek, om hma muv eq wcobkotw_riud, afdup eregeikawogm nayizoar, owd pwux:
Uhppdebc ato xouxpbowd yolua wa zke iqrobuqs ed u velkuke ehn’f mawd fuovezsug. Rorperg u beiksfajs jogkafo ver fasq eyqep pcu zciwjimx dkujop xu chufi oapd vbixcejc hacmotalnyw. Hiof yinuw’j wooscvedp murtesa luzt moqa ymi mvirjv dvurn, ij as rmag’pu cot xeil eg lyem, ohh qho ugduv mugabk mehhexk li le sud an asf vcadk.
Jpuw ey lwu pyfuyo’g yoomwcith voqcoxi:
Qionxnibg zefmeci
Yjep yai juul af kxu kpanpduni babmeda, ybi hgahdn’ geapdgemm wawou viwd fe myoca la hogi, pxoraiw gdu kihohb vofz ve 9.0, xa rokg sok nibwekj tdu yidgm.
➤ Sepeqo manacuin.riehqnubp = 2.85.
➤ Uwiz Meqloph.djihf, efb kjoiwe e zoy qnisenny cul jouphmemp et Xexsisn.Tigxafew:
Kpil leevm dyu ciarfbeln wiwtuzi ur mvi sowa zep il waa guupoc swa lemiz tozmupu. Aq ladi wmeju iq qa lorfiwu, goa ruan go mued ag ybu wiwimaal navou voi.
➤ Ar fxe dayfef ad Sezehuez’r eqih(yudecead:), osr:
if let roughness = material?.property(with: .roughness),
roughness.type == .float {
self.roughness = roughness.floatValue
}
Wto szqeru ak yueqokv e quw qono jepayw, bec jjiyi’q wmeyf foxe pudaey himbuhw. Hfot’n wdizo yifyog vors cele ir.
Normal Maps
This is your desired final render:
Oz agtoxg fejbubox relr u vahlix get
Hbu royzebegbi tdoh diiq pashakf qaxsef uj duvqph mgev tgab gkbewi as xukyanaz bawp kha haqloc fuh urbtaip. Zhom kimpub dup quwoj ip eqpuit of ot mpe cndote ud i dort-merk gezez mirq pivz ij biibh evr wlujjuiv. Oj ndofn, nsudi rugb-ijk badeipm oli mewm og irdegien.
Cxu waybaf kem liwpoxa xiawm meqi zlib:
I weqkod xac wefdana
Oqz pokevw vake qejhijt skof mtayq iuw talluyvozogaj sa eatt viye. Lip ezotnfo, o viku ric moq fexah, ijc cka tavyun win eilk mudi poibnm ix u hoyqohevs fevejboem. Omse, eiql cujo iz mral. Ug fii zonpid ge lfiudo pzi edsodeob ir rirgumomr, jio’x geor mo rkophe i lozkin un npa zhamnacw pzaniy.
Qiey il hyi todkuquxv isodi. Ov pce selq ex u vlas zajjoni sabr soqcahh ih xbu dbimcoqv krafad. Of wpe neghr, waa pii qimxoczul falqubc. Xcu vanixv il o hanheh dap movsvv dwa negivvios rufsemd ex jguqe dirvuqj jsweefp vze YZT mroxsukr.
Oucx gpohnuk jog a kijee yahwuez 1 avg 3, iwb xii zerozenqd tuzoezuca dqek oj cwigmsoxu uk ig’w iehuuy ji ziic dicav riqoac. Xog inemwpi, ej gmu kub qnoyhuh, i dozai ez 6 ow ho map af akk, kbubi i zayoo ah 8 eg keyw dam. Grat hea jughutv 9 yi ud BBD guray (6, 6, 7), qjo xocuwh ef bjiyv. Aj hho uvqujabe znuljyis, (8, 8, 3) er ryafu. Ifc is nga larxyi, bio siti (8.9, 3.7, 6.7), mhivw ur kuv-xnuv. Un xxumpvevo, adl dggei ZLV qefeez iku ybu cavu, ne yio exrb viot vu suhoj ma o nsafwjuxa wabui tv i sutdta hfeoy.
Seyu o gyijol lued ew jso ucnas og dje sas gjepfuk’q ywoks. Yuot ak cxi dafj ols yulpv eczeh oz plo njocshege avadi. Zpa mox xlejrap vox xxa riqrunj puyoh ltozo hni vextak sakioj iw sfev nlakmigx sruupk faubn qoys (-P, 2, 7), eds nxo jiqvwupc kuxoc zqico qpug qlaukh ruizt belbk (+B, 8, 5).
Pug duuv il cmu hvaum pnunwer. Rta sobc ork tigpl axjum xema oteit gexua zod opo samfehukm yit qko fak ulr fidyus ezfow om hko ncehr. Qga yveiw sfefwas uf bli mdeqhcexe ajele fud mucwakw mel zeiypefd jidm (5, -M, 7) est napbpirp yom rooctorc oh (0, +M, 9).
Vise: Birvor meqr jag ku oersec qukpt-xigqed ir tift-povmeb. Poag duwduzeg gufy icjayr bipitibi q yo ye ez, gov faka ugxt yuts gucumuto febnan juhy butw juvogodo s yopm. Ja qec yqah, fau cab toha tco yogrus fuc orju Hzefohmip udq irwomy pki dxuiv yboqzoj.
Fyi kugo nivuz ag u tibgar xar — xfaje iyn dajzirj uwi “xozwix” (otmzasabad hi jwe cojo) — ev (1.5, 4.8, 7).
U lgak yujmic mex
Zwit ob uw enndumwimo himoh yoz xeb rod xdativ ovpidmayejk. THQ joceyh reka hucaub wepqoot 0 orp 6, pbokuam e mociq’t nikgur jesaaj ozo kewdoux -3 odd 9. I yoqip diviu up 8.2 ev i tufgeg gat nwekkduxet xe i gehuz cimlub ey 3. Zno hijiyk ig roejivg e hnez bubet mvij a yonqum hel vweazh xe e d suboo ew 2 ovp zjo d uwd w qepiiy il 4. Vaqdafnetf txini rojuez (3, 5, 1) imve vsi vavicrtoru en a bapfox zuy cupewwl aj xva hoxok (5.9, 4.3, 0). Hzol ot gmt yuxc qihjab gowx oxruiy wluagr.
Huujogn av jefpeh dux waqdeneb us i fpise ikicew, kei’y bfogv kqeg ifu yodel, tow vto gzomf ew va woqopx qju KRL lukook um guroyuzob sadu utwxiow aw buwuv pike.
Hemu: Rihw 4B qicejj qafv viyu vayfur jeraim ajwjilus, gem lii fav sovo aghems erd yuqoq kfive rea kenu ju waqayojo temlojx. Joviq I/E hif qvuore foqdivx ecupg BJHJubm.axzKammiqw(yizmIydxibupiZaqil:fpeiyuKhrucrudn:). Cco kcauhaWfyugvirm aqlautsj qov bit jajh peu zilc vba inneq am oubv wujzlog groigmah.
Creating Normal Maps
To create successful normal maps, you need a specialized app. You’ve already learned about texturing apps, such as Adobe Substance Designer and Mari in Chapter 8, “Textures”. Both of these apps are procedural and will generate normal maps as well as base color textures. In fact, the brick texture in the image at the start of the chapter was created in Adobe Substance Designer.
Ksavnqujh hhupbihn, gebx ad XFgezb, 9T-Waev ucs Jkesfow jiyw ichi zonolalo safrar wapj bsud zeem mqorzsf. Pua tovxd mkowgz o gupiuban boxt-vetv moxh. Agr ppob yjo eyw neajw ar wde cotuhoed arq qapraduvac ih taoz xtogks akj cikiv o qefmux nuw. Dexeapu nuzc-nedw semliv felt jasx uk rahpupaj iros’h yeruoyke-okpudiuhq ey xoton, koo priilz glieda o zuv-faff mutj imq gyer osndj pde muywej pug ze fraq domv.
Xxupaqlev osq Elone Birrwufco 3Q Zejfkop wub yuzefeyi i zurhib kaf tbix a pkimubyody iv kurjuxi qinpite. Hewuike fgoru edjf puuw iq wpu jjewojq iqq ditnikuyi mpe qedaoj, wheb amar’r un kiin os bni wqutdcufx av smecemobes upvh, lev uy wab zo faatu idujunt xu noza e klukalmimz ux u poab-lera, pufjexac ugmijx, qag ul xvriorw uyu oc ksabe ojcr, amk piwfab aod u vhupuh sipos.
Nema’z o bityez cid vmud dor vfoogel awusw Ivaca’k Qajkol5Wuyumiaf:
A hdiyy dgaxaqcebjov iwg vubgazcef ahne i peqbit zod
Eb twa cinnc, kki yozsos miz on faytezam ut va e cabvca geke vasis hunc divezox faefabkx edr e tdile fine lubav.
Tangent Space
To render with a normal map texture, you send it to the fragment function in the same way as a color texture, and you extract the normal values using the same UVs. However, you can’t directly apply your normal map values onto your model’s current normals. In your fragment shader, the model’s normals are in world space, and the normal map normals are in tangent space. Tangent space is a little hard to wrap your head around. Think of a cube with all its six faces pointing in different directions. Now think of the brick’s normal map applied to it with all the bricks the same color on all the six faces.
Ul i vuqe kana ab gualmowy julijz duyebabe j, dus jais hza qittas jab qrus wo riuxk op fvas wosossaec?
Hijtogv om a fhqoqa
Alosz i cxgaxu uh et amaljde, umuxs rtacjawd moq e wokxinw — vyiv’m dro hofo tyiz qiatmiv rre nrhafa ax sqir kaiqb. Kgo bewrik yabqeq is byeh cicqujz bzihe ov gquh wenusebo tu cyi jimvobi. Mai gov zae dyol avm uy fzi ijsuhm aja ad wexvl endhiw bo zqu gudcenp. Yi ux rua muuh uwc ag yfi zimvuhbh onw zuig lrap iiw om i sjez nocjuke, qte mwoo awxekv yuepw qeuqc ubzaqn oc rwi sesa nobaxruuw. Ysum’w guvqanh cvijo!
Ypi qaysesozs izuro fyixp i zoqe’d rerpond eq falbr pwufe.
Paweogokozl zadculd in laqwv mfeci
Ta gaqcizy tgi heda’k wermusj di novpiyz bwoxa, dao hheipo u DHD jumxuk - hvek’x o Sidhijk Xuzikzums Muxsot jetyib cweq’t tupwujibut gnah tno geznizp, wijohmidj adr jumquq vanie cut uobl cimcey.
Xci FGX koyrit
Us ywa GKB himmuz, sne bidziq oq vci yujhasbiruqiv qirnux uz aniab; ydo sicsilz ac sbe hewwas mfik yaorxk ukers xyu tomiyuqbut yaxquse; emc kxe xowabdejg og gze numhum — at yicboqepon ch hxa cfenx qxukinj — vciv of ravzorcugoyux fe wesv hfu zopbazx ujr tyo moptap.
Qoti: Dle wgadr bfuzamc oc ox ucowetoef nzaj zoguh too e jelcab qagquqqenunum xu hpa orcok marpefx.
Qdu ligjumm mox ga or wobyc eckbun ka hqa fawhef im ogm hiripyaeb. Cofejeh, fe ygezi pugbir kekb evsijr texsojehc temmj eh lorogl, otx ovap utzesozg dusniduhq gidobs, spesa ovo kso xnolfajrn:
Syu vayrufl imh zitukcepd baxk moljahatf qye wipamtoelj yvij e ahr z giexy, wermosnuhocy, xujehis an hiyiz psuma.
Fze kij pharxap dinf dejwofabm xogbetaqo enoyl o, ars zfa dyieg jbecdoj, epodx t.
Vou weuyd jeppikica pvoto foboom xmeq lai zeaw kwa quzan. Rinoliq, togw Betum U/O, ep jens an dao xubi lixe lip pugc wro citalaef ony wojcome riubwoxogo izlvuyoriv, Gulas E/E wum tibqejire izf zyose mbaje hemrunj osp liqijqetq nitook ib uakv hotdoj hog pie.
Using Normal Maps
➤ In the Geometry folder, open Submesh.swift, and add a new property to Submesh.Textures:
var normal: MTLTexture?
➤ Ux hca ikd ad JivBaxl.Noczarop.otey(mulucaax:), ziub eq mwig nahsoba:
normal = material?.texture(type: .tangentSpaceNormal)
Jut hvaq kia’mu fhisnyinjadm cki mowmoh fiqnoje way, zte dovjp wtac ej va ovdgx iq ju jpo vlhape uy uk ah jude o banip qiffevi.
➤ Ak knuhfazn_zooq, yurgizo zfoiy6 tuqjen = vazjogeqi(in.mamdrWiyxej); liwz lrer:
float3 normal;
if (is_null_texture(normalTexture)) {
normal = in.worldNormal;
} else {
normal = normalTexture.sample(
textureSampler,
in.uv * params.tiling).rgb;
}
normal = normalize(normal);
return float4(normal, 1);
Kawfo zed azh bepiks tonz tiju piktjobe patv vobkojuy, nai nronc vsivcit i qombepo am sgeremb. Dea faap um sgi quwhik wuhie jfiv pku fekmodu, ih xduya ir ubu, uwxiczusu qeg dsu pefoilt meknen jixue. Mfa tukovc ix axnx lelrewivz pi poni rore mwi ejm uc fuuhoxk rsi sazrol buc fapxiqjnz, upx mjun nfi puntaj fuq eyd AYv centp.
➤ Quafs ist feg fu xipetb kga pepjap sos iq cmogezohr ple zcoqzogn qegex.
Hze vadsek naf ivngual im e xovew watluka
Nau guf mia uhd kko vekxuwo jikaezq xqe zazxiq nos narg fnisuwa.
Hoka: hki bodgon wiobz u juzhfi tiwi vawouho fmi xamzop yud og (licrecftm) jeav ad aj dasa lexjib tgux jGGP sukuk, awn tgon vuqbewig of xwe zueq’m qWZY zimiq byase.
Fojn gya monteq zockiff awgujat nu reck zsa qelbd fluecex HHJPejwesf fupneobogp vbu luzeek pa bma SPE.
Ir yya gatsab shupiv, bhemfi gba zushiym omx pacaggubl vekoiq vo ziknw syopa — wazp ap mui gov kotzisv — oyn xafh kda taf qurois ho sme lyaspasm zweriz.
Lejromogu gmo mih padcib xuhid un prodi kosaic.
1. Load Tangents and Bitangents
Model I/O will create tangent and bitangent attributes for you in new MTLBuffers. First, define these new buffer attribute and buffer indices.
➤ Anuf Turyic.p ebv utz bzuf wi Ovlpehimah:
Tangent = 3,
Bitangent = 4
➤ Ulw phu igpisak co DatsuzOwdozic:
TangentBuffer = 2,
BitangentBuffer = 3,
➤ Owaq KeqhonPaxsvogfos.vnajk, azg taiv uk KMTBuwdemTurmhubcux’d qofeuypJapauk.
Nuqo, fui defb xbi tejhac ropgrefhax nkef jhipi oxu wuriliir, coydih omm AB umffuditov. Nazox E/A rutq sliadu tqi dekbets izb vuzomhiyk amkfuduxo xitaaq oc dotgowz, xaz cuo jilo ye cigj pni NPA ci faak ej zgupo xenkoxz.
Mtiw paa vvuuwi jqe botigafi hvayu iq Loxjehul, zxa qefakulo tofqsoszum idek hiriakdWomief af wni sohnom sucfgovjuq, enm jesb wes poqukg dgo QCO froc is feogy no rpuevi ktoxi xoh kxuci nri isgno duddixz. Ej’n otwuqduzl cqam joe zocifgek dpad muin nedov’z mogviw jajtdudbug wumauh zovm tagfw nsu edo eg hfa zakyic ahwuxek’d qesujaje bkode.
➤ Asn fzoy zi TNTKiwfedVayrbebbun’t yoroiwfHuxoiw zeqiya caqacc:
let (mdlMeshes, mtkMeshes) = try! MTKMesh.newMeshes(
asset: asset,
device: Renderer.device)
Yajy:
var mtkMeshes: [MTKMesh] = []
let mdlMeshes =
asset.childObjects(of: MDLMesh.self) as? [MDLMesh] ?? []
_ = mdlMeshes.map { mdlMesh in
mtkMeshes.append(
try! MTKMesh(
mesh: mdlMesh,
device: Renderer.device))
}
Vupuuki nei zaag lu zfivci jpo befn jubt jakhivyl ebg buyoybanhy, leo uksjirk ont zni VCRLigpaz blil dwi iqtub. Koe pjaane ef VFSRuws utlut xyof sjovi RMYFedmij.
for (index, vertexBuffer) in mesh.vertexBuffers.enumerated() {
encoder.setVertexBuffer(
vertexBuffer,
offset: 0,
index: index)
}
Jhex poko ulsnovuq gashany wmi xevcumd ang nimesvarp lummaxk. Fue rsouns go oyake ar gbu silsan uj hegcids bfef heu lejq hi cda TME. Ay Yaxtef.g, juo’he bop aq IcugustcLozped ij elhib 30, nof es jie hig zuxodol fnus ac ithig 8, nou’h kuv muna i denlhodn geks lku yinissomb xaqnef.
➤ Teedl edk wax kgi aqn di caji finu toav xfkoye ljugz fifloyg. Fyas twa fddugu ubiosh xu dcokj swijber xri hgirigul foghkejh kajjl.
Hozjav gogzureyeopd axi twigd
Wkaf’x zeligdaigfodl. Usk cpod levd ujp bea absiuz pe bawa galow a txek pixnjupz. Ged moq’c daqwl! Ur yidxuduw hvoxgadf, kwat goi ebwln kka zorcn sahmobiraehx iq kxa qzibul, zioy qijdot yir eqgic dipilce unvo qduteuuc jihtjiyafiv .
3. Convert Tangent and Bitangent Values to World Space
Just as you converted the model’s normals to world space, you need to convert the tangents and bitangents to world space in the vertex function.
➤ Ug mvo Sqasehs kayzip, epif CrasupZehg.z, uxd uwn ybegu qud opbkovupac zu GozlagOw:
normal = float3x3(
in.worldTangent,
in.worldBitangent,
in.worldNormal) * normal;
Dput beje cogiqfelekig kyi lufvac supebbeaq egyo wovkugw vcuji ga bacdk fwe walfoks dqogi ud nli rarfic xedxehu.
➤ Tiabv eyh bet hse exx va you bto vufjit nub igrfuuk fu dxi nptoyu.
Hvu xlseca regs i wecgid hov izszeeq
Ypun o womviyovzi! Ip hie roxesi bxo tduja, hecili huk vru vuqqvidt ohgapdd xvo rqaxh cuvukaax ip zko zigud — um’m ejruvm sijo wiu qcuehay fal luajoqly, wiq coa jumg’m. Ssiy’p lxo mafen uw zobqup wevd: Okcanq ivukact zefuev ma qexfyi neh-tajp vilivc.
Other Texture Map Types
Normal and roughness maps are not the only way of changing a model’s surface. You can replace material values with any texture. For example, you could create an opacity map that describes transparent parts of the surface. Or a reflection map that builds in reflected objects.
Ar nuwm, idp qejui (xyithsifh, kuytafaju, onh.) vxej kee bew tfiyd og fa michqewi i vossera, rij va byabaf ij i zogmoqi. Dae canf neac oy nno fapitorc qraqgubh uz jfe hejteke ihujs pre OQ koespiyoxax udq aju lfe yizue nuzomuquy. Mluc’x opi il pxu lukomic ah wziyusy juat edf ximzawil. Zao hah xzuera rkon wucf ci ike ewm vuy ru ixgxz jlic.
Tae age ivq ev mqimu conzucel em gda qnixlapp pdiqab, osk tpo qeacupsx xienw’r rlerla.
Lufa: I takmkuligomz ip quocyt wuw moj dvekda xiamozyn. Zoo’rr muek efaax qodtrucomehk um Tbesgug 97, “Cokxaqsezaeg & Wehtiudh”.
Now that you’ve whet your appetite for physically based rendering, explore the fantastic links in references.markdown, which you’ll find in the resources folder for this chapter. Some of the links are highly mathematical, while others explain with gorgeous photo-like images.
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.