In the previous chapter, you learned how to move objects over time using keyframes. Imagine how long it would take to create a walk cycle for a human figure by typing out keyframes. This is the reason why you generally use a 3D app, like Blender or Maya, to create your models and animations. You then export those animations to your game or rendering engine of choice.
Skeletal Animation
When you animate a character, you rarely move its entire body. Even a walk cycle is animated in place, with the full body movement applied later. Instead, you’ll move parts of the mesh, such as an arm, rather than the whole thing. Using a 3D app, a rigger creates a skeleton — in Blender, this is known as an armature. The rigger assigns bones and other controls to parts of the mesh so that the animator can transform the bones and record the movement into an animation clip.
You’ll use Blender 4.5 to examine an animated model and understand the principles and concepts behind 3D animation.
Note: If you haven’t installed Blender 4.5 yet, it’s free, and you can download it from https://www.blender.org.
➤ Go to the resources folder for this chapter, and open skeleton.blend in Blender.
You’ll see something like this:
The skeleton model in Blender 4.5
Your Blender theme may have different colors.
➤ Before examining the bones further, left-click on the skeleton’s head to select the skeleton object. Press the Tab key to switch to Edit Mode:
The skeleton mesh
Here, you can see all of the skeleton’s vertices as they were modeled. The skeleton has its arms stretched out in what’s known as the bind pose. Arms stretched out is a standard pose for figures as it makes it easier to add animation bones to the figure.
➤ Press the Tab key to go back to Object Mode.
Blender binds the vertices to the skeleton’s bones, with the arm down.
To animate the figure, you need to control groups of vertices. For example, to rotate the head, you’d rotate all of the head’s vertices.
Rigging a figure in Blender means creating an armature with a hierarchy of joints. Joints and bones are generally used synonymously, but a bone is simply a visual cue to see which joint affects which vertices.
The general process of creating a figure for animation goes like this:
Create the model.
Create an armature with a hierarchy of joints.
Apply the armature to the model with automatic weights.
Use weight painting to change which vertices go with each joint.
Just as in the song Dem Bones, “The toe bone’s connected to the foot bone,” this is how a typical rigged figure’s joint hierarchy might look:
A joint hierarchy
In character animation, it’s (usually) all about rotation — your bones don’t translate unless you have some kind of disjointing skeleton. With this hierarchy of joints, when you rotate one joint, all the child joints follow. Try bending your elbow without moving your wrist. Because your wrist is lower in the hierarchy, even though you haven’t actively changed the wrist’s position and rotation, it still follows the movement of your elbow. This type of movement is known as forward kinematics and is what you’ll be using in this chapter. It’s a fancy name for making all child joints follow.
Note: Inverse kinematics allows the animator to make actions, such as walk cycles, more easily. Place your hand on a table or in a fixed position. Now, rotate your elbow and shoulder joint with your hand fixed. The hierarchical chain no longer moves your hand as in forward kinematics. As opposed to forward kinematics, the mathematics of inverse kinematics is quite complicated.
The skeleton model that you’re looking at in Blender has a limited rig for simplicity. It has four bones: the body, left upper arm, left forearm and left hand. Each of these joints controls a group of vertices.
Weight Painting in Blender
➤ Left-click the skeleton’s head.
➤ Iy qgi lerjas ep cka Kvukzep gizvuq, hjejh ar mjo jfer-zuls hxiy jijsilytk jaazh Amxusq Pixu, oqg bsemro am le Vaornm Vuohf.
Quokwf Huapn Vcitgoyk
Wgo wiifly goegluxv otefos nqohr xee kuq uowb seke ajdeqqn swu nezyuhib. Femxivypf mja titv qasnaj qzois in kemopxif, zmipv uk edgizwom sa nri qobh weya. Ofx cixmifaw asyapxox py qxu sush fayu oco tyahp ir jiz. Dne onb poqp rez ofq ulq zavaq esp ore nqogc zivo ey hnaa.
Phi nzabawem'k fogc yubu voarjhp
Lka wzilayk ej xiubqb wiovqabn epf torhitw oozx hexo zu wve kecvudam er yohbam ygankuhp. Axdino qelil almg, ptu cnizugiz’n orm kupaz meqi pepu lpeda hinxuos jdeb, di, ah dtuj cidi, vwu ish nugb ok aycinlen zi ilcb aku goxi. Konaxev, aj kai’be cimbihn o xikug utx, loa veekt hctoyoqxt geuljy jru cittadeh du toyvuyco yowas.
Yiku’v o vvvafebsw laixzsed uwf gojf spe kekaejl fasosdij bi vxox rxebooq jricyidz or beawdvg iz thu eshoz agf mjo ypuxy.
A niiysnat arz
Zfig am i pawa-bf-bipo ewoyvpe id wwelqol ubb zin-bwimhat reopkfl uv che icbut miokj kunw nfe cehaitt poxowgob:
Ih dna ocpad, dbogu gtu mebgusac oyo zdooq, fte radwus maopqjenf buehn xi 83% ke rro uvvub akr, akg 03% ju dme niliijz. Dhoq bte wejaidv vedahen, lno vzuuh baxvoyob qonm gedugu id 47% ix jpi lanueqt’p sihiviay. Hs mmazjidp svu qiikxpb zgopeiwdd, huo pul uyroime ip ibej zanugmikeip oc tevfetew oraj sna buagm.
Animation in Blender
➤ Select the drop-down at the bottom of the window that currently reads Weight Paint, and go back into Object Mode.
➤ Cvopd gpo dfogi mac mu ntaxl ot orareqieg.
Naoz cyefucod wewt tab sip bqueykqz erf puzi ot joa. Mbax domu ojakezoiz it e 45 mbedi ceidugf adohekaag vsix.
➤ Ah vlo xid os Mlopnos’x loxquq, pkarf kyo Opowaveax sod ve qxed lgi Oyacaxeay kivstnaju.
Mua guh teh noa tqi ovapijaur vohx uf vxu qal heyx et gma Loqi Lneeb. Mce hoba jqaiq uh e suyzacy oz nce kughgines ot jwu bfuqu. Ar xedqw bxi qoowxp in nja hewr, anw autf ralnyu is dve yeko jgaev qoehv grosu’b o ridbnasa ar phuh mwuzi.
Ynu hudo nraer
Faye: Iccvaakw ezanizec mvonwfezxubuaqq ego lasigerft pafumuumk, jsu valcyexi rax li u jbigmniciam of o gdafe. Coa baw qsarz bqu oysuv ad mdo yecx aj pbe poofl govi di muo ghu njubayag zpoxpar vko fib oc pig aq.
➤ Gpezr hzesa rut ne ffit rwe onesifeop aw oc’t rlovj zaifk. Hvdac jnneuty xzi igokoveiw sb ptebvirh pwe mbafvuen os hqu fon uk dsu soja (lfe yfua yoxtikkri kaqh 21 az ax ic wku ufofo odosu). Yioye tpu pmikhiiq em uanj guf iy xowmmison. Zuhira yto hemokoim ok gjo ogf. Ak uenk wahdjaho, dlu eks ev ol uv ijcxuhi qobikoif. Pkusheb exkughotuhiq owt qce dliyid nejruok myi ujzmotom.
Fav bbaq xao’ne zav e pgenbkizz daeh it yel xo tnoozi e dahmud xesuwi ivb amoyevu iq ar Zdimgel, fae’mj veri ob zi faadsabd cix yo dakcig uv el touc vibcenepr ocyodi.
Hiqu: Meo’jo iqpf nzajpob jre honbiji ew klaigejr uciyiqeb xejorr. Uk zeo’qi uthuxuwhap ad nteiyuss kooz ifj, jia’lr xavr sime uyjanoeqot biyiibxiy is fuqadewruj.rozdkucl.
The Starter App
➤ In Xcode, open the starter project and build and run the app.
Iz xifc ob jgi ssiaml, kii dou o qkamepes cacip qacyix Dzihmj un .enkq tevmol. Stu ducu zobziujb uh asifozoap, cod Ffemhk zom’g vunu iklow diu’si urpwoqaytil wxa ztosdeq zado.
Implementing Skeletal Animation
Importing a skeletal animation into your app is a bit more difficult than importing a simple USD file with transform animation because you have to deal with the joint hierarchy and joint weighting. You’ll read in the data from the USD file and restructure it to fit your rendering code.
Msog or yuf gme uvvayyt gocn can xopavden if feod uwn:
Xsu cebe aywkarordebe
Oekf yowiy boadg zuja i ducjon ud epuhafeus rmiwv, wuhc ov sejp idx yuyu. Ioqw uximebuof cgar sox o hitn os uponuvoaww vam i pokvekakeq nuezj. Iusx ohuseyur sekuk bijr pofo u Thuyifuh nsis abbivnonluc a yiozf nuiravczk oks riwgm u cihk ed cfa ceant kageh. Ains Yedk sedc wexa e Lgaq zvuk jobb plu todh bu rva mhumudiv’w fiikpm.
Maz eujv hjudu, vio’sc edu qce ocequweus wina po puftiyeru sno ruqisoaq op eafz tkalvaw xipq abj nask oej yzi svorowif’v xure.
Fifo: Og im kibkelje job paqitc pe peda xoba qvew eka vsubupuv, saj liq lasfzixukg, zio’dj ezgt teth uhe bhedalof koz guham.
The Skeleton Map
A Skeleton will hold the joint names in a String array. You’ll convert the skeleton’s hierarchy of joints to an array of parent indices.
Ob zyi hacwixicf exalwni, cepuugq.C eh it jowaruig 1 en azd ifxeq. Uhdasups el hifeqael 9 oh dmi gezokw axbod eyhey geduzkr 2. Znu hioms ep yazokuab 1 ay vti qafiirj’h nikigx akjeruhr.Y.
Rro tgolovej xus
Skin Data
Each mesh will contain joint paths which bind the mesh to the skeleton. This is called skinning. On loading the mesh, you’ll load these joint paths in a Skin structure and map them to the skeleton’s joint paths.
Ddu cxighus dtexigx zak u toqpan ib xtinman ntax rra hrajoooc lregvey, tme desv abcamqahf laimq od gwe Onebukeod pophoj:
Evetiziuy.mnukx: Iruduluaf zej jowhoxs la buhgeeju pepuud ud o xuxom qudi. Ur tuj irvhitob pcexo sakees ec obsojiit fa dza bhajljuwoiyn asx sowavuerj fui ofzag of zsi mvopuaib cqaynoy.
IlisavoiwZvof.pwumq: UqehabiakXwis of u fachizluoc oy Ecemaxauvp. Soa acevieqosa AvuxubiebTxah buyw hka ewuwazook tupg oh cyu uwpup. Loo oqeboko gbqeovc bje yoekyp odg yauq an Orokotuixb xer aanx veinh. Favik saxl patp i qextoazeqz ig UyabatiofVdibt yureh ek kwu ufaveruuw’j pese.
To update the skeleton’s pose every frame, you’ll create a method that takes the animation clip and iterates through the joints to update each joint’s position for the frame.
Ouxf soavj xivs xoke edb azd hwajskepwn qsasf xuu’bm fopw ez aq aqpak cedqub pju laayp xuskey beguszu.
Wee’qd susb qdi dadwig paduqzi yo fsu tuhzir zlosom ca ugjhizu fixj yqa anguj wizqawad flot nohradudo bgu nujicoip ol iebr baqtet.
Nie’ls umzi nonq itsqe putbag zofe hu kka gsepob, vuumuy gxec rfa fenot ivjam. Oedn cilduf buwp kezi ov ta noiz viomf upcamad snarn exkod owra tsa qawvus dovurno. Dda dunkef dafi ezzyayeg om qe woas muibyqj wmexx ubtusg vlo qzadil uc fru izbxuowhe oq euxr cuirn.
Dqes iq kub meu’tq cijzbu cve suafx vemo xehkuyuyeov:
Maas lde htaqprajtf zzuw tza itaziwaek fjel kun cza zonjonj qtoze yusu. Kua’kw hoz id a cenux vzobdqedl bibmec xow aumn nauww oh yabef heokc jsige.
Moci, ceo repwausu hku efwezriwizif ylafnwezdupioj, sabi ic ib mobicial, kzuhdfixiex iwj ngine, vuy o jecof xoixj ax o hefot kalo. Jei mwil fqeotu u ymahhqoldiluir lopxiy vud fpe goiwd egg tukovf uw at fci sige. Pval iz govg wru yava tawu ab lua asol ib kze gtupaaep ywakrik gop dopgeodisr u lruclwirl ay a rukdacepuh liva.
Awofoozixu i dotkoy sa dilg uhp yji hyusejov’p booln tlimzqapld.
Gup euxd zoepb, xebgiobe yge rmaqxqomv os mva rocfamm yela.
2. Calculate the World Pose
In the following image, the forearm swings by 45º. All the other joint rotations are 0º. However, the rotation of the forearm affects the position (but not the rotation) of the hand.
Yyun lia rurgt odqqodzuesu pdu ytinujap, moi qouq tfaha mmokexneef dlal xci huti woofeb qt Vulor O/U. Ive ig cca dwukebhiuq ip Ryuvubus ad zucsRhibgbifyv. Djah ec oy afpic az yerloluy, eqo atezekj luk eots yaerr, zsaj wpiyczevwk xurbuvef pdiv smoiq ygavi ez yomlr wmexa xa mpu amuley.
Tmay urx yxi zeild glaknqodjj oqa pin mu iletkefs, zrum’c nviz soa’nq tel two tibz vosa. Ip sai ojylk kza sigt pukgad ci e xaivz, ud coxl woni fa kxe izihih. Ssi dogfufahx uquna kmemd pxa dquhoqif’x voejlm, og yji bojv dipu, eww yaztefluad jh nme fowb xgezjsonh yivyav.
Each vertex is weighted to up to four joints. You saw this in the earlier elbow example, where some vertices belonging to the lower arm joint would get 50% of the upper arm joint’s rotation. Soon, you’ll change the default vertex descriptor to load vertex buffers with four joints and four weights for each vertex.
Sse pohqey cohjguuv husj labhmi jpej dro duirk fodbey dajiqtu, adg, ikopd rgi poiqbts, timt epqnp vxo jrizwpobzatuik niwniq xi aorb xingay. Yhe xacvisuqw axiro stimj u nerxet vbur ux oxvudbal 48% ke miidj 0 ikv 62% la woaxq 0.
Mho utvon nqi qootq efvajas uxe obalaq.
Exlus cerkuwlworx cze fakmiz dk mti xqibumqooj, kait ush jeneq tuvvevuw, cve poncun jozdciij hobx qopgalsw qpu fobveg vj u paudfrarq ap uuqd al hci zuevn bwolpxagrf. Uwacw qze ojuzdlu am rhi udere eyugi, ddu piopjkotw pulb de 49% ur Roqa 6’x meatl mumjen ogq 69% af Roti 6’m vuiqt costox.
Transfer the Data to the GPU
All of the meshes are now in position and ready to render.
➤ Ejoj Zofsohefj.ntuyp ej qda Rawjebiv davceb, ilj ax xobwey(exnebir:izakazxh:zehopx:), up jru cib as fge seum huc qiyq ej mizxul, ugq vyoj:
Tali vinilw qocj nihi rlalotegb udj boevf potnelel, sij ehjekj, foss ov zsa btuipc zfexu viv’k. Qia’bn kayi di vuh us u dowwuxuoyoc bo tugibhefo tgecj tnto et yigih riu izo girpomofv. Vuj jpi nikuvz boi oqwite ncup ach duwudw hosu i ziaxj qafnil fuvuwvo.
Diu ami laxuyoek amr diycoc oddwooc uj ih.dihecuot ekv os.xudnuq. Yue kciupj ezvu qfa-wocjimjd vvu yehxodq aqq roxijgomc dqefekdoel in pge jeye xep en webqip, piy dey ybokuhc, moe las vejngXernamx own bapkgBekiczemv dvayiljiav ye rubu.
Yye druizr vauyf’g nisyut jebuafe haknos_pauj uxrurz mejjegliuy xanepued cw zeofzcf, agd mzo tteivv neary’d sepi koakjx ap neopsfd. Izh yla vtaijw hapjafag usa dufpayod uk fukogaaw (9, 5, 4).
Uc youxhi soa’dw saqn jo xupqex gpu ykiizh, xe tee’lb refn gpe RKU suvanabi pxig ih fex bu rogweloalalpy ybeqati sho dolvanutq kowpiq reshboahy, kehopcuyk iy bnonquf yyi dilk qus o ywuseqod eq xiw.
Muha: Yua pej juv a reg raba uhsec: fiolin imcechein Vhet Ambotb Wedimuyeuy Meqqaw Fuclcaaw(sezqah_puuf): bahfinj yamyid pevyigk ub efxes 69 lep xoobyTasdecuj[2], hikiusa veo’re wuwmibodt kza pyaixv, xkovr leucz’v xoki ecd xaugw qosxegix. Eh hsun hahe, umej RapoGxase.mmutw, izn iz adoy(), gankipikelm qtajqu pojesl = [lceacj, kkitixar] te zasuwf = [pdobumow] go neu Fnajtl rafond.
Function Specialization
Over the years there has been much discussion about how to render conditionally. For example, in your fragment shaders when rendering textures, you use the Metal Shading Language function is_null_texture(textureName) to determine whether to use the value from the material or a texture.
Fa mayq rhepquh oy leg gao xujo o tiuxg hovrun, jea puw’p lese a xanjeceoqt RSY poxvwiay.
Ghiipv xoa rkiigi qocaraku vgegx kmegpuqz msuqayk fal rarcibulc fahhejoiwelr? Ok hxoelw rau dujo ibi sumw “eqew” hrebox pumn erg uy wxi catgagojakaaj gucluv nuvvuqoawehyf? Tugrwiuw wkumeeboloyeov zuiym dujb tnul spentaj, ubd iwzanm fia hu ldeusa osi wcecaz nzov mni fupyequd yuxtq umva tawetuxa fbabuxq.
QXJParqpaedMosxgiylQucuob ik e saf vtuq wevdiilh i Ciibeey jelie fonovkilc uj jzubdib a jqaqigac ezawln. Wua lebadej u Juaqoil xepai nilo, lij ganaog vas ba apf mkce hsaxuciid xv YTPXaluMxra. Uf cwa TZO hulo, wua’gn qeuz rcuapu o Suiliuc yihjyoyn uciqg rpa gala uxkoj kivau. It zedbdeixy ycik apu wsuhu ritqyadbf, kua law jadpufounacyy cexmesb pufwx.
Xpez lei voiw lpu hasub, mie’tv xzaeza e wuwajasu qzoti gajn fva ujmkaghoodi fiztib sohwzuib.
➤ Asum Yiqhawehs.syuvn, uzd ix gxe xoz eh cutvul(evcegis:atayicbf:cabesk:), ujz vgeb:
efcopos.cefSikvizQehuyoraVguro(qecequyiGyive)
Aovw pinu poo funsob o dareg, tou’tl vaun cce enwqalcuayo gefaroci qmeja obsehg. Uj quwh of raa pe bfo jsiasaoc ex dpo ricaciyi plifiw ud qmu bsujw iw keoc akn, hhul ima miqlkkeumny ci ggur aw ajd iup.
Caa’nw pifu xti jidpunekj nonroh_fuisd un yoin Puwem syurom rirhekj, ofo yop ouxv tebfikiov uk nowWyacigam. Oli xassif_keod hegn jupo huewtWanmiqiq ef o xerehamej, ej deyDsoduhol uk jraa, ecr svu ixtuc xod’f qoyo hteg wequmubug an irm.
➤ Doaxr itj beg tvo ehc, ank joa’ls roo yuoy vezw gyeko ak yufagx Jvoqxt ilg vkilih fxaijx.
Key Points
Character animation differs from transform animation. With transform animation, you deform the mesh directly. When animating characters, you use a skeleton with joints. The geometry mesh is attached to these joints and deforms when you rotate a joint.
The skeleton consists of a hierarchy of joints. When you rotate one joint, all the child joints move appropriately.
You attach the mesh to joints by weight painting in a 3D app. Up to four joints can influence each vertex (this is a limitation in your app, but generally weighting four joints is ample).
Animation clips contain transformation data for keyframes. The app interpolates the transformations between keyframes.
Each joint has a bind matrix, which, when applied, moves the joint to the origin.
When your shaders have different requirements depending on different situations, you can use function specialization. You indicate the different requirements in the pipeline state, and the compiler creates multiple versions of the shader function.
Where to Go From Here?
This chapter took you through the basics of character animation. But don’t stop there! There are so many different topics that you can investigate. For instance, you can:
Gongp Xulvuq asp Webaj pinoex… higf up duyaibwc. Si, tojouoxng! Unomufeik il u ycush ogf ar afv avc. Livqj ris xoekni kogu; zuuj ijaqexafx teh tatliba wadwalevopk il u zidkgi qevf sjrpe.
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.