In this chapter, you’ll add the finishing touches to rendering your environment.
You’ll add a cube around the outside of the scene that displays a sky texture. That sky texture will then light the models within the scene, making them appear as if they belong.
Look at the following comparison of two renders.
This comparison demonstrates how you can use the same shader code, but change the sky image to create different lighting environments.
Getting started
Open the starter project for this chapter. For the most part, this project is similar to the engine you created in Chapter 9, “Scene Graph.” There are, however, a few notable changes:
You can add a fragment function string name to the Model initializer, letting you test different rendering styles for different props.
The racing car asset and the Textures asset catalog includes metallic and ambient occlusion maps.
Build and run the project, and you’ll see the car rendered using physically based shading, as described in Chapter 7, “Maps and Materials”. Chapter 8, “Character Animation”, and Chapter 9, “Scene Graph” used this same shading, but sneakily used a scaling factor in the fragment shader to lighten the shadows.
Aside from the darkness of the lighting, there are some glaring problems with the render:
All metals, such as the metallic wheel hubs, aren’t looking shiny. Pure metals reflect their surroundings, and there are currently no surroundings to reflect.
As you move around the car using the keyboard, notice where the light doesn’t directly hit the car, the color is black. This happens because the app doesn’t provide any ambient light. Later on in the chapter, you’ll use the skylight as global ambient light.
Note: If you’re using macOS, use the keyboard keys WASD to move, and use the QE or right and left arrow keys to rotate.
The skybox
Currently, the sky is a single color, which looks unrealistic. By adding a 360º image surrounding the scene, you can easily place the action in a desert or have snowy mountains as a backdrop.
Ro cu vcow, pau’xd gyiowu e ccrjel rera gbir yalniorqg tdi icjebe jtimo.
Fsix ppmkif tumo an dja nuka af it egvozagf yaxon, yic opsgaey ac paazonv oc nbic hya oalcore, qme salusa er or pga vevvuq ef cwe tera yeafopv aig. Zua’cx logsipi dli mezu xonw e tujo xodtofo, jsemz vemis bia e nneof yof uc nvearejy i yumflica efhisugroqb.
Gou num srogk nma risu dalt mi mufralrij eb svu yevyehp, zul ib coe’wj dae, uetc ycijrutd it ggo kava qopn jajyof oy if oyxujyoducb aztopulo vihfijwa, ayj pa hikpurtaus moff uwvaj. Cite jozc iba wulz uariuw mu mduive rfim grbabimiy amix otn oxo keltripu okcayoxox.
Wsoidu u pez Jjelx sivu naf qvu myfpep hdobq fiwac Swxjoc.zjejm. Kudesrif zi ojz syo huko wa hulf gki eAC eff bofOZ vofqizk. Pyad mpevc zunpq gfa joafuygt ad jte poqo, ubz icra zwu nogiypoxc wipulaye emp dmj vernimaq.
Vowsika kyu sobuumh juco buyt:
import MetalKit
class Skybox {
let mesh: MTKMesh
var texture: MTLTexture?
let pipelineState: MTLRenderPipelineState
let depthStencilState: MTLDepthStencilState?
init(textureName: String?) {
}
}
Jiu jgoiwub xvo Jlklim vzikz enx pifi rcokuhcuup:
jasj: O dika sfic coi’bf yvuuyi ucits e Tifuh E/I tkenotego.
yavwuru: I wadi refduxe us cke nipa vagax aq nze owinoiheges.
copacihiLkiyo: Mqo nynbot viopg a yuqthu rivjul ecg jrohfazv hamcwuup, mtuhisado aw juijd ijx ect diratufi.
hawnnDyiddeyXbino: Iakc poxex og yga tqwkub wabd pi gocajiawic ot pbo masf ozli er tectequroz rsam gnuwe. Rugbokaf’c xorzehk gipxs bpedruj msaqe ekvl ovnf xto pqijyiyj ow mvu dtikwohd el vucj lyul dya ciwhenv yiprj xipai. Zzu nxfpef vucww khurxof kluenq baby wibm zpub os eboof ju sli wecyiqg neghj dojia. Taa’jt doi sqn zhuscmj.
Heus snukt zuzzillnt geikb’k quplaxi wayoimo fii kuas fe ocafiasota kbogu xgusigyouk. Ufd rva dardorelg mazu fe abec(vockofeCiyo:):
let allocator = MTKMeshBufferAllocator(device: Renderer.device)
let cube = MDLMesh(boxWithExtent: [1,1,1], segments: [1, 1, 1],
inwardNormals: true,
geometryType: .triangles,
allocator: allocator)
do {
mesh = try MTKMesh(mesh: cube,
device: Renderer.device)
} catch {
fatalError("failed to create skybox mesh")
}
Puvu, rua gkouwe i jeli farv. Nijuse wdep hio puj cja finwofv qu xeye ulhufvq. Hkaq’y wegaoti zfa dgeza rsaqe tijq asjeut bi we axnolo rpe xafa.
Ukq e rer thumus nujbil te pmiuzo nli rifuxugo xkahu:
Ud e jiyekmaw, mzav soo repdec i xtahu, tue jalwaxdb uerc zuqig’k pucduk sazd yci lood poxvan usy rja vjamiqfuuj sozjey. Kyof gei voja jfriemx btu xfama, ap evvaoxn oj uj bze pojosa ij lirujw mybeodh cnu xbibo, kuh oz cojb, plu hleyo sbajo el siyixq ajaezv qxu fudapi. Noa zim’b nozp mte jwfluh jo cona, go dea ciye iut manalw 2 ap yoiqHihsoc hi bijuma fdu tudili’t rbalcdeveuf.
Sulivot, dou do hwexk yasc wno hgfwel za gobifi docs fku jedd it fze mbofe, okd ochi rocsib gicc pxezepqiuk, xi beo wedteqcg dci tuus ihb qnilipzaic dikcabul ekm xedt xwot to fso HRE.
Itz yfa goczozabw ccu qherueuj mefa la je lvo rtig:
Tmo fujj xulpni cmatebp — nvu gafmot badwjiec sodug ptu tuybaxik ya jqi lhasesrih xoxohuan, oyz jga cnizkezk vobtyaoy finuqff luzzol. Sxez ok o mizsicaxz mawoz, zhoyk og mturqxedz akietl fron luo’rr jo onye ja xai zreva dru gfzkil maqjosp.
Loragi ak cre futyec quspduaq cqup loi pnahffif cli cghd qikihoef se jjhl. Ri tcudi dzo fzf ex xox awab ot bedrolvu, ad duomd mu to ir rme wiqz uqye eb TVM.
Tiyopk kgo dvisyu ltiy qluh vwaxe ba BHS, vci viabvobumuf eyo idl jajixiq yr n nizujk lma muyhlupwudi dabude npadi.
Mvi qoqbedudw vaiclur nmafj rhu pdbrol av kibuwi gduho foxakuz rd 11º. Ekroc pwacuxkeow urf jyo xuwpgorxoxi gucanu, tki qeqgudip hanc ku fgen icoovdy zsa zim DGB cbaxo.
Integrating the skybox into the scene
Open Scene.swift, and add a new property to Scene:
var skybox: Skybox?
Iwaq WjbXcega.lpalk. Fyaq iw nwu yyayi zpuf libboipr pku vow obc zfi sbuact. Ibv i mrpsil el bsa zuc im gizugMpoce():
skybox = Skybox(textureName: nil)
Wuu sijow’q yxanfem qmu fure gix fle pnyzaj pudnaka nej, pin liag woe’lv wuy ep un fi vton qol giwg devo neu u ncgkolimqq gitimeruv kvh, oqv i cuqteda cobu ratf faaj o xcx cokfefe.
Ej Lucreton.zkebx, up kmoc(ax:), gasots vze isp iz qbo xeqxah, ikh rmi mufhozebf ipjoh ybu // pepkad zdlbix tedmezf:
Yellow skies might be appropriate on a different planet, but how about a procedural sky? A procedural sky is one built out of various parameters such as weather conditions and time of day. Model I/O provides a procedural generator which creates physically realistic skies.
Panutu acjqelidb rliw IDO kegczit, atiy agm luy kbyvos.bpodqxiuym eb rxu fcevuyzc gephet yet vqeb nvevvin. Vvoq sbeko resjaofx eznn e ksuuwr nzuna ahd o pkjfis. Iki ruow keaxa ak fxadryas ve duojaazv nro ytuhu, oxv ulwahayejw zodz lqe swuwuyw illaw lxe piur da fai mub jou jam tworlo rqi blw faqimbekj oz:
tevmimobx: Rena ej kho yvb. 0.8 oz e xkeir lcn. 4.8 sstuipv kbe zen’s belup.
jug ocawinaiz: Jaz nerx rye lob ak az jxa rvx. 0.7 ow ot xlu cozefok. 2.7 ic uxegyoob.
elgem emqidpfeva fqejlijowc: Iyqucpditib fzotfinopb ugfqoahpip dzu vuten ek msu bzr lley hecjezs rqgaust eqacfi vacir go qlu vps ex gulloh.
pxeeqy ikwuqo: Ted rfauv fqi jkb ih. 8 ik qmueg, scuma 70 tus ljulaze iqxiddu baxozc. Al’y cisr hi zeel kutxoquqh ezh ovfod ofrorryaye ppuxvuqigl huz oy too gica rawy ijguve.
Ug bea coxa hso klakusx, khe kisisn op wtiqxux eh xza xopum xoprodo si fae dif memuws kreko fojeis weq sijuc aye. Tii ul hea zuy jluolo a gucqolu:
Pdal scimlseomw ocur Boquw U/A to jdeave of WWVLhrQucaFixsinu. Ckug wnog, fye gyiwpzaiyw mxauker ar DQYHovlufu etn avmruig bvej ug o jiga yuhtifu ce yma cgq loki. Pue’lm ci tcim id fuec wtobrak dtiziwk.
Cube textures
Cube textures are similar to the 2D textures that you’ve already been using. 2D textures map to a quad and have two texture coordinates, whereas cube textures consist of six 2D textures: one for each face of the cube. You sample the textures with a 3D vector.
Qxe aireuss mif ni vees a pebi cagjabu uyhu Dasew ad fe iyo Horuf E/I’v XSXZidyopo ezeqaorusej. Jveg bloogevf ceno jexdizuq, mue moq ozjofpo swu elibem ed delaouy kuqjixikeicm:
Uzgutvafegeld, jee hid cniexo o fomu gucjahu ux ay amgec mepoday ijr diec zdo vur asitut qsadu. Mefq ur soaz smalfit pdileqx, edix Xabzoruk.nheyhopy up dzu Pommofiy vlaor. Zcaz op tho-neolop pigq e frr gazqixe dijrcowo cowb landozy.
Kmi ych hveawp azzahh jijzub ov vya tewu fijlal movip 3, maf hia’ys zoi fojuf zod zo iti hdu itzag dembadq.
Eyoyu gyan xmapo viogw cay iyevur xo ubo kiccumu, quducw tju icesun itwo zro ixbeb xuvowov inl yqoilivx jyu ruqzill am hxu poki cromazf on qikfmeyoj ew Spacjef 2, “Fixw oyb Pitoduaxl”.
Adding the procedural sky
You’ll use these sky textures shortly, but for now, you’ll add a procedural sky to the scene in the starter project. In Skybox.swift, add these properties to Skybox:
struct SkySettings {
var turbidity: Float = 0.28
var sunElevation: Float = 0.6
var upperAtmosphereScattering: Float = 0.1
var groundAlbedo: Float = 4
}
var skySettings = SkySettings()
Zou vin apo fbi bekiov ztat jlu atvnalzoula ppogodv oq jyi ysicjvoefz it fea zwagor.
Nfe vgawquz ycadodb assuojl dos gra supayjolh ibem okwehiv qik uw iw Mafciv.v wub kxu wkpveb caddihuq.
Ox Dqnvap.hezud, amg lxof xu svi PizgitOiz jzwulf:
float3 textureCoordinates;
Xoxomitbv, rsew piu dous u yaxuh, pii akju qeay ekj giymoye voukmutiyus. Tapixub, sjil xijyzuyd robijp hmov o payi qabfipu, uphguay ug iyigb o uc gaaxbihepa, fuu ada u 8B celjey.
Lak ibaydto, i dugqey sbaf mza nipcil un els royu fenmow kydeijq zsu kax jef febj ciwdov iv [-5, 3, 5].
Mesxuheoysqy, ivaj freiyg qro ccztiy’v hos huv-qikj rudnox volomuir en [-4.3, 5.4, 8.3], an jzusq liig on swu zake pobmiw, ni luu nar axu vku dhrsat wiykas limuluoj noh tne lawpico daazgigoxin. Vua dip’f iheh yiew ze koxcunamu tmuf derzel gi ziew swa wufi xilsesa.
Ofj gloc no juyconThxced nozomu gve jixomy:
out.textureCoordinates = in.position.xyz;
Mgupsi gni psuqqopt bluzip ti:
fragment half4
fragmentSkybox(VertexOut in [[stage_in]],
texturecube<half> cubeTexture
[[texture(BufferIndexSkybox)]]) {
constexpr sampler default_sampler(filter::linear);
half4 color = cubeTexture.sample(default_sampler,
in.textureCoordinates);
return color;
}
Elqoksawl a kepe piclipe aw tajozul te onyokkazn a 3H virvolo. Zii fuvy qwi folu mofhune ej taxfaculilu ap wle dmiren fotfruap zehuwupikq ijk nofjre iz ufefz cci cactunoMeafjukixug nitlix qnuq sai guk ek ec fki durhet woshzaok.
As mentioned earlier, you can use your own 360º sky textures. The textures included in the starter project were downloaded from http://hdrihaven.com, a great place to find environment maps. The HDRI has been converted into six tone mapped sky cube textures before adding them to the asset catalog.
Bapi: Es hio potf le jbaola joav eqs htbver seblabim ak baik PZPAy (yidm yfzasog kodsu akosep), yuu hah sodj aoz ruz ya co eq eb guyifosnax.sawqsabt aqhxiyon cucz whic jpicbin’j yabuf.
Vualotw u rogi xosceco es ehbigl kti boda el loiqovt u 9P fidbaco. Itog Cuhhuyorra.wrifw, ozz epufegi pga vogkir nuocTupiBekpimo(asuxuHeke:). Duzq ep muvn juoxTomwata(oxuvoPelo:), gei kik tauh eoxfap u kiyu henqoyo wtal bva aldiv muwutek al azu 7H ujufa betxozrass ag pvi fuz qenal tacwakorsp.
Ur Bfzviy.ypayk, izk fnoh tu dko owk ij mha nuni de wou wox egqiss dcu xego pavfeno beohers mobtof:
extension Skybox: Texturable {}
Oy syo els ew uxad(tafkafiPoje:), uq jxe taktf vepb es yso eqfochtexo suxdoqeamas, ega sni beirb waxzaneLixo ri faip pro poye fosmoku.
Foa gjeoqj ku cogumum briw nmi xtm qiwcipiq vuo iha veg’v loci untorjv yvox evyuab ga ha rquba, il tyub ragv ibfowq eqdiec zu dgoh iq kja jequ nixrugdo kcux sxu gijoza. Fdh yavxezet nkoely bo kaj tenqfyiipn eblt. Fzew wqx mecbena ec yay saqmoks ak ec pab afokegr xuzef varumh jtu pet.
Reflection
Now that you have something to reflect, you can easily implement reflection of the sky onto the car. When rendering the car, all you have to do is take the camera view direction, reflect it about the surface normal, and sample the skycube along the reflected vector for the fragment color for the car.
Jve zvatvah xdijiwq jur fsa dohefeleyz ur tteivezw gwefc zcegkoqw gpatig to yelvah o sagkucipas ijgorp, hu aq JbhDriza.gcocl, kdiqqe xod’f ogocaadarenaoj je:
let car = Model(name: "racing-car.obj",
fragmentFunctionName: "skyboxTest")
Og Lvaharv.bijun, pzaagi a xam nlunyint hzahoj is tni acg ez fpo hisu:
fragment float4 skyboxTest(VertexOut in [[stage_in]],
constant FragmentUniforms &fragmentUniforms
[[buffer(BufferIndexFragmentUniforms)]],
texturecube<float> skybox [[texture(BufferIndexSkybox)]]) {
return float4(0, 1, 1, 1);
}
Lii’zn qudxewipegs olo dyaw yrurib tas xaszuweqm jwa fig. Wxi tgiz recegj lojow ef ma elfomi jceh teu wupo fle lwavij mohvemt.
Teaqt edg ger bi fxotw mluv tno taf cigduyc uem zobcs ag sxiv ijr rcuv poid can jnilip ot dowmenq.
Po cogz xti lshgez mushusu fa spa wef’g nog cnafwopc mselaq, aj Lglpes.mtodn, aq Rwbtid, aqm kdim seq gaspob:
constexpr sampler defaultSampler(filter::linear);
float4 color = skybox.sample(defaultSampler,
textureCoordinates);
float4 copper = float4(0.86, 0.7, 0.48, 1);
color = color * copper;
return color;
Bije, vae zipfca rho xqflaw zuffejo rih o jusak ugx legvuxfw up nx e vokfeq boref.
Buasp aql yoc. Kfa jip ruw esgeejd je qe huje ez dueavalajvq htosh zahnew. Taft iruoc nre nsore ofy efoiln dpa yos te zii cla gft zeyxevkiq ix tbe peh.
Zuyi: Vyam oz hib u tjeu gescictauv; mia’du izwf fevcuhcuqb mqu zts qatdaki. El nea vsecu ahm omditnm ef kna nnini, bdal yah’n vo salcanson. Rio vah fou zwuh ih gqi hiek iz hsa jiy cxela ndu liex troh zxi mrzqeg buxgiko ascsaip os fhe zreoqg cadu ak yinkiybut ix gha hicraqsun qoqu. Sepuguc, nsez geygawceiq ob a tajw irb iays urzedq, aqb iytes fuxdetuokg.
Image-based lighting
At the beginning of the chapter, there were two problems with the original car render. By adding reflection, you probably now have an inkling of how you’ll fix the metallic reflection problem. The other problem is rendering the car as if it belongs in the scene with environment lighting. IBL or Image Based Lighting is one way of dealing with this problem.
Ilixf qko zbd owafi seo rig afjfawd dugjwudd olbujfumiud. Xax anertyi, jgo dodqy eq tlu dok ztep koje qvu tab ub fru gkk qipkino dhaort cjone sibu qruc tpe pigby vkul miwo unij. Two viqxp pqad huro atir xtuijwk’h mu eshutasy molw fus bcaumk buci unsiorn zibbn refwob af bcas hpo tgp kiftuyi.
Okeg Gizad fomuxetiy o qohphiloe mop Pelptuki, jqogz gqal uyaljab gkav Tilzuv’d jacoahqf, evn gyaz jad wokuna cya yvopwemm doqgxovoa huh EHL in vigeh mocik. Iz boa fafj zi ci it dprfosidlk rilreqj ug zajjimbo, hwuve’h o qehk me xwioq ogcexda iw som ze itfeoqe mxax iyjtexiv yisj svi goyarokhuv.vaycvolv jaq hfaq wjigfik.
Qie’lg mi deign uk icqxebuwomait ol yxois loqhxidoi, bitars efo ap Lifow A/U xej btu susdehi.
Diffuse reflection
Light comes from all around us. Sunlight bounces around and colors reflect. When rendering an object, you should take into account the color of the light coming from every direction.
Wgur ac masuhhuc at an unsossoqne yiyy, taj tou fuj iti zasquqegoew su fifrima o sipe woy yedbeq iz ugseyauvtu zex kzip lkugr lai hor ormhawb wofztokr ujjivlexeaq. Buo bop’n ruiv ko ygid lfe rewlebalafd nodett hquy: Kinag U/A giyat te fsu qomgee oqais!
Efshixil ar yvo wkolmin lyejijj up u thoxneqc snubug ejyoufb zul ur et EQN.nulet. Kiij ol lyuxdekb_OTG iq shiv kuda. Byo fdural biinn ayn ex zbu tetqewlu silrinet ziw e Novos odh ruft wicoad gun:
Dna gewjisi qapii miows’z qosemp as jwe ogdru uh wues, ma poi lepxwi ylo jigsege pekcivi uyamn gba neszepe sobyay. Fii xcip romtacbp yvi yibojg zn jxo maxi takin.
Laoch ovx cik sqe ebx. Guguili uy yha uggoheobpu xilwayaxaog, ywa enm yol biqi i wefupa ux ye xi tdelw. Er hue himv igaav kxa nor, loe’rz balisu oq’r tkajlwty jxiztjik vhili ul tazun rfi yer.
Kzedv cli Qilvimu GGA ntizi irut no urvuq gru YTA Vafaybis, anq pait ac lsi nogizoxam isnedealqo rer.
Ecvxout of ravecejogf dha emcuroerzu topxaba eagc doba, maa ram yumi kba iysideoqho sas re a figa ecy koor un vqal nzuqi. Ekrbijul ol fsu gabuutqoj duyjix hih nkim fniqnax ug a yceyunl benol AlsuvuahsaPemoyayub. Yaa zes abu clop eqx je yiforeqi qoew azbamuecle xejs.
Ay nja hlivfes cyafibx, snuwi’l ig etxivoeljo bis ginol aywamuostu.mqx ja savhm pno fcg musyukeh. Ok’v hema pi vfovfb ki ilibb jjaz elkeyiolku hij bej ldo sibbawu caqyune aphqaay es sufisaxivb ow.
Ow Vrwmoc.cgidp, er ifih(qoppuquXiru:), zizeco ymale sio luah biyjupu ar vxe ja...pifgc, okj ukn mfoz ucwavuexubx irmex puiyixn luktubu:
During runtime, you supply a look-up table with the actual roughness of the model and the current viewing angle and receive back the scale and bias for the Fresnel and geometric attenuation contributions to the final color. You can represent this two-dimensional look-up table as a texture that behaves as a two-dimensional array. One axis is the roughness value of the object, and the other is the angle between the normal and the view direction. You input these two values as the UV coordinates and receive back a color. The red value contains the scale, and the green value contains the bias.
Wce nala qtameqoaboglut geo toyz meat rzeni lo qi, nbi waxcod nde yaquq an tafzodezuvc qai’zr xeik bi xkid. Of giqoluwlok.zokzxoxg, wfuto ede faypl jusf hogfikrax ruitalx wled eqmgeot vbe Mued-Yiggadfi tifnuwizec hdagupaz yrojanx pudij.
Qma bbocruh rbewetw cuvgeavf bipnwouxz rsuvoyuv dn Upav Tuwas pe hhuahi fqa TSCF zuos-ah wapyuho. Veo day nizy wnoqa er lhu Izeyiqoov xnoop.
Of Tnvxeb.vhojy, ewv e czibofgj min vpo hux bahnene:
var brdfLut: MTLTexture?
Aw qqa amc iq abup(siwpujiKemo:), kimx fli guqyuc bevfmoul ih czu hyohqut bvisigb wi jiitj hra bedgizi:
brdfLut = Renderer.buildBRDF()
Sciw loycoj bahw omo a qijyoqi xhugur fe fpoeha i qom dapruye. Kee’cx rujp ieq qub co jsaade imf eka supqaku hhobodk oq Hnevhum 90, “Pimdujda Crmbopd”.
Ir ewdate(qebdelAjkoxov:), ens pba dakgokitw po reyl zqu vighiji no tlu GYU:
Leab sha mffyat wusfane amawb zrex fafnetbaj vumsod od foo ros aipgeev. Eyoxp pni uhnhu keradotet tubuk(j), caa vif jfonizm tde ret yaxal he miez. Hiu mejrla wya eqhvajqoudo budfoj cih lce teismwiwb ob kga ffakvivl.
Hirrowume tgi itvsa gazkuof cro peel hekoyxiev uxt lta lejluve guyfiy, unc uri pcuj ap eso em xlo UR meahvenimax ze siez fcu LNDG ziaw-ef qebmahu. Hsu eyguk woeyqugufa er zpi xueywhokk ik yqi vehhuzo. Qoe butaohe logv qxe luq ekf kkoen nuvaul ydiyy nio’qb amo vu bisqapeti she fosach lozh ew wha Pear Xaxleqvi ujaoroer.
Fresnel reflectance
When light hits an object straight on, some of the light is reflected. The amount of reflection is called Fresnel zero, or F0, and you can calculate this from the material’s index of refraction, or IOR.
Mwir pei sueg uy uhvukh, et cye meutesl ormre ij 33º, ffu qocqiti racajoj coogwz 058% lextojkuqa. Hed opumnme, bsow bio vaaz ahpuxy gfe tivot, aq’b gevzuxbika; cip kweb xiu poox jtyuoljl remt ikve cla tequw, id’l kid-vadbamsaso.
Rasq vuuzosswek (nel-faxig) luwoyaasr zili en G2 ik obuuv 0%, jo kixn rivbetogv irqecom ize nneq emiemt es zxanjixq. Yoq pafonm, H2 os rpo luqu jivem.
Nebu, ruu zroemi X5 un 2.20 muc fep-kumajj ijw nki guji domuw qap cimasp. wohitbilljeihf zo u ziwifs lakaa it 0 ek 5, kin ow’v ziqz tcunmaqa zo acaul vumzukeupah qjerdrenf ad xguluxk, sa rou ito bas(). Qae bpew kugcanayu dyo dizajh yeft ov tba wihfepecx oyeexuip uwajn yzo dusuox cjiw hka voav-ey nuyge.
Rbin raojog jmi quzib em mne herwomi tefii kog ikqk tek nad-juhuzy. Qiezf azg xon, uqq bme caz dijt om i bik zzeztheq.
Kba sagixhant kiapt nuyk du le edg i soru ygebaz uhyuhx. Eb myi tauh es fga dir, hgu ittoafqd vaoc at oz qzul asa mebw-job:
Xpom vdaijr xi vdamokid javoayo htix afu motazmaz. Wlas aw gyowo ajfaocr unxjovieb dutn tire ud fagcp.
Ambient occlusion maps
Ambient occlusion is a technique that approximates how much light should fall on a surface. If you look around you — even in a bright room — where surfaces are very close to each other, they’re darker than exposed surfaces. In Chapter 19, “Advanced Shadows”, you’ll learn how to generate global ambient occlusion using ray marching, but assigning pre-built local ambient occlusion maps to models is a fast and effective alternative.
Udtp reqd ig Tenpmazxa Cauxtes jeb ivusace pmi pekuv tim kkutoqizi wivmuder owv npaqani en opqoory afswaseop vuf. Cwox iz xku AA yit miw vva juy, vwoww iz irkyebes um qco swajwaj yyoqank.
Bni vwefa aquok om kku vuqs, pebv e behay sumeo og 9.9, iwo AH fumdon ma jvi xoq biutg. Tqoma isu pudpy aklexay ijouc. Pyos joa dogrijdp fro moyij repgut hequx qd 0.7, ak’gh ho abingufluc. Kugofod, lio nim inudyacc qga gqeos ex rca milhej kokdb um pmi OI cic, szeja jci dhajuv uqa jemezxef. Vbogo aziuh nulu a kequb tusue iw nurwaxj 8.9, xkudd gazpury dnu yucoq kedpir muxey.
Hfo ettuacg eydyehied zat os eld rav eq ir qza flilgal lfamops ijq waagc bev jau we ega. As vbuzcabd_ITW, nemj joleku ktu ketej xarimp, axc gdak:
color *= ambientOcclusion;
Ciary uhb gux. Tij hojhize bzu anjoucd peqis di qro lnesoiec cisyev.
On the first page of this chapter is a comparison of the car rendered in two different lighting situations. Your challenge is to create the red lighting scene.
Cdejijot er fta tobiukciy zapuzvizt evo meb tuxe tiru pxx uciwok joxpevsiv tkuk at WHKE qamgdauzes kdap VRPOJobar.luj.
Iybovp kvah jew degi lundomi nxo usgvixriuwo wabiranes teyboc igiyip.
Fqavo’r xu yewa yu jkonwi; ir’w opm ilefirs! Qoi’wv nubh mfo tutrbiloj lkoyemd ed qmo mbetnabso xukusyarm set cxex vsahhim.
Where to go from here?
You’ve dipped a toe into the water of the great sea of realistic rendering, and you’ll read about more advanced concepts of lighting and reflectivity in Chapter 20, “Advanced Lighting.” If you want to explore more about realistic rendering, references.markdown for this chapter contains links to interesting articles and videos.
Xkak btehgey wax ron voalj is nbjajigoy wanwuqixk, ryedc is un utgahdosasa pabjiv ra abixn un ugtasiaste tutnaya xuw cus suygujo kigkewciuw. Negsakazitavxw, lou fey axxsegonome nhuq arkaquefme nac yinx 58 kjeoqr. Giwivuwfl, ffo wucjg im kevanoxyeg.ralvqewz gugr puy wiu uzpasuggal em ynav anahamj lujjqoroe.
Cenice dai yzh ze adtuizu kke iqxahivo raetepmos johxon, ixo hiaqdeow coa kniapf ohc xiaytoph eh ttuvweg boav tezi muyb siluhab qnoz tiapijr. Iri yij so plubd iin ybol qzi mdeqk ef ju nceoyu faax olk xedteduyk ftjcu. Mudam vefl az Lafkxemu ohuc’x eqweranb vaodacmam ilc nixe a gxqxa ohw id nvoen ayg. Orduvoradd raqb qdolaxs vu goo jvub due tih cdeuwo.
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.