[{"data":1,"prerenderedAt":3455},["ShallowReactive",2],{"post-/articles/becoming-a-better-3d-modeler-part-01":3,"articles-recent":374},{"id":4,"title":5,"body":6,"date":363,"description":364,"extension":365,"image":366,"meta":367,"navigation":368,"path":369,"seo":370,"stem":371,"tags":372,"__hash__":373},"articles/Articles/Becoming a better 3d modeler - Part 01.md","Becoming a Better 3D Modeler - Part 01",{"type":7,"value":8,"toc":340},"minimark",[9,14,18,21,24,28,31,34,39,60,64,67,94,98,101,121,125,131,154,158,161,188,192,207,211,214,217,221,228,231,234,240,243,248,252,258,261,264,267,273,276,282,286,292,295,298,302,305,311,315,319,322,326,329],[10,11,13],"h2",{"id":12},"introduction","Introduction",[15,16,17],"p",{},"I'm a pretty mediocre 3D modeler. I understand the basics and make some decent-looking scenes, but the majority of the heavy lifting is done through lighting and texturing, while the models remain very basic.",[15,19,20],{},"I find that I struggle with visualizing proper form/proportions and rely too much on orthographic reference. I always shy away from more organic or complex shapes.",[15,22,23],{},"So I set up a little challenge to myself. 12 weeks, 12 models. Here's how I break down the process. I’ve stayed faithful to this and make sure I give myself 30-60 minutes a day before work for this.",[10,25,27],{"id":26},"the-gameplan","The Gameplan",[15,29,30],{},"How do you get better at making models? By modeling of course! ",[15,32,33],{},"The only caveat is that the models need to follow a structure and have some ground rules. Creating random models without any clear goals isn't helpful.",[35,36,38],"h3",{"id":37},"mondayreference-topology-planning-no-software","Monday: Reference & Topology Planning (No software)",[40,41,42,46,54],"ul",{},[43,44,45],"li",{},"Gather 3–5 references, pick one primary and pin the rest for detail later",[43,47,48,49,53],{},"Draw a rough ",[50,51,52],"strong",{},"topology map."," Where do the major loops need to run? Where are the poles going to live?",[43,55,56,59],{},[50,57,58],{},"Goal:"," Walk into Tuesday knowing exactly what you're building and why",[35,61,63],{"id":62},"tuesdayprimary-blockout-big-forms-only","Tuesday: Primary Blockout (Big forms only)",[15,65,66],{},"Proportions and masses. Nothing else.",[40,68,69,76,83,86,89],{},[43,70,71,72,75],{},"Block the entire form in ",[50,73,74],{},"primitive shapes only."," Boxes, cylinders, spheres etc",[43,77,78,79,82],{},"Work ",[50,80,81],{},"flat shaded, no wireframe,"," so you're reading silhouette and mass, not topology",[43,84,85],{},"Step back every 15 minutes and check proportions against your reference at a matching camera angle",[43,87,88],{},"Do not add a single edge loop that isn't structural mass",[43,90,91,93],{},[50,92,58],{}," Correct proportions and major form relationships locked in. Ugly is fine.",[35,95,97],{"id":96},"wednesdaytopology-pass","Wednesday: Topology Pass",[15,99,100],{}," Turn the blockout into real geometry with intention.",[40,102,103,106,113,116],{},[43,104,105],{},"Retopo or rebuild from your blockout with your Monday plan as the guide",[43,107,108,109,112],{},"Focus on ",[50,110,111],{},"loop flow serving the form",". Think about how the surface wants to deform or read",[43,114,115],{},"Resolve your poles and star points deliberately, not accidentally",[43,117,118,120],{},[50,119,58],{}," Clean, intentional topology that you could defend every edge of.",[35,122,124],{"id":123},"thursdayform-refinement-surface-detail","Thursday: Form Refinement & Surface Detail",[15,126,127],{},[128,129,130],"em",{},"Push the form, add the first layer of surface interest.",[40,132,133,136,139,142,149],{},[43,134,135],{},"Subdivision or sculpt pass — let the topology breathe and check it holds up",[43,137,138],{},"Add primary surface detail only: plank edges on wood, major mortar lines on brick, main wrinkles on leather",[43,140,141],{},"No texturing, no tiny detail, if you can't see it at arm's length from the screen, it doesn't exist today",[43,143,144,145,148],{},"Spend the last 10 minutes doing a ",[50,146,147],{},"topology audit",". Find your problem areas, fix the worst one",[43,150,151,153],{},[50,152,58],{}," A model that reads correctly at mid-distance",[35,155,157],{"id":156},"fridaypolish-critique-notes","Friday: Polish, Critique & Notes",[15,159,160],{},"Final surface detail pass. Secondary and tertiary forms only.",[40,162,163,166,183],{},[43,164,165],{},"Does the topology serve the silhouette?",[43,167,168,171,172],{},[50,169,170],{},"Written critique",":\n",[40,173,174,177,180],{},[43,175,176],{},"What did your eye get wrong on Tuesday vs the reference?",[43,178,179],{},"Where did your topology fight you instead of help you?",[43,181,182],{},"What's the one thing to carry into next week?",[43,184,185,187],{},[50,186,58],{}," Finished piece + one concrete lesson extracted in writing",[35,189,191],{"id":190},"the-rules","The Rules",[193,194,195,201,204],"ol",{},[43,196,197,198],{},"Only one perspective image is allowed in the viewport and ",[50,199,200],{},"NO ORTHOGRAPHICS",[43,202,203],{},"Form and proportions come first",[43,205,206],{},"Quad only and subdivision friendly topology",[10,208,210],{"id":209},"phase-01-hard-surface-props","Phase 01 - Hard Surface Props",[15,212,213],{},"This is typically reserved for things like robots and mechanical pieces but for my definition I meant things like woods/ceramics.",[15,215,216],{},"I wanted to get out of my comfort zone and pick more stylized or cartoony concept art.",[35,218,220],{"id":219},"chair","Chair",[15,222,223],{},[224,225],"img",{"alt":226,"src":227},"01_Chair","/articles/modeling_challenge_01/01_Chair.png",[15,229,230],{},"A chair that would fit with a Halloween-themed cartoon special. No straight lines, everything is \"bendy\".",[15,232,233],{},"A first for me in Blender was using a lattice to take the initial chair shape and alter the silhouette globally.",[15,235,236],{},[224,237],{"alt":238,"src":239},"lattice","/articles/modeling_challenge_01/lattice.png",[15,241,242],{},"I'm quite proud at how I was able to convey that the chair is made of wood without any texture work.",[15,244,245],{},[224,246],{"alt":219,"src":247},"/articles/modeling_challenge_01/chair.png",[35,249,251],{"id":250},"vase","Vase",[15,253,254],{},[224,255],{"alt":256,"src":257},"02_Vase","/articles/modeling_challenge_01/02_Vase.png",[15,259,260],{},"This was probably the most difficult for me. I've never really worked on a prop this stylized before, and some of the flowing shapes in the handle took a lot of trial and error. ",[15,262,263],{},"Many places on this model go from hard edge to soft, so the topology was tricky to map out. ",[15,265,266],{},"Two unique techniques I tried for this were sculpting and retopology. The handle went through an initial sculpt pass to get the overlapping shapes that almost fold on top of each other. ",[15,268,269],{},[224,270],{"alt":271,"src":272},"handle","/articles/modeling_challenge_01/handle.png",[15,274,275],{},"One benefit of this design was that quite a few elements could be repeated. I used a circular array to accomplish this.",[15,277,278],{},[224,279],{"alt":280,"src":281},"radial","/articles/modeling_challenge_01/radial.png",[35,283,285],{"id":284},"crate-and-lamp","Crate and Lamp",[15,287,288],{},[224,289],{"alt":290,"src":291},"03_Crate","/articles/modeling_challenge_01/03_Crate.png",[15,293,294],{},"This model was the most fun for me as I think it leans the most into my natural sensibilities, but the goal of this week was to work with the scale of multiple objects in a single scene.",[15,296,297],{},"The holes in the crate were made through a simple boolean shape cutout. This example was about as simple as it comes but the boolean -> SubD workflow can be very powerful.",[299,300],"video-player",{"url":301},"https://www.youtube.com/watch?v=wbzhBKMB_kI",[15,303,304],{},"I also applied sculpting to the melting candle mesh. Building up a toolset as this challenge continues.",[15,306,307],{},[224,308],{"alt":309,"src":310},"candle","/articles/modeling_challenge_01/candle.png",[10,312,314],{"id":313},"closing","Closing",[35,316,318],{"id":317},"what-could-have-been-better","What could have been better",[15,320,321],{},"There are PLENTY of examples of the models not matching the reference. The vase is probably the weakest of the group in this regard. ",[35,323,325],{"id":324},"whats-next","What's Next",[15,327,328],{},"Next are more organic props. This will push me even further out of my comfort zone, but I think it is the phase I will grow the most! Here are the projects:",[193,330,331,334,337],{},[43,332,333],{},"Mushroom Cluster",[43,335,336],{},"Leather Bag",[43,338,339],{},"Gnarled Root",{"title":341,"searchDepth":342,"depth":342,"links":343},"",2,[344,345,354,359],{"id":12,"depth":342,"text":13},{"id":26,"depth":342,"text":27,"children":346},[347,349,350,351,352,353],{"id":37,"depth":348,"text":38},3,{"id":62,"depth":348,"text":63},{"id":96,"depth":348,"text":97},{"id":123,"depth":348,"text":124},{"id":156,"depth":348,"text":157},{"id":190,"depth":348,"text":191},{"id":209,"depth":342,"text":210,"children":355},[356,357,358],{"id":219,"depth":348,"text":220},{"id":250,"depth":348,"text":251},{"id":284,"depth":348,"text":285},{"id":313,"depth":342,"text":314,"children":360},[361,362],{"id":317,"depth":348,"text":318},{"id":324,"depth":348,"text":325},"2026-04-14T00:00:00.000Z","Follow along as I build a structured 3D course to become better at SubD Modeling","md","/articles/modeling_challenge_01/BetterModeler_Thumbnail.png",{},{"description":364,"title":5},"/articles/becoming-a-better-3d-modeler-part-01",{"title":5,"description":364},"Articles/Becoming a better 3d modeler - Part 01",null,"aO0Wv7jHcyW5m3arS8oXAreBIzu7ZaWCcOVwQOXpUqw",[375,611,1115,3070],{"id":4,"title":5,"body":376,"date":363,"description":364,"extension":365,"image":366,"meta":608,"navigation":609,"path":369,"seo":610,"stem":371,"tags":372,"__hash__":373},{"type":7,"value":377,"toc":588},[378,380,382,384,386,388,390,392,394,406,408,410,428,430,432,446,448,452,468,470,472,492,494,504,506,508,510,512,516,518,520,524,526,530,532,536,538,540,542,546,548,552,554,558,560,562,564,566,570,572,574,576,578,580],[10,379,13],{"id":12},[15,381,17],{},[15,383,20],{},[15,385,23],{},[10,387,27],{"id":26},[15,389,30],{},[15,391,33],{},[35,393,38],{"id":37},[40,395,396,398,402],{},[43,397,45],{},[43,399,48,400,53],{},[50,401,52],{},[43,403,404,59],{},[50,405,58],{},[35,407,63],{"id":62},[15,409,66],{},[40,411,412,416,420,422,424],{},[43,413,71,414,75],{},[50,415,74],{},[43,417,78,418,82],{},[50,419,81],{},[43,421,85],{},[43,423,88],{},[43,425,426,93],{},[50,427,58],{},[35,429,97],{"id":96},[15,431,100],{},[40,433,434,436,440,442],{},[43,435,105],{},[43,437,108,438,112],{},[50,439,111],{},[43,441,115],{},[43,443,444,120],{},[50,445,58],{},[35,447,124],{"id":123},[15,449,450],{},[128,451,130],{},[40,453,454,456,458,460,464],{},[43,455,135],{},[43,457,138],{},[43,459,141],{},[43,461,144,462,148],{},[50,463,147],{},[43,465,466,153],{},[50,467,58],{},[35,469,157],{"id":156},[15,471,160],{},[40,473,474,476,488],{},[43,475,165],{},[43,477,478,171,480],{},[50,479,170],{},[40,481,482,484,486],{},[43,483,176],{},[43,485,179],{},[43,487,182],{},[43,489,490,187],{},[50,491,58],{},[35,493,191],{"id":190},[193,495,496,500,502],{},[43,497,197,498],{},[50,499,200],{},[43,501,203],{},[43,503,206],{},[10,505,210],{"id":209},[15,507,213],{},[15,509,216],{},[35,511,220],{"id":219},[15,513,514],{},[224,515],{"alt":226,"src":227},[15,517,230],{},[15,519,233],{},[15,521,522],{},[224,523],{"alt":238,"src":239},[15,525,242],{},[15,527,528],{},[224,529],{"alt":219,"src":247},[35,531,251],{"id":250},[15,533,534],{},[224,535],{"alt":256,"src":257},[15,537,260],{},[15,539,263],{},[15,541,266],{},[15,543,544],{},[224,545],{"alt":271,"src":272},[15,547,275],{},[15,549,550],{},[224,551],{"alt":280,"src":281},[35,553,285],{"id":284},[15,555,556],{},[224,557],{"alt":290,"src":291},[15,559,294],{},[15,561,297],{},[299,563],{"url":301},[15,565,304],{},[15,567,568],{},[224,569],{"alt":309,"src":310},[10,571,314],{"id":313},[35,573,318],{"id":317},[15,575,321],{},[35,577,325],{"id":324},[15,579,328],{},[193,581,582,584,586],{},[43,583,333],{},[43,585,336],{},[43,587,339],{},{"title":341,"searchDepth":342,"depth":342,"links":589},[590,591,599,604],{"id":12,"depth":342,"text":13},{"id":26,"depth":342,"text":27,"children":592},[593,594,595,596,597,598],{"id":37,"depth":348,"text":38},{"id":62,"depth":348,"text":63},{"id":96,"depth":348,"text":97},{"id":123,"depth":348,"text":124},{"id":156,"depth":348,"text":157},{"id":190,"depth":348,"text":191},{"id":209,"depth":342,"text":210,"children":600},[601,602,603],{"id":219,"depth":348,"text":220},{"id":250,"depth":348,"text":251},{"id":284,"depth":348,"text":285},{"id":313,"depth":342,"text":314,"children":605},[606,607],{"id":317,"depth":348,"text":318},{"id":324,"depth":348,"text":325},{},{"description":364,"title":5},{"title":5,"description":364},{"id":612,"title":613,"body":614,"date":1101,"description":1102,"extension":365,"image":1103,"meta":1104,"navigation":1105,"path":1106,"seo":1107,"stem":1110,"tags":1111,"__hash__":1114},"articles/Articles/How%20to%20texture%20like%20Pixar.md","How to texture like Pixar",{"type":7,"value":615,"toc":1081},[616,618,621,624,627,630,633,637,640,643,653,659,663,666,669,672,678,681,684,687,694,700,704,707,710,716,719,723,726,729,735,738,744,747,752,755,758,762,765,771,774,783,789,792,798,801,807,810,816,819,822,828,831,838,841,844,848,851,854,857,860,863,866,870,873,876,879,883,889,895,898,904,907,911,916,919,925,928,931,935,938,944,947,950,953,959,963,966,972,975,979,982,985,988,991,995,1001,1004,1007,1010,1013,1017,1020,1023,1027,1030,1033,1047,1050,1053,1056,1059,1062,1068,1071,1075,1078],[10,617,13],{"id":12},[15,619,620],{},"I love Pixar and all of their movies. My daughter and I have watched Soul probably 10 times this week and we've seen all the classics.",[15,622,623],{},"When I was a professional 3D artist, I always tried to research the tools they used. That’s why I came across this video years ago. I hated it back then and it's been living rent free in my head ever since.",[299,625],{"url":626},"https://www.youtube.com/watch?v=o_I6jxlN-Ck",[15,628,629],{},"This has absolutely nothing to do with Pixar and their techniques. Just pure clickbait that acts as a complete beginners guide to PBR textures.",[15,631,632],{},"Pixar is fairly open with their process and I have amassed quite the collection of resources/techniques that I can share with you.",[10,634,636],{"id":635},"disclaimer","Disclaimer",[15,638,639],{},"I have never worked at Pixar. I can’t with 100% certainty say this is the current workflow of the studio. While I can’t guarantee this, I can say that all of the information shared is based on resources from Pixar employees or behind the scenes videos they have released.",[15,641,642],{},"These techniques are software agnostic and can be applied to any project. ",[15,644,645,646],{},"For instance I used many of them here to create this Old Fishing Hut Scene 100% in ",[647,648,652],"a",{"href":649,"rel":650},"https://www.blender.org/",[651],"nofollow","Blender",[15,654,655],{},[224,656],{"alt":657,"src":658},"fishingHut","/articles/how-to-texture-like-pixar/fishingHut.png",[10,660,662],{"id":661},"modeling","Modeling",[15,664,665],{},"Pixar relies heavily on procedural shading (More on this later). This requires that the models contain a lot of geometry based details to provide information for the shaders to use.",[15,667,668],{},"What do I mean by this? Look at some examples of behind the scenes footage from their films.",[15,670,671],{},"They actually modeled each tile in this Turning Red bathroom set.",[15,673,674],{},[224,675],{"alt":676,"src":677},"turningRed_bathroom","/articles/how-to-texture-like-pixar/turningRed_bathroom.png",[15,679,680],{},"Or check out this behind the scenes look at Luca. Individual cobblestones, cracks, edge details, etc are real pieces of geometry instead of a displacement or bump texture.",[299,682],{"url":683},"https://www.youtube.com/watch?v=RGG0LAxazwg",[15,685,686],{},"Not to say that Pixar is against using bump or displacement maps. Those are also frequently used but many components that build up objects are modeled as separate pieces. ",[15,688,689,690],{},"Gaston Ugarte is a modeling artist at Pixar and a glance at his portfolio includes examples of how detailed their production models are. ",[647,691,692],{"href":692,"rel":693},"https://www.tucumanian.com/general-clean",[651],[15,695,696],{},[224,697],{"alt":698,"src":699},"luca_clay","/articles/how-to-texture-like-pixar/luca_clay.png",[35,701,703],{"id":702},"why-geometry-driven-vs-texture-driven","Why Geometry-Driven vs Texture-Driven?",[15,705,706],{},"Pixar has thousands of objects that populate their films. It just isn't practical to manually UV Unwrap every object and apply custom texture maps for things like bolts, cracks, etc. This means shaders are made to utilize data from the models to look a certain way.",[15,708,709],{},"Down below I have an example of two objects with the same material applied.",[15,711,712],{},[224,713],{"alt":714,"src":715},"geo_details","/articles/how-to-texture-like-pixar/geo_details.png",[15,717,718],{},"While the objects share the exact same material, you can see that the right side has additional details in the model that the procedural shader can use. Elements like scratches on the edges or the rust in the crevices rely on this extra information.",[35,720,722],{"id":721},"gathering-reference-for-pixar-inspired-modeling","Gathering Reference for Pixar Inspired Modeling",[15,724,725],{},"I’ve found that the best reference for Pixar style scenes are miniatures. Pixar tends to use photorealistic materials with stylized proportions and bevels.",[15,727,728],{},"Look at these examples of miniature sets and see how they compare to Pixar scenes.",[15,730,731],{},[224,732],{"alt":733,"src":734},"Miniatures","/articles/how-to-texture-like-pixar/Miniatures.png",[15,736,737],{},"Here are some screenshots from various Pixar films. You can see how similar the style really is.",[15,739,740],{},[224,741],{"alt":742,"src":743},"Pixar_Miniatures","/articles/how-to-texture-like-pixar/Pixar_Miniatures.png",[15,745,746],{},"Materials react to light in a photoreal manner but patterns like wood grains are very large, edges are much softer than real world counterparts and items aren’t aligned perfectly to one another.",[748,749,751],"h4",{"id":750},"why-does-this-matter","Why does this matter?",[15,753,754],{},"The size of the bevels, object alignment, amount of details in the model and scale of patterns such as wood grain all feed into the procedural materials and contribute to the final look of an object.",[15,756,757],{},"Every part of the pipeline contributes to the render and must be accounted for if you are trying to emulate a certain look.",[10,759,761],{"id":760},"using-layered-materials","Using Layered Materials",[15,763,764],{},"Objects in the real world are complex. Its overall look is often made up by more than one material.",[15,766,767],{},[224,768],{"alt":769,"src":770},"material_layers_example_01","/articles/how-to-texture-like-pixar/material_layers_example_01.jpg",[15,772,773],{},"A base metal is covered with a red paint. The red paint is covered with rust, dirt, and dust. As 3D artists we can capture this several ways. Pixar (and many other studios) use a layered shader approach to build up these looks in their materials.",[15,775,776,777,782],{},"Here is an image of a free material from ",[647,778,781],{"href":779,"rel":780},"https://cc0-textures.com/t/cc0t-diamond-plate-006-c",[651],"CC0 Textures"," ",[15,784,785],{},[224,786],{"alt":787,"src":788},"Layers_Example","/articles/how-to-texture-like-pixar/Layers_Example.png",[15,790,791],{},"This material is a collection of image files that are meant to be plugged directly into a shader node. ",[15,793,794],{},[224,795],{"alt":796,"src":797},"layers_nodes","/articles/how-to-texture-like-pixar/layers_nodes.png",[15,799,800],{},"This looks great and is easy to just plug into your single shader but it isn't very flexible. What if we want to change the flaking pattern? Or maybe we want red paint instead yellow? Or maybe we want the metal to be brass instead of steal?",[15,802,803],{},[224,804],{"alt":805,"src":806},"material_layers","/articles/how-to-texture-like-pixar/material_layers.png",[15,808,809],{},"Instead of just making a single shader, make one for each type of material and blend between them using masks.",[15,811,812],{},[224,813],{"alt":814,"src":815},"masking","/articles/how-to-texture-like-pixar/masking.png",[15,817,818],{},"This provides a good mental model of how we can build our shaders up. We can save each of these layers as separate materials and use them on many objects throughout our project (or other projects).",[15,820,821],{},"This approach is very scalable. For instance, we can swap out the metal/rust layer for wood and voila, we have painted wood instead of metal.",[15,823,824],{},[224,825],{"alt":826,"src":827},"masking_02","/articles/how-to-texture-like-pixar/masking_02.png",[15,829,830],{},"Pixar loves this workflow so much that they made a dedicated shader for it!",[15,832,833],{},[647,834,837],{"href":835,"rel":836},"https://rmanwiki-26.pixar.com/space/REN26/19661463/PxrLayerSurface",[651],"pxrLayerSurface Documentation",[15,839,840],{},"Here is a tutorial on how to do this in Blender:",[299,842],{"url":843},"https://www.youtube.com/watch?v=vG8USHUjQ6g",[10,845,847],{"id":846},"procedural-textures","Procedural Textures",[15,849,850],{},"This is the meat and potatoes of this whole write-up and what the original video didn’t even touch. Proceduralism. Watch the below video and see how Pixar uses their internal texturing program Flow, to build up reusable shader networks in their films.",[299,852],{"url":853},"https://vimeo.com/1153663442",[15,855,856],{},"Instead of manually unwrapping and texturing every prop, just make a reusable material that can be applied to any object. This comes in especially handy in very large scenes with many props/objects. Unwrapping a single model isn’t too bad, but unwrapping hundreds or thousands is just too much to handle.",[15,858,859],{},"If you are unfamiliar with UV Unwrapping here is a good explanation",[299,861],{"url":862},"https://www.youtube.com/watch?v=Yx2JNbv8Kpg",[15,864,865],{},"These procedural materials use geometry based inputs to add details such as dirt, dust, edge damages etc. Here is the example from earlier to illustrate this concept again:",[15,867,868],{},[224,869],{"alt":714,"src":715},[15,871,872],{},"And here is a great video by Pixar Technical Artist Paul Kanyuk describing how pixar uses this technique.",[299,874],{"url":875},"https://www.youtube.com/watch?v=vYi_Dh8ROSg&t=866s",[15,877,878],{},"To summarize Paul’s breakdown, there are several categories of geometry driven details you can apply to scenes",[35,880,882],{"id":881},"ao","AO",[884,885,886],"blockquote",{},[15,887,888],{},"Ambient Occlusion (AO) is a rendering technique that simulates contact and corner shadows: areas that receive less ambient light are darkened.",[15,890,891],{},[224,892],{"alt":893,"src":894},"ambient-occlusion-example","/articles/how-to-texture-like-pixar/ambient-occlusion-example.jpg",[15,896,897],{},"What is this useful for? Dirt of course! We can use ambient occlusion as a mask to place dirt or rust where is would naturally occur in real life. ",[15,899,900],{},[224,901],{"alt":902,"src":903},"AO%20Examples","/articles/how-to-texture-like-pixar/AO%20Examples.png",[299,905],{"url":906},"https://www.youtube.com/watch?v=gQ3y4OGOSTc",[35,908,910],{"id":909},"curvature","Curvature",[15,912,913],{},[224,914],{"alt":909,"src":915},"/articles/how-to-texture-like-pixar/curvature.png",[15,917,918],{},"We can use curvature to isolate the outside edges of our objects and emulate edge wear or damage, effects like peeling back paint where the edges rubbed off or adding scratches to corners of wood where they would naturally occur in the real world.",[15,920,921],{},[224,922],{"alt":923,"src":924},"distressed_wood","/articles/how-to-texture-like-pixar/distressed_wood.png",[15,926,927],{},"Here is a guide on targeting the edges in blender:",[299,929],{"url":930},"https://www.youtube.com/watch?v=Aa8gf1pwb4E",[35,932,934],{"id":933},"upward-facing","Upward Facing",[15,936,937],{},"Add things like dust or snow to the tops of your objects automatically. This is especially helpful when set dressing.",[15,939,940],{},[224,941],{"alt":942,"src":943},"upward","/articles/how-to-texture-like-pixar/upward.png",[15,945,946],{},"In a traditional workflow, you cannot rotate an object around after these types of details have been painted because the textures are \"baked in\".",[15,948,949],{},"Through proceduralism, you're free to rotate move and scale freely while the snow/dirt/moss updates in realtime.",[15,951,952],{},"Here is the node graph I used for the example above",[15,954,955],{},[224,956],{"alt":957,"src":958},"upward_nodes","/articles/how-to-texture-like-pixar/upward_nodes.png",[35,960,962],{"id":961},"world-position","World Position",[15,964,965],{},"Apply dirt or moss to the bottom of objects based on it’s location in the world.",[15,967,968],{},[224,969],{"alt":970,"src":971},"world_position","/articles/how-to-texture-like-pixar/world_position.png",[299,973],{"url":974},"https://www.youtube.com/watch?v=zMaZjx2JC_U",[35,976,978],{"id":977},"projection-mapping","Projection Mapping",[15,980,981],{},"If they don’t use UV Maps, how do they apply patterns to their objects? ",[15,983,984],{},"Project them! This is typically referred to as “Triplanar Mapping” and it is essentially projecting a texture from all axes (XYZ) around your object and blending between them.",[15,986,987],{},"This removes the need for UV Maps.",[299,989],{"url":990},"https://www.youtube.com/watch?v=vyNm3I16rHg",[35,992,994],{"id":993},"procedural-noise-patterns","Procedural Noise Patterns",[15,996,997],{},[224,998],{"alt":999,"src":1000},"noise","/articles/how-to-texture-like-pixar/noise.png",[15,1002,1003],{},"There are limitations when using image maps for texture projection. Resolution for one. You are limited by the size of your texture. Applying a 512x512 texture to a giant wall will be a blurry mess of pixels.",[15,1005,1006],{},"You could tile it but repetition becomes very obvious and that’s assuming the texture is tileable in the first place.",[15,1008,1009],{},"Another solution is procedural noise. These are patterns that are generated by math. They are tileable by default and have no intrinsic resolution so they can be added to any object of any scale.",[299,1011],{"url":1012},"https://www.youtube.com/watch?v=ns-ZK83xgqU",[10,1014,1016],{"id":1015},"putting-it-all-together","Putting it all together",[15,1018,1019],{},"Here is a good video on how you can use all of the maps mentioned above to make a real shader",[299,1021],{"url":1022},"https://www.youtube.com/watch?v=hAWLqRpzK6I",[10,1024,1026],{"id":1025},"using-a-material-library","Using a Material Library",[299,1028],{"url":1029},"https://vimeo.com/353633376",[15,1031,1032],{},"According to their “Technical Toy Story” talk. The general workflow at Pixar is as follows.",[193,1034,1035,1038,1041,1044],{},[43,1036,1037],{},"Determine a list of materials based on the script",[43,1039,1040],{},"Shading artists create reusable materials and save them to a library",[43,1042,1043],{},"Modeling artists apply these pre-made shaders to objects in the scene",[43,1045,1046],{},"Further refinement is done based on the needs of the particular shot",[15,1048,1049],{},"Pixar loves this so much that it’s built into Renderman. The preset browser allows you to create material libraries and reuse them across projects.",[299,1051],{"url":1052},"https://www.youtube.com/watch?v=-OdzP_m7_zs",[15,1054,1055],{},"Blender also leans into this concept with the asset library features that go beyond just materials.",[299,1057],{"url":1058},"https://www.youtube.com/watch?v=jpz13q52YWM",[15,1060,1061],{},"The best part about this approach is that you can reuse these materials across multiple projects or even download third party material libraries like the ones below:",[15,1063,1064],{},[647,1065,1066],{"href":1066,"rel":1067},"https://renderman.pixar.com/fun-da-mental-materials",[651],[299,1069],{"url":1070},"https://www.youtube.com/watch?v=10PNjs2FZqc",[10,1072,1074],{"id":1073},"conclusion","Conclusion",[15,1076,1077],{},"I hope that this was informative and gave you some practical tips to building better art in a more efficient manner.",[15,1079,1080],{},"Thanks for reading!",{"title":341,"searchDepth":342,"depth":342,"links":1082},[1083,1084,1085,1089,1090,1098,1099,1100],{"id":12,"depth":342,"text":13},{"id":635,"depth":342,"text":636},{"id":661,"depth":342,"text":662,"children":1086},[1087,1088],{"id":702,"depth":348,"text":703},{"id":721,"depth":348,"text":722},{"id":760,"depth":342,"text":761},{"id":846,"depth":342,"text":847,"children":1091},[1092,1093,1094,1095,1096,1097],{"id":881,"depth":348,"text":882},{"id":909,"depth":348,"text":910},{"id":933,"depth":348,"text":934},{"id":961,"depth":348,"text":962},{"id":977,"depth":348,"text":978},{"id":993,"depth":348,"text":994},{"id":1015,"depth":342,"text":1016},{"id":1025,"depth":342,"text":1026},{"id":1073,"depth":342,"text":1074},"2026-02-06T05:00:00.000Z","Learn how Pixar gives their films life through procedural texturing techniques","/articles/how-to-texture-like-pixar/TextureLikePixar.png",{"subtitle":1102},true,"/articles/howpercent20topercent20texturepercent20likepercent20pixar",{"title":1108,"description":1109},"How to texture like Pixar file","L","Articles/How%20to%20texture%20like%20Pixar",[1112,1113],"Technical","Art","kORXt99KbO7pu0h9ATN3-U_l6tHF5NJvsOcK2IcO5aE",{"id":1116,"title":1117,"body":1118,"date":3058,"description":3059,"extension":365,"image":3060,"meta":3061,"navigation":3062,"path":3063,"seo":3064,"stem":3065,"tags":3066,"__hash__":3069},"articles/Articles/Creating%20a%20Dynamic%20Video%20Player%20for%20Nuxt%20Studio.md","Creating a Dynamic Video Player for Nuxt Studio",{"type":7,"value":1119,"toc":3045},[1120,1122,1125,1133,1138,1141,1173,1176,1180,1183,1186,1193,1196,1200,1203,1212,1216,1219,1223,1226,1231,1234,1237,1254,1258,1261,1269,1273,1276,1786,1790,1799,1802,1863,1866,2107,2110,2120,2123,2126,2130,2133,2476,3036,3038,3041],[10,1121,13],{"id":12},[15,1123,1124],{},"Nuxt Studio is amazing. It bridges the gap between no-code CMS solutions such as Wordpress or Squarespace and fully custom web applications built in frameworks such as React or Vue. ",[15,1126,1127,1132],{},[647,1128,1131],{"href":1129,"rel":1130},"https://nuxt.studio/",[651],"Nuxt studio"," is a standalone module that you can add to any Nuxt Content based site and edit your posts using their all new visual editor.",[884,1134,1135],{},[15,1136,1137],{},"Self-hosted CMS for your Nuxt Content website. Edit content visually, manage media, and publish changes from your production site.",[15,1139,1140],{},"Just install it with a single command",[1142,1143,1148],"pre",{"className":1144,"code":1145,"filename":1146,"language":1147,"meta":341,"style":341},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","npx nuxt module add nuxt-studio\n","terminal","bash",[1149,1150,1151],"code",{"__ignoreMap":341},[1152,1153,1156,1160,1164,1167,1170],"span",{"class":1154,"line":1155},"line",1,[1152,1157,1159],{"class":1158},"sBMFI","npx",[1152,1161,1163],{"class":1162},"sfazB"," nuxt",[1152,1165,1166],{"class":1162}," module",[1152,1168,1169],{"class":1162}," add",[1152,1171,1172],{"class":1162}," nuxt-studio\n",[15,1174,1175],{},"The release of this new module honestly inspired me to make this very blog so thanks Nuxt Studio!",[10,1177,1179],{"id":1178},"custom-components","Custom Components",[15,1181,1182],{},"The true power of Nuxt Content is that you can leverage the power of Vue/Nuxt from within your markdown files.",[15,1184,1185],{},"For example here is a \"callout\" that I can customize and use inside this blog post. This is just a vue component that I can use anywhere I'd like.",[1187,1188,1190],"callout",{"color":1189},"warning",[15,1191,1192],{},"Here is my super cool callout",[15,1194,1195],{},"What's extra cool is that I can make my own custom components and use them as well.",[10,1197,1199],{"id":1198},"what-are-we-trying-to-do","What are we trying to do?",[15,1201,1202],{},"My blog can be technical at times and I like to include videos describing various topics. These videos aren't saved to the site, but are links from other players such as Youtube or Vimeo.",[15,1204,1205,1206,1211],{},"I could just provide a boring old ",[647,1207,1210],{"href":1208,"rel":1209},"https://www.youtube.com/watch?v=dQw4w9WgXcQ",[651],"link to the video"," but I want my posts to be more exciting than that! The reader should be able to watch without leaving.",[35,1213,1215],{"id":1214},"multiple-types-of-players","Multiple Types of Players",[15,1217,1218],{},"That brings us to our main issue.  There are MANY video players/services out there. My goal was to use a single custom component that could scale to any number of players and only require a single URL. Youtube? Vimeo? Something else? Doesn't matter. ",[35,1220,1222],{"id":1221},"example","Example",[15,1224,1225],{},"The two videos below actually use the same parent component. I don't need to care whether the URL I chose came from Vimeo or Youtube. The component switches automatically for me.",[299,1227],{"url":1228,"className":1229},"https://www.youtube.com/watch?v=nz7UGgr5epQ",[1230],"mb-4",[299,1232],{"url":1233},"https://vimeo.com/56108219",[15,1235,1236],{},"Here it is from a code standpoint, very simple. Just a single URL:",[1142,1238,1241],{"className":1239,"code":1240,"language":365,"meta":341,"style":341},"language-md shiki shiki-themes material-theme-lighter material-theme material-theme-palenight",":video-player{url=\"https://www.youtube.com/watch?v=nz7UGgr5epQ\"}\n:video-player{url=\"https://vimeo.com/56108219\"}\n",[1149,1242,1243,1249],{"__ignoreMap":341},[1152,1244,1245],{"class":1154,"line":1155},[1152,1246,1248],{"class":1247},"sTEyZ",":video-player{url=\"https://www.youtube.com/watch?v=nz7UGgr5epQ\"}\n",[1152,1250,1251],{"class":1154,"line":342},[1152,1252,1253],{"class":1247},":video-player{url=\"https://vimeo.com/56108219\"}\n",[10,1255,1257],{"id":1256},"how-it-works","How it works",[15,1259,1260],{},"There are two parts to this component that make this system work.",[193,1262,1263,1266],{},[43,1264,1265],{},"A main component that decides what player to use based on the URL given",[43,1267,1268],{},"The individual player components themselves",[35,1270,1272],{"id":1271},"main-component","Main Component",[15,1274,1275],{},"This is the central hub that's sole responsibility is to parse the URL and see what player component to use.",[1142,1277,1282],{"className":1278,"code":1279,"filename":1280,"language":1281,"meta":341,"style":341},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003Ctemplate>\n    \u003Ccomponent :is=\"determineVideoPlayer()\" v-bind=\"props\">\u003C/component>\n\u003C/template>\n\n\u003Cscript setup lang=\"ts\">\n\nimport { resolveComponent } from 'vue'\n\nconst props = defineProps\u003C{\n    url: string\n}>();\n\nconst youtubePlayer = resolveComponent('video-player-youtube');\nconst vimeoPlayer = resolveComponent('video-player-vimeo');\n\nconst videoPlayerIndex = {\n    vimeo: vimeoPlayer,\n    youtube: youtubePlayer\n};\n\ntype VideoProvider = keyof typeof videoPlayerIndex;\n\nconst determineVideoPlayer = () => {\n    const { hostname } = new URL(props.url);\n\n    const key = (Object.keys(videoPlayerIndex) as VideoProvider[]).find(provider => hostname.toLowerCase().includes(provider));\n\n    return key ? videoPlayerIndex[key] : undefined;\n};\n\n\u003C/script>\n","videoPlayer.vue","ts",[1149,1283,1284,1295,1349,1357,1363,1381,1386,1414,1419,1438,1451,1463,1468,1496,1521,1526,1539,1553,1564,1570,1575,1598,1603,1621,1656,1661,1734,1739,1766,1771,1776],{"__ignoreMap":341},[1152,1285,1286,1289,1292],{"class":1154,"line":1155},[1152,1287,1288],{"class":1247},"\u003C",[1152,1290,1291],{"class":1158},"template",[1152,1293,1294],{"class":1247},">\n",[1152,1296,1297,1301,1304,1307,1310,1313,1316,1319,1321,1324,1327,1330,1332,1334,1337,1339,1342,1345,1347],{"class":1154,"line":342},[1152,1298,1300],{"class":1299},"sMK4o","    \u003C",[1152,1302,1303],{"class":1158},"component",[1152,1305,1306],{"class":1299}," :",[1152,1308,1309],{"class":1247},"is",[1152,1311,1312],{"class":1299},"=",[1152,1314,1315],{"class":1299},"\"",[1152,1317,1318],{"class":1162},"determineVideoPlayer()",[1152,1320,1315],{"class":1299},[1152,1322,1323],{"class":1247}," v",[1152,1325,1326],{"class":1299},"-",[1152,1328,1329],{"class":1247},"bind",[1152,1331,1312],{"class":1299},[1152,1333,1315],{"class":1299},[1152,1335,1336],{"class":1162},"props",[1152,1338,1315],{"class":1299},[1152,1340,1341],{"class":1299},">",[1152,1343,1344],{"class":1247},"\u003C/",[1152,1346,1303],{"class":1158},[1152,1348,1294],{"class":1247},[1152,1350,1351,1353,1355],{"class":1154,"line":348},[1152,1352,1344],{"class":1299},[1152,1354,1291],{"class":1247},[1152,1356,1294],{"class":1299},[1152,1358,1360],{"class":1154,"line":1359},4,[1152,1361,1362],{"emptyLinePlaceholder":1105},"\n",[1152,1364,1366,1368,1371,1373,1375,1377,1379],{"class":1154,"line":1365},5,[1152,1367,1288],{"class":1299},[1152,1369,1370],{"class":1247},"script setup lang",[1152,1372,1312],{"class":1299},[1152,1374,1315],{"class":1299},[1152,1376,1281],{"class":1162},[1152,1378,1315],{"class":1299},[1152,1380,1294],{"class":1299},[1152,1382,1384],{"class":1154,"line":1383},6,[1152,1385,1362],{"emptyLinePlaceholder":1105},[1152,1387,1389,1393,1396,1399,1402,1405,1408,1411],{"class":1154,"line":1388},7,[1152,1390,1392],{"class":1391},"s7zQu","import",[1152,1394,1395],{"class":1299}," {",[1152,1397,1398],{"class":1247}," resolveComponent",[1152,1400,1401],{"class":1299}," }",[1152,1403,1404],{"class":1391}," from",[1152,1406,1407],{"class":1299}," '",[1152,1409,1410],{"class":1162},"vue",[1152,1412,1413],{"class":1299},"'\n",[1152,1415,1417],{"class":1154,"line":1416},8,[1152,1418,1362],{"emptyLinePlaceholder":1105},[1152,1420,1422,1426,1429,1431,1435],{"class":1154,"line":1421},9,[1152,1423,1425],{"class":1424},"spNyl","const",[1152,1427,1428],{"class":1247}," props ",[1152,1430,1312],{"class":1299},[1152,1432,1434],{"class":1433},"s2Zo4"," defineProps",[1152,1436,1437],{"class":1299},"\u003C{\n",[1152,1439,1441,1445,1448],{"class":1154,"line":1440},10,[1152,1442,1444],{"class":1443},"swJcz","    url",[1152,1446,1447],{"class":1299},":",[1152,1449,1450],{"class":1158}," string\n",[1152,1452,1454,1457,1460],{"class":1154,"line":1453},11,[1152,1455,1456],{"class":1299},"}>",[1152,1458,1459],{"class":1247},"()",[1152,1461,1462],{"class":1299},";\n",[1152,1464,1466],{"class":1154,"line":1465},12,[1152,1467,1362],{"emptyLinePlaceholder":1105},[1152,1469,1471,1473,1476,1478,1480,1483,1486,1489,1491,1494],{"class":1154,"line":1470},13,[1152,1472,1425],{"class":1424},[1152,1474,1475],{"class":1247}," youtubePlayer ",[1152,1477,1312],{"class":1299},[1152,1479,1398],{"class":1433},[1152,1481,1482],{"class":1247},"(",[1152,1484,1485],{"class":1299},"'",[1152,1487,1488],{"class":1162},"video-player-youtube",[1152,1490,1485],{"class":1299},[1152,1492,1493],{"class":1247},")",[1152,1495,1462],{"class":1299},[1152,1497,1499,1501,1504,1506,1508,1510,1512,1515,1517,1519],{"class":1154,"line":1498},14,[1152,1500,1425],{"class":1424},[1152,1502,1503],{"class":1247}," vimeoPlayer ",[1152,1505,1312],{"class":1299},[1152,1507,1398],{"class":1433},[1152,1509,1482],{"class":1247},[1152,1511,1485],{"class":1299},[1152,1513,1514],{"class":1162},"video-player-vimeo",[1152,1516,1485],{"class":1299},[1152,1518,1493],{"class":1247},[1152,1520,1462],{"class":1299},[1152,1522,1524],{"class":1154,"line":1523},15,[1152,1525,1362],{"emptyLinePlaceholder":1105},[1152,1527,1529,1531,1534,1536],{"class":1154,"line":1528},16,[1152,1530,1425],{"class":1424},[1152,1532,1533],{"class":1247}," videoPlayerIndex ",[1152,1535,1312],{"class":1299},[1152,1537,1538],{"class":1299}," {\n",[1152,1540,1542,1545,1547,1550],{"class":1154,"line":1541},17,[1152,1543,1544],{"class":1443},"    vimeo",[1152,1546,1447],{"class":1299},[1152,1548,1549],{"class":1247}," vimeoPlayer",[1152,1551,1552],{"class":1299},",\n",[1152,1554,1556,1559,1561],{"class":1154,"line":1555},18,[1152,1557,1558],{"class":1443},"    youtube",[1152,1560,1447],{"class":1299},[1152,1562,1563],{"class":1247}," youtubePlayer\n",[1152,1565,1567],{"class":1154,"line":1566},19,[1152,1568,1569],{"class":1299},"};\n",[1152,1571,1573],{"class":1154,"line":1572},20,[1152,1574,1362],{"emptyLinePlaceholder":1105},[1152,1576,1578,1581,1584,1587,1590,1593,1596],{"class":1154,"line":1577},21,[1152,1579,1580],{"class":1424},"type",[1152,1582,1583],{"class":1158}," VideoProvider",[1152,1585,1586],{"class":1299}," =",[1152,1588,1589],{"class":1299}," keyof",[1152,1591,1592],{"class":1299}," typeof",[1152,1594,1595],{"class":1247}," videoPlayerIndex",[1152,1597,1462],{"class":1299},[1152,1599,1601],{"class":1154,"line":1600},22,[1152,1602,1362],{"emptyLinePlaceholder":1105},[1152,1604,1606,1608,1611,1613,1616,1619],{"class":1154,"line":1605},23,[1152,1607,1425],{"class":1424},[1152,1609,1610],{"class":1247}," determineVideoPlayer ",[1152,1612,1312],{"class":1299},[1152,1614,1615],{"class":1299}," ()",[1152,1617,1618],{"class":1424}," =>",[1152,1620,1538],{"class":1299},[1152,1622,1624,1627,1629,1632,1634,1636,1639,1642,1644,1646,1649,1652,1654],{"class":1154,"line":1623},24,[1152,1625,1626],{"class":1424},"    const",[1152,1628,1395],{"class":1299},[1152,1630,1631],{"class":1247}," hostname",[1152,1633,1401],{"class":1299},[1152,1635,1586],{"class":1299},[1152,1637,1638],{"class":1299}," new",[1152,1640,1641],{"class":1433}," URL",[1152,1643,1482],{"class":1443},[1152,1645,1336],{"class":1247},[1152,1647,1648],{"class":1299},".",[1152,1650,1651],{"class":1247},"url",[1152,1653,1493],{"class":1443},[1152,1655,1462],{"class":1299},[1152,1657,1659],{"class":1154,"line":1658},25,[1152,1660,1362],{"emptyLinePlaceholder":1105},[1152,1662,1664,1666,1669,1671,1674,1677,1679,1682,1684,1687,1690,1693,1695,1698,1700,1703,1705,1709,1711,1713,1715,1718,1720,1722,1725,1727,1729,1732],{"class":1154,"line":1663},26,[1152,1665,1626],{"class":1424},[1152,1667,1668],{"class":1247}," key",[1152,1670,1586],{"class":1299},[1152,1672,1673],{"class":1443}," (",[1152,1675,1676],{"class":1247},"Object",[1152,1678,1648],{"class":1299},[1152,1680,1681],{"class":1433},"keys",[1152,1683,1482],{"class":1443},[1152,1685,1686],{"class":1247},"videoPlayerIndex",[1152,1688,1689],{"class":1443},") ",[1152,1691,1692],{"class":1391},"as",[1152,1694,1583],{"class":1158},[1152,1696,1697],{"class":1443},"[])",[1152,1699,1648],{"class":1299},[1152,1701,1702],{"class":1433},"find",[1152,1704,1482],{"class":1443},[1152,1706,1708],{"class":1707},"sHdIc","provider",[1152,1710,1618],{"class":1424},[1152,1712,1631],{"class":1247},[1152,1714,1648],{"class":1299},[1152,1716,1717],{"class":1433},"toLowerCase",[1152,1719,1459],{"class":1443},[1152,1721,1648],{"class":1299},[1152,1723,1724],{"class":1433},"includes",[1152,1726,1482],{"class":1443},[1152,1728,1708],{"class":1247},[1152,1730,1731],{"class":1443},"))",[1152,1733,1462],{"class":1299},[1152,1735,1737],{"class":1154,"line":1736},27,[1152,1738,1362],{"emptyLinePlaceholder":1105},[1152,1740,1742,1745,1747,1750,1752,1755,1758,1761,1763],{"class":1154,"line":1741},28,[1152,1743,1744],{"class":1391},"    return",[1152,1746,1668],{"class":1247},[1152,1748,1749],{"class":1299}," ?",[1152,1751,1595],{"class":1247},[1152,1753,1754],{"class":1443},"[",[1152,1756,1757],{"class":1247},"key",[1152,1759,1760],{"class":1443},"] ",[1152,1762,1447],{"class":1299},[1152,1764,1765],{"class":1299}," undefined;\n",[1152,1767,1769],{"class":1154,"line":1768},29,[1152,1770,1569],{"class":1299},[1152,1772,1774],{"class":1154,"line":1773},30,[1152,1775,1362],{"emptyLinePlaceholder":1105},[1152,1777,1779,1781,1784],{"class":1154,"line":1778},31,[1152,1780,1344],{"class":1299},[1152,1782,1783],{"class":1247},"script",[1152,1785,1294],{"class":1299},[748,1787,1789],{"id":1788},"dynamic-component","Dynamic Component",[15,1791,1792,1793,1798],{},"This is a feature I've never used but Vue 3 has the option of creating ",[647,1794,1797],{"href":1795,"rel":1796},"https://vuejs.org/guide/essentials/component-basics#dynamic-components",[651],"dynamic components"," that are selected based on code based logic instead of nesting v-if statements in the html template.",[15,1800,1801],{},"Using the \":is\" prop, I can tell the \u003Ccomponent> tag what to render through code and switch it in real-time based on any logic I decide.",[1142,1803,1805],{"className":1278,"code":1804,"language":1281,"meta":341,"style":341},"\u003Ctemplate>\n    \u003Ccomponent :is=\"determineVideoPlayer()\" v-bind=\"props\">\u003C/component>\n\u003C/template>\n",[1149,1806,1807,1815,1855],{"__ignoreMap":341},[1152,1808,1809,1811,1813],{"class":1154,"line":1155},[1152,1810,1288],{"class":1247},[1152,1812,1291],{"class":1158},[1152,1814,1294],{"class":1247},[1152,1816,1817,1819,1821,1823,1825,1827,1829,1831,1833,1835,1837,1839,1841,1843,1845,1847,1849,1851,1853],{"class":1154,"line":342},[1152,1818,1300],{"class":1299},[1152,1820,1303],{"class":1158},[1152,1822,1306],{"class":1299},[1152,1824,1309],{"class":1247},[1152,1826,1312],{"class":1299},[1152,1828,1315],{"class":1299},[1152,1830,1318],{"class":1162},[1152,1832,1315],{"class":1299},[1152,1834,1323],{"class":1247},[1152,1836,1326],{"class":1299},[1152,1838,1329],{"class":1247},[1152,1840,1312],{"class":1299},[1152,1842,1315],{"class":1299},[1152,1844,1336],{"class":1162},[1152,1846,1315],{"class":1299},[1152,1848,1341],{"class":1299},[1152,1850,1344],{"class":1247},[1152,1852,1303],{"class":1158},[1152,1854,1294],{"class":1247},[1152,1856,1857,1859,1861],{"class":1154,"line":348},[1152,1858,1344],{"class":1299},[1152,1860,1291],{"class":1247},[1152,1862,1294],{"class":1299},[15,1864,1865],{},"In this case the \"determineVideoPlayer()\" function contains the logic used to parse the URL and return the proper component to display",[1142,1867,1869],{"className":1278,"code":1868,"language":1281,"meta":341,"style":341},"const youtubePlayer = resolveComponent('video-player-youtube');\nconst vimeoPlayer = resolveComponent('video-player-vimeo');\n\nconst videoPlayerIndex = {\n    vimeo: vimeoPlayer,\n    youtube: youtubePlayer\n};\n\ntype VideoProvider = keyof typeof videoPlayerIndex;\n\nconst determineVideoPlayer = () => {\n    const { hostname } = new URL(props.url);\n\n    const key = (Object.keys(videoPlayerIndex) as VideoProvider[]).find(provider => hostname.toLowerCase().includes(provider));\n\n    return key ? videoPlayerIndex[key] : undefined;\n};\n",[1149,1870,1871,1893,1915,1919,1929,1939,1947,1951,1955,1971,1975,1989,2017,2021,2079,2083,2103],{"__ignoreMap":341},[1152,1872,1873,1875,1877,1879,1881,1883,1885,1887,1889,1891],{"class":1154,"line":1155},[1152,1874,1425],{"class":1424},[1152,1876,1475],{"class":1247},[1152,1878,1312],{"class":1299},[1152,1880,1398],{"class":1433},[1152,1882,1482],{"class":1247},[1152,1884,1485],{"class":1299},[1152,1886,1488],{"class":1162},[1152,1888,1485],{"class":1299},[1152,1890,1493],{"class":1247},[1152,1892,1462],{"class":1299},[1152,1894,1895,1897,1899,1901,1903,1905,1907,1909,1911,1913],{"class":1154,"line":342},[1152,1896,1425],{"class":1424},[1152,1898,1503],{"class":1247},[1152,1900,1312],{"class":1299},[1152,1902,1398],{"class":1433},[1152,1904,1482],{"class":1247},[1152,1906,1485],{"class":1299},[1152,1908,1514],{"class":1162},[1152,1910,1485],{"class":1299},[1152,1912,1493],{"class":1247},[1152,1914,1462],{"class":1299},[1152,1916,1917],{"class":1154,"line":348},[1152,1918,1362],{"emptyLinePlaceholder":1105},[1152,1920,1921,1923,1925,1927],{"class":1154,"line":1359},[1152,1922,1425],{"class":1424},[1152,1924,1533],{"class":1247},[1152,1926,1312],{"class":1299},[1152,1928,1538],{"class":1299},[1152,1930,1931,1933,1935,1937],{"class":1154,"line":1365},[1152,1932,1544],{"class":1443},[1152,1934,1447],{"class":1299},[1152,1936,1549],{"class":1247},[1152,1938,1552],{"class":1299},[1152,1940,1941,1943,1945],{"class":1154,"line":1383},[1152,1942,1558],{"class":1443},[1152,1944,1447],{"class":1299},[1152,1946,1563],{"class":1247},[1152,1948,1949],{"class":1154,"line":1388},[1152,1950,1569],{"class":1299},[1152,1952,1953],{"class":1154,"line":1416},[1152,1954,1362],{"emptyLinePlaceholder":1105},[1152,1956,1957,1959,1961,1963,1965,1967,1969],{"class":1154,"line":1421},[1152,1958,1580],{"class":1424},[1152,1960,1583],{"class":1158},[1152,1962,1586],{"class":1299},[1152,1964,1589],{"class":1299},[1152,1966,1592],{"class":1299},[1152,1968,1595],{"class":1247},[1152,1970,1462],{"class":1299},[1152,1972,1973],{"class":1154,"line":1440},[1152,1974,1362],{"emptyLinePlaceholder":1105},[1152,1976,1977,1979,1981,1983,1985,1987],{"class":1154,"line":1453},[1152,1978,1425],{"class":1424},[1152,1980,1610],{"class":1247},[1152,1982,1312],{"class":1299},[1152,1984,1615],{"class":1299},[1152,1986,1618],{"class":1424},[1152,1988,1538],{"class":1299},[1152,1990,1991,1993,1995,1997,1999,2001,2003,2005,2007,2009,2011,2013,2015],{"class":1154,"line":1465},[1152,1992,1626],{"class":1424},[1152,1994,1395],{"class":1299},[1152,1996,1631],{"class":1247},[1152,1998,1401],{"class":1299},[1152,2000,1586],{"class":1299},[1152,2002,1638],{"class":1299},[1152,2004,1641],{"class":1433},[1152,2006,1482],{"class":1443},[1152,2008,1336],{"class":1247},[1152,2010,1648],{"class":1299},[1152,2012,1651],{"class":1247},[1152,2014,1493],{"class":1443},[1152,2016,1462],{"class":1299},[1152,2018,2019],{"class":1154,"line":1470},[1152,2020,1362],{"emptyLinePlaceholder":1105},[1152,2022,2023,2025,2027,2029,2031,2033,2035,2037,2039,2041,2043,2045,2047,2049,2051,2053,2055,2057,2059,2061,2063,2065,2067,2069,2071,2073,2075,2077],{"class":1154,"line":1498},[1152,2024,1626],{"class":1424},[1152,2026,1668],{"class":1247},[1152,2028,1586],{"class":1299},[1152,2030,1673],{"class":1443},[1152,2032,1676],{"class":1247},[1152,2034,1648],{"class":1299},[1152,2036,1681],{"class":1433},[1152,2038,1482],{"class":1443},[1152,2040,1686],{"class":1247},[1152,2042,1689],{"class":1443},[1152,2044,1692],{"class":1391},[1152,2046,1583],{"class":1158},[1152,2048,1697],{"class":1443},[1152,2050,1648],{"class":1299},[1152,2052,1702],{"class":1433},[1152,2054,1482],{"class":1443},[1152,2056,1708],{"class":1707},[1152,2058,1618],{"class":1424},[1152,2060,1631],{"class":1247},[1152,2062,1648],{"class":1299},[1152,2064,1717],{"class":1433},[1152,2066,1459],{"class":1443},[1152,2068,1648],{"class":1299},[1152,2070,1724],{"class":1433},[1152,2072,1482],{"class":1443},[1152,2074,1708],{"class":1247},[1152,2076,1731],{"class":1443},[1152,2078,1462],{"class":1299},[1152,2080,2081],{"class":1154,"line":1523},[1152,2082,1362],{"emptyLinePlaceholder":1105},[1152,2084,2085,2087,2089,2091,2093,2095,2097,2099,2101],{"class":1154,"line":1528},[1152,2086,1744],{"class":1391},[1152,2088,1668],{"class":1247},[1152,2090,1749],{"class":1299},[1152,2092,1595],{"class":1247},[1152,2094,1754],{"class":1443},[1152,2096,1757],{"class":1247},[1152,2098,1760],{"class":1443},[1152,2100,1447],{"class":1299},[1152,2102,1765],{"class":1299},[1152,2104,2105],{"class":1154,"line":1541},[1152,2106,1569],{"class":1299},[15,2108,2109],{},"Instead of nesting if else statements, I wanted to use a solution that could scale infinitely. I use a videoPlayerIndex object to store a key value pair of providers with their vue component (I'll go over those shortly)",[15,2111,2112,2113,2116,2117,782],{},"The function checks to see if the particular key (youtube or vimeo in this case) is included in the base url passed to the component. This is the main domain so a long youtube link like \"",[647,2114,1208],{"href":1208,"rel":2115},[651],"\" becomes just \"",[647,2118,2119],{"href":341},"www.youtube.com\".",[15,2121,2122],{},"The function sees that there is a key of \"youtube\" and passes the value of that key to the dynamic component.",[15,2124,2125],{},"I can add an infinite number of keys to this object without ever touching my determineVideoPlayer() again.",[35,2127,2129],{"id":2128},"individual-players","Individual Players",[15,2131,2132],{},"Each player has its own dedicated component. Here are the two I am using. They are just the default boilerplate given by the providers with dynamic URLs.",[1142,2134,2137],{"className":1278,"code":2135,"filename":2136,"language":1281,"meta":341,"style":341},"\u003Ctemplate>\n    \u003Cdiv style=\"padding:56.25% 0 0 0;position:relative;\">\u003Ciframe :src=\"buildVimeoURL\" frameborder=\"0\" allow=\"autoplay; fullscreen; picture-in-picture; clipboard-write; encrypted-media; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" style=\"position:absolute;top:0;left:0;width:100%;height:100%;\" title=\"Pixar BOF SIGGRAPH 2022\">\u003C/iframe>\u003C/div>\n\u003C/template>\n\n\u003Cscript setup lang=\"ts\">\n\nconst props = defineProps\u003C{\n    url: string\n}>();\n\nconst buildVimeoURL = computed( () => {\n    const url = new URL(props.url);\n    const urlParsed = url.pathname.replaceAll('/', '');\n\n    let outputURL = `https://player.vimeo.com/video/${urlParsed}?badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479`\n\n    return outputURL;\n})\n\n\n\u003C/script>\n","vimeo.vue",[1149,2138,2139,2147,2256,2264,2268,2284,2288,2300,2308,2316,2320,2341,2366,2406,2410,2441,2445,2453,2460,2464,2468],{"__ignoreMap":341},[1152,2140,2141,2143,2145],{"class":1154,"line":1155},[1152,2142,1288],{"class":1247},[1152,2144,1291],{"class":1158},[1152,2146,1294],{"class":1247},[1152,2148,2149,2151,2154,2156,2158,2161,2163,2165,2167,2170,2172,2175,2177,2179,2182,2184,2187,2189,2191,2194,2196,2199,2201,2203,2206,2208,2211,2213,2215,2218,2220,2223,2225,2227,2230,2232,2235,2237,2239,2242,2244,2247,2249,2251,2254],{"class":1154,"line":342},[1152,2150,1300],{"class":1299},[1152,2152,2153],{"class":1247},"div style",[1152,2155,1312],{"class":1299},[1152,2157,1315],{"class":1299},[1152,2159,2160],{"class":1162},"padding:56.25% 0 0 0;position:relative;",[1152,2162,1315],{"class":1299},[1152,2164,1341],{"class":1299},[1152,2166,1288],{"class":1247},[1152,2168,2169],{"class":1158},"iframe",[1152,2171,1306],{"class":1299},[1152,2173,2174],{"class":1158},"src",[1152,2176,1312],{"class":1247},[1152,2178,1315],{"class":1299},[1152,2180,2181],{"class":1162},"buildVimeoURL",[1152,2183,1315],{"class":1299},[1152,2185,2186],{"class":1158}," frameborder",[1152,2188,1312],{"class":1247},[1152,2190,1315],{"class":1299},[1152,2192,2193],{"class":1162},"0",[1152,2195,1315],{"class":1299},[1152,2197,2198],{"class":1158}," allow",[1152,2200,1312],{"class":1247},[1152,2202,1315],{"class":1299},[1152,2204,2205],{"class":1162},"autoplay; fullscreen; picture-in-picture; clipboard-write; encrypted-media; web-share",[1152,2207,1315],{"class":1299},[1152,2209,2210],{"class":1158}," referrerpolicy",[1152,2212,1312],{"class":1247},[1152,2214,1315],{"class":1299},[1152,2216,2217],{"class":1162},"strict-origin-when-cross-origin",[1152,2219,1315],{"class":1299},[1152,2221,2222],{"class":1158}," style",[1152,2224,1312],{"class":1247},[1152,2226,1315],{"class":1299},[1152,2228,2229],{"class":1162},"position:absolute;top:0;left:0;width:100%;height:100%;",[1152,2231,1315],{"class":1299},[1152,2233,2234],{"class":1158}," title",[1152,2236,1312],{"class":1247},[1152,2238,1315],{"class":1299},[1152,2240,2241],{"class":1162},"Pixar BOF SIGGRAPH 2022",[1152,2243,1315],{"class":1299},[1152,2245,2246],{"class":1247},">\u003C/",[1152,2248,2169],{"class":1158},[1152,2250,2246],{"class":1247},[1152,2252,2253],{"class":1158},"div",[1152,2255,1294],{"class":1247},[1152,2257,2258,2260,2262],{"class":1154,"line":348},[1152,2259,1344],{"class":1299},[1152,2261,1291],{"class":1247},[1152,2263,1294],{"class":1299},[1152,2265,2266],{"class":1154,"line":1359},[1152,2267,1362],{"emptyLinePlaceholder":1105},[1152,2269,2270,2272,2274,2276,2278,2280,2282],{"class":1154,"line":1365},[1152,2271,1288],{"class":1299},[1152,2273,1370],{"class":1247},[1152,2275,1312],{"class":1299},[1152,2277,1315],{"class":1299},[1152,2279,1281],{"class":1162},[1152,2281,1315],{"class":1299},[1152,2283,1294],{"class":1299},[1152,2285,2286],{"class":1154,"line":1383},[1152,2287,1362],{"emptyLinePlaceholder":1105},[1152,2289,2290,2292,2294,2296,2298],{"class":1154,"line":1388},[1152,2291,1425],{"class":1424},[1152,2293,1428],{"class":1247},[1152,2295,1312],{"class":1299},[1152,2297,1434],{"class":1433},[1152,2299,1437],{"class":1299},[1152,2301,2302,2304,2306],{"class":1154,"line":1416},[1152,2303,1444],{"class":1443},[1152,2305,1447],{"class":1299},[1152,2307,1450],{"class":1158},[1152,2309,2310,2312,2314],{"class":1154,"line":1421},[1152,2311,1456],{"class":1299},[1152,2313,1459],{"class":1247},[1152,2315,1462],{"class":1299},[1152,2317,2318],{"class":1154,"line":1440},[1152,2319,1362],{"emptyLinePlaceholder":1105},[1152,2321,2322,2324,2327,2329,2332,2335,2337,2339],{"class":1154,"line":1453},[1152,2323,1425],{"class":1424},[1152,2325,2326],{"class":1247}," buildVimeoURL ",[1152,2328,1312],{"class":1299},[1152,2330,2331],{"class":1433}," computed",[1152,2333,2334],{"class":1247},"( ",[1152,2336,1459],{"class":1299},[1152,2338,1618],{"class":1424},[1152,2340,1538],{"class":1299},[1152,2342,2343,2345,2348,2350,2352,2354,2356,2358,2360,2362,2364],{"class":1154,"line":1465},[1152,2344,1626],{"class":1424},[1152,2346,2347],{"class":1247}," url",[1152,2349,1586],{"class":1299},[1152,2351,1638],{"class":1299},[1152,2353,1641],{"class":1433},[1152,2355,1482],{"class":1443},[1152,2357,1336],{"class":1247},[1152,2359,1648],{"class":1299},[1152,2361,1651],{"class":1247},[1152,2363,1493],{"class":1443},[1152,2365,1462],{"class":1299},[1152,2367,2368,2370,2373,2375,2377,2379,2382,2384,2387,2389,2391,2394,2396,2399,2402,2404],{"class":1154,"line":1470},[1152,2369,1626],{"class":1424},[1152,2371,2372],{"class":1247}," urlParsed",[1152,2374,1586],{"class":1299},[1152,2376,2347],{"class":1247},[1152,2378,1648],{"class":1299},[1152,2380,2381],{"class":1247},"pathname",[1152,2383,1648],{"class":1299},[1152,2385,2386],{"class":1433},"replaceAll",[1152,2388,1482],{"class":1443},[1152,2390,1485],{"class":1299},[1152,2392,2393],{"class":1162},"/",[1152,2395,1485],{"class":1299},[1152,2397,2398],{"class":1299},",",[1152,2400,2401],{"class":1299}," ''",[1152,2403,1493],{"class":1443},[1152,2405,1462],{"class":1299},[1152,2407,2408],{"class":1154,"line":1498},[1152,2409,1362],{"emptyLinePlaceholder":1105},[1152,2411,2412,2415,2418,2420,2423,2426,2429,2432,2435,2438],{"class":1154,"line":1523},[1152,2413,2414],{"class":1424},"    let",[1152,2416,2417],{"class":1247}," outputURL",[1152,2419,1586],{"class":1299},[1152,2421,2422],{"class":1299}," `",[1152,2424,2425],{"class":1162},"https://player.vimeo.com/video/",[1152,2427,2428],{"class":1299},"${",[1152,2430,2431],{"class":1247},"urlParsed",[1152,2433,2434],{"class":1299},"}",[1152,2436,2437],{"class":1162},"?badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479",[1152,2439,2440],{"class":1299},"`\n",[1152,2442,2443],{"class":1154,"line":1528},[1152,2444,1362],{"emptyLinePlaceholder":1105},[1152,2446,2447,2449,2451],{"class":1154,"line":1541},[1152,2448,1744],{"class":1391},[1152,2450,2417],{"class":1247},[1152,2452,1462],{"class":1299},[1152,2454,2455,2457],{"class":1154,"line":1555},[1152,2456,2434],{"class":1299},[1152,2458,2459],{"class":1247},")\n",[1152,2461,2462],{"class":1154,"line":1566},[1152,2463,1362],{"emptyLinePlaceholder":1105},[1152,2465,2466],{"class":1154,"line":1572},[1152,2467,1362],{"emptyLinePlaceholder":1105},[1152,2469,2470,2472,2474],{"class":1154,"line":1577},[1152,2471,1344],{"class":1299},[1152,2473,1783],{"class":1247},[1152,2475,1294],{"class":1299},[1142,2477,2480],{"className":1278,"code":2478,"filename":2479,"language":1281,"meta":341,"style":341},"\u003Ctemplate>\n    \u003Ciframe width=\"100%\" height=\"400\" :src=\"`https://www.youtube.com/embed/${parseYoutubeURL(props.url)}`\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen>\u003C/iframe>\n\u003C/template>\n\n\u003Cscript setup lang=\"ts\">\n\nconst props = defineProps\u003C{\n    url: string\n}>();\n\nconst parseYoutubeURL = (url: string) => {\n\n    try {\n        const parsedUrl = new URL(url);\n\n        // youtu.be/VIDEO_ID\n        if (parsedUrl.hostname === 'youtu.be') {\n            return parsedUrl.pathname.slice(1);\n        }\n\n        // youtube.com/watch?v=VIDEO_ID\n        if (parsedUrl.searchParams.has('v')) {\n            return parsedUrl.searchParams.get('v');\n        }\n\n        // youtube.com/embed/VIDEO_ID\n        // youtube.com/shorts/VIDEO_ID\n        const pathMatch = parsedUrl.pathname.match(\n            /^\\/(embed|shorts)\\/([^/?]+)/\n        );\n\n        if (pathMatch) {\n            return pathMatch[2];\n        }\n\n        return null;\n    } catch (e) {\n        return null;\n    }\n\n}\n\n\u003C/script>\n","youtube.vue",[1149,2481,2482,2490,2583,2591,2595,2611,2615,2627,2635,2643,2647,2671,2675,2682,2704,2708,2714,2744,2770,2775,2779,2784,2816,2843,2847,2851,2856,2861,2884,2919,2926,2930,2944,2961,2966,2971,2980,2998,3005,3011,3016,3022,3027],{"__ignoreMap":341},[1152,2483,2484,2486,2488],{"class":1154,"line":1155},[1152,2485,1288],{"class":1247},[1152,2487,1291],{"class":1158},[1152,2489,1294],{"class":1247},[1152,2491,2492,2494,2497,2499,2501,2504,2506,2509,2511,2513,2516,2518,2521,2523,2525,2528,2530,2532,2534,2536,2539,2541,2543,2545,2547,2549,2551,2553,2555,2557,2560,2562,2564,2566,2568,2570,2572,2575,2577,2579,2581],{"class":1154,"line":342},[1152,2493,1300],{"class":1299},[1152,2495,2496],{"class":1247},"iframe width",[1152,2498,1312],{"class":1299},[1152,2500,1315],{"class":1299},[1152,2502,2503],{"class":1162},"100%",[1152,2505,1315],{"class":1299},[1152,2507,2508],{"class":1247}," height",[1152,2510,1312],{"class":1299},[1152,2512,1315],{"class":1299},[1152,2514,2515],{"class":1162},"400",[1152,2517,1315],{"class":1299},[1152,2519,2520],{"class":1247}," :src",[1152,2522,1312],{"class":1299},[1152,2524,1315],{"class":1299},[1152,2526,2527],{"class":1162},"`https://www.youtube.com/embed/${parseYoutubeURL(props.url)}`",[1152,2529,1315],{"class":1299},[1152,2531,2234],{"class":1247},[1152,2533,1312],{"class":1299},[1152,2535,1315],{"class":1299},[1152,2537,2538],{"class":1162},"YouTube video player",[1152,2540,1315],{"class":1299},[1152,2542,2186],{"class":1247},[1152,2544,1312],{"class":1299},[1152,2546,1315],{"class":1299},[1152,2548,2193],{"class":1162},[1152,2550,1315],{"class":1299},[1152,2552,2198],{"class":1247},[1152,2554,1312],{"class":1299},[1152,2556,1315],{"class":1299},[1152,2558,2559],{"class":1162},"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",[1152,2561,1315],{"class":1299},[1152,2563,2210],{"class":1247},[1152,2565,1312],{"class":1299},[1152,2567,1315],{"class":1299},[1152,2569,2217],{"class":1162},[1152,2571,1315],{"class":1299},[1152,2573,2574],{"class":1247}," allowfullscreen",[1152,2576,1341],{"class":1299},[1152,2578,1344],{"class":1247},[1152,2580,2169],{"class":1158},[1152,2582,1294],{"class":1247},[1152,2584,2585,2587,2589],{"class":1154,"line":348},[1152,2586,1344],{"class":1299},[1152,2588,1291],{"class":1247},[1152,2590,1294],{"class":1299},[1152,2592,2593],{"class":1154,"line":1359},[1152,2594,1362],{"emptyLinePlaceholder":1105},[1152,2596,2597,2599,2601,2603,2605,2607,2609],{"class":1154,"line":1365},[1152,2598,1288],{"class":1299},[1152,2600,1370],{"class":1247},[1152,2602,1312],{"class":1299},[1152,2604,1315],{"class":1299},[1152,2606,1281],{"class":1162},[1152,2608,1315],{"class":1299},[1152,2610,1294],{"class":1299},[1152,2612,2613],{"class":1154,"line":1383},[1152,2614,1362],{"emptyLinePlaceholder":1105},[1152,2616,2617,2619,2621,2623,2625],{"class":1154,"line":1388},[1152,2618,1425],{"class":1424},[1152,2620,1428],{"class":1247},[1152,2622,1312],{"class":1299},[1152,2624,1434],{"class":1433},[1152,2626,1437],{"class":1299},[1152,2628,2629,2631,2633],{"class":1154,"line":1416},[1152,2630,1444],{"class":1443},[1152,2632,1447],{"class":1299},[1152,2634,1450],{"class":1158},[1152,2636,2637,2639,2641],{"class":1154,"line":1421},[1152,2638,1456],{"class":1299},[1152,2640,1459],{"class":1247},[1152,2642,1462],{"class":1299},[1152,2644,2645],{"class":1154,"line":1440},[1152,2646,1362],{"emptyLinePlaceholder":1105},[1152,2648,2649,2651,2654,2656,2658,2660,2662,2665,2667,2669],{"class":1154,"line":1453},[1152,2650,1425],{"class":1424},[1152,2652,2653],{"class":1247}," parseYoutubeURL ",[1152,2655,1312],{"class":1299},[1152,2657,1673],{"class":1299},[1152,2659,1651],{"class":1707},[1152,2661,1447],{"class":1299},[1152,2663,2664],{"class":1158}," string",[1152,2666,1493],{"class":1299},[1152,2668,1618],{"class":1424},[1152,2670,1538],{"class":1299},[1152,2672,2673],{"class":1154,"line":1465},[1152,2674,1362],{"emptyLinePlaceholder":1105},[1152,2676,2677,2680],{"class":1154,"line":1470},[1152,2678,2679],{"class":1391},"    try",[1152,2681,1538],{"class":1299},[1152,2683,2684,2687,2690,2692,2694,2696,2698,2700,2702],{"class":1154,"line":1498},[1152,2685,2686],{"class":1424},"        const",[1152,2688,2689],{"class":1247}," parsedUrl",[1152,2691,1586],{"class":1299},[1152,2693,1638],{"class":1299},[1152,2695,1641],{"class":1433},[1152,2697,1482],{"class":1443},[1152,2699,1651],{"class":1247},[1152,2701,1493],{"class":1443},[1152,2703,1462],{"class":1299},[1152,2705,2706],{"class":1154,"line":1523},[1152,2707,1362],{"emptyLinePlaceholder":1105},[1152,2709,2710],{"class":1154,"line":1528},[1152,2711,2713],{"class":2712},"sHwdD","        // youtu.be/VIDEO_ID\n",[1152,2715,2716,2719,2721,2724,2726,2729,2732,2734,2737,2739,2741],{"class":1154,"line":1541},[1152,2717,2718],{"class":1391},"        if",[1152,2720,1673],{"class":1443},[1152,2722,2723],{"class":1247},"parsedUrl",[1152,2725,1648],{"class":1299},[1152,2727,2728],{"class":1247},"hostname",[1152,2730,2731],{"class":1299}," ===",[1152,2733,1407],{"class":1299},[1152,2735,2736],{"class":1162},"youtu.be",[1152,2738,1485],{"class":1299},[1152,2740,1689],{"class":1443},[1152,2742,2743],{"class":1299},"{\n",[1152,2745,2746,2749,2751,2753,2755,2757,2760,2762,2766,2768],{"class":1154,"line":1555},[1152,2747,2748],{"class":1391},"            return",[1152,2750,2689],{"class":1247},[1152,2752,1648],{"class":1299},[1152,2754,2381],{"class":1247},[1152,2756,1648],{"class":1299},[1152,2758,2759],{"class":1433},"slice",[1152,2761,1482],{"class":1443},[1152,2763,2765],{"class":2764},"sbssI","1",[1152,2767,1493],{"class":1443},[1152,2769,1462],{"class":1299},[1152,2771,2772],{"class":1154,"line":1566},[1152,2773,2774],{"class":1299},"        }\n",[1152,2776,2777],{"class":1154,"line":1572},[1152,2778,1362],{"emptyLinePlaceholder":1105},[1152,2780,2781],{"class":1154,"line":1577},[1152,2782,2783],{"class":2712},"        // youtube.com/watch?v=VIDEO_ID\n",[1152,2785,2786,2788,2790,2792,2794,2797,2799,2802,2804,2806,2809,2811,2814],{"class":1154,"line":1600},[1152,2787,2718],{"class":1391},[1152,2789,1673],{"class":1443},[1152,2791,2723],{"class":1247},[1152,2793,1648],{"class":1299},[1152,2795,2796],{"class":1247},"searchParams",[1152,2798,1648],{"class":1299},[1152,2800,2801],{"class":1433},"has",[1152,2803,1482],{"class":1443},[1152,2805,1485],{"class":1299},[1152,2807,2808],{"class":1162},"v",[1152,2810,1485],{"class":1299},[1152,2812,2813],{"class":1443},")) ",[1152,2815,2743],{"class":1299},[1152,2817,2818,2820,2822,2824,2826,2828,2831,2833,2835,2837,2839,2841],{"class":1154,"line":1605},[1152,2819,2748],{"class":1391},[1152,2821,2689],{"class":1247},[1152,2823,1648],{"class":1299},[1152,2825,2796],{"class":1247},[1152,2827,1648],{"class":1299},[1152,2829,2830],{"class":1433},"get",[1152,2832,1482],{"class":1443},[1152,2834,1485],{"class":1299},[1152,2836,2808],{"class":1162},[1152,2838,1485],{"class":1299},[1152,2840,1493],{"class":1443},[1152,2842,1462],{"class":1299},[1152,2844,2845],{"class":1154,"line":1623},[1152,2846,2774],{"class":1299},[1152,2848,2849],{"class":1154,"line":1658},[1152,2850,1362],{"emptyLinePlaceholder":1105},[1152,2852,2853],{"class":1154,"line":1663},[1152,2854,2855],{"class":2712},"        // youtube.com/embed/VIDEO_ID\n",[1152,2857,2858],{"class":1154,"line":1736},[1152,2859,2860],{"class":2712},"        // youtube.com/shorts/VIDEO_ID\n",[1152,2862,2863,2865,2868,2870,2872,2874,2876,2878,2881],{"class":1154,"line":1741},[1152,2864,2686],{"class":1424},[1152,2866,2867],{"class":1247}," pathMatch",[1152,2869,1586],{"class":1299},[1152,2871,2689],{"class":1247},[1152,2873,1648],{"class":1299},[1152,2875,2381],{"class":1247},[1152,2877,1648],{"class":1299},[1152,2879,2880],{"class":1433},"match",[1152,2882,2883],{"class":1443},"(\n",[1152,2885,2886,2889,2892,2895,2897,2900,2903,2906,2908,2910,2913,2916],{"class":1154,"line":1768},[1152,2887,2888],{"class":1299},"            /",[1152,2890,2891],{"class":1391},"^",[1152,2893,2894],{"class":1247},"\\/",[1152,2896,1482],{"class":1299},[1152,2898,2899],{"class":1162},"embed",[1152,2901,2902],{"class":1299},"|",[1152,2904,2905],{"class":1162},"shorts",[1152,2907,1493],{"class":1299},[1152,2909,2894],{"class":1247},[1152,2911,2912],{"class":1299},"([^",[1152,2914,2915],{"class":1162},"/?",[1152,2917,2918],{"class":1299},"]+)/\n",[1152,2920,2921,2924],{"class":1154,"line":1773},[1152,2922,2923],{"class":1443},"        )",[1152,2925,1462],{"class":1299},[1152,2927,2928],{"class":1154,"line":1778},[1152,2929,1362],{"emptyLinePlaceholder":1105},[1152,2931,2933,2935,2937,2940,2942],{"class":1154,"line":2932},32,[1152,2934,2718],{"class":1391},[1152,2936,1673],{"class":1443},[1152,2938,2939],{"class":1247},"pathMatch",[1152,2941,1689],{"class":1443},[1152,2943,2743],{"class":1299},[1152,2945,2947,2949,2951,2953,2956,2959],{"class":1154,"line":2946},33,[1152,2948,2748],{"class":1391},[1152,2950,2867],{"class":1247},[1152,2952,1754],{"class":1443},[1152,2954,2955],{"class":2764},"2",[1152,2957,2958],{"class":1443},"]",[1152,2960,1462],{"class":1299},[1152,2962,2964],{"class":1154,"line":2963},34,[1152,2965,2774],{"class":1299},[1152,2967,2969],{"class":1154,"line":2968},35,[1152,2970,1362],{"emptyLinePlaceholder":1105},[1152,2972,2974,2977],{"class":1154,"line":2973},36,[1152,2975,2976],{"class":1391},"        return",[1152,2978,2979],{"class":1299}," null;\n",[1152,2981,2983,2986,2989,2991,2994,2996],{"class":1154,"line":2982},37,[1152,2984,2985],{"class":1299},"    }",[1152,2987,2988],{"class":1391}," catch",[1152,2990,1673],{"class":1443},[1152,2992,2993],{"class":1247},"e",[1152,2995,1689],{"class":1443},[1152,2997,2743],{"class":1299},[1152,2999,3001,3003],{"class":1154,"line":3000},38,[1152,3002,2976],{"class":1391},[1152,3004,2979],{"class":1299},[1152,3006,3008],{"class":1154,"line":3007},39,[1152,3009,3010],{"class":1299},"    }\n",[1152,3012,3014],{"class":1154,"line":3013},40,[1152,3015,1362],{"emptyLinePlaceholder":1105},[1152,3017,3019],{"class":1154,"line":3018},41,[1152,3020,3021],{"class":1299},"}\n",[1152,3023,3025],{"class":1154,"line":3024},42,[1152,3026,1362],{"emptyLinePlaceholder":1105},[1152,3028,3030,3032,3034],{"class":1154,"line":3029},43,[1152,3031,1344],{"class":1299},[1152,3033,1783],{"class":1247},[1152,3035,1294],{"class":1299},[10,3037,1074],{"id":1073},[15,3039,3040],{},"And just like that we have a scalable video player that all I do is pass a single URL. Now this isn't perfect and I could definitely improve on it to make it more production ready but for a personal blog, it does what I need!",[3042,3043,3044],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":341,"searchDepth":342,"depth":342,"links":3046},[3047,3048,3049,3053,3057],{"id":12,"depth":342,"text":13},{"id":1178,"depth":342,"text":1179},{"id":1198,"depth":342,"text":1199,"children":3050},[3051,3052],{"id":1214,"depth":348,"text":1215},{"id":1221,"depth":348,"text":1222},{"id":1256,"depth":342,"text":1257,"children":3054},[3055,3056],{"id":1271,"depth":348,"text":1272},{"id":2128,"depth":348,"text":2129},{"id":1073,"depth":342,"text":1074},"2026-01-13T05:00:00.000Z","Learn how to make a video player component that switches embeded players based on the url given","/articles/custom-video-component/custom-video-component-thumbnail.jpg",{"subtitle":3059},{"description":3059,"title":1117},"/articles/creatingpercent20apercent20dynamicpercent20videopercent20playerpercent20forpercent20nuxtpercent20studio",{"title":1117,"description":3059},"Articles/Creating%20a%20Dynamic%20Video%20Player%20for%20Nuxt%20Studio",[3067,1112,3068],"Programming","Web Design","ZmOClNJnjoIirEkioTuZHRIOls00PBYD_hu00N9rHck",{"id":3071,"title":3072,"body":3073,"date":3444,"description":3445,"extension":365,"image":3446,"meta":3447,"navigation":1105,"path":3449,"seo":3450,"stem":3451,"tags":3452,"__hash__":3454},"articles/Articles/grass-field-usd.md","Grass Field Usd",{"type":7,"value":3074,"toc":3428},[3075,3078,3083,3087,3090,3093,3104,3107,3111,3114,3117,3122,3125,3136,3139,3143,3146,3154,3157,3161,3164,3169,3172,3177,3200,3205,3225,3230,3233,3237,3240,3248,3251,3254,3258,3261,3264,3269,3272,3275,3280,3283,3288,3291,3295,3298,3303,3306,3311,3314,3317,3322,3325,3330,3333,3338,3341,3346,3349,3353,3356,3360,3374,3378,3392,3396,3407,3411],[15,3076,3077],{},"Over the past few months, I’ve been doing a bit of research on industry workflows/trends and there are two topics that kept grabbing my attention. Houdini and USD. So of course the logical progression was to create a personal project using both! But what to make? After a flurry of awful ideas, I figured that grass seemed to be the perfect candidate. I could use Houdini to generate the terrain and scatter the geometry, use USD to pass all that data along to Katana, and finally get those sweet renders out using Renderman. So I have my subject and tools lined up, now it’s time to build the USD plugins and get to work. Easy right? Well what followed was two months of stumbling through forums and online resources to iron out all of the wrinkles that came with this project. All in all I learned plenty and I’m excited to pass some of that on to the public!",[15,3079,3080],{},[224,3081],{"alt":341,"src":3082},"https://digitalcolony3d.wordpress.com/wp-content/uploads/2019/10/grassnuke_v004.png?w=1024",[10,3084,3086],{"id":3085},"gathering-reference","Gathering Reference",[15,3088,3089],{},"Truly the key to a great final image. The famous quote “Good artists copy, but great artists steal” seems to be rather abrasive at first glance but it’s the credo we all should live by. See what works and make it your own!",[15,3091,3092],{},"Some of my favorite places to look for reference are Google Images, Pinterest and Artstation. But you can’t beat going outside and taking your own photos.",[15,3094,3095,3098,3101],{},[224,3096],{"alt":341,"src":3097},"https://digitalcolony3d.wordpress.com/wp-content/uploads/2019/10/img_4353.jpg?w=1024",[224,3099],{"alt":341,"src":3100},"https://digitalcolony3d.wordpress.com/wp-content/uploads/2019/10/img_4350.jpg?w=1024",[224,3102],{"alt":341,"src":3103},"https://digitalcolony3d.wordpress.com/wp-content/uploads/2019/10/img_4354.jpg?w=1024",[15,3105,3106],{},"That being said, I was inspired by several artists on Artstation and they set the bar for what I wanted to accomplish. Down in the resources below, I posted links to their portfolios. Check them out!",[10,3108,3110],{"id":3109},"texture-photoshoot","Texture Photoshoot",[15,3112,3113],{},"I debated on whether or not I was going to use pre-made assets from a resource such as Megascans or if I would completely make everything from scratch. I decided it would be a good exercise to go out and take the photos myself and create a single texture atlas from these photos.",[15,3115,3116],{},"This allowed me to optimize my lookdev workflow and only require a single material for all variations of grass.",[15,3118,3119],{},[224,3120],{"alt":341,"src":3121},"https://digitalcolony3d.wordpress.com/wp-content/uploads/2019/10/foliageatlas.jpeg?w=1024",[15,3123,3124],{},"Not a glamorous setup but it worked out. All I used was a manila folder to stop any light bleed from creeping in, and a few sheets of white paper to make the tedious process of cutting out the blades as easy as possible. I used my poor, aging Iphone SE to take the photos. Old phone aside, the texture quality holds up surprisingly well.",[15,3126,3127,3130,3133],{},[224,3128],{"alt":341,"src":3129},"https://digitalcolony3d.wordpress.com/wp-content/uploads/2019/10/img_4369.jpg?w=768",[224,3131],{"alt":341,"src":3132},"https://digitalcolony3d.wordpress.com/wp-content/uploads/2019/10/img_4366.jpg?w=768",[224,3134],{"alt":341,"src":3135},"https://digitalcolony3d.wordpress.com/wp-content/uploads/2019/10/img_4364.jpg?w=768",[15,3137,3138],{},"I made sure to take pictures of single blades for the actual modeling and full stalks to really understand how grass grew in nature. The common mistake in making grass is having individual blades grow straight up from the ground. They actually grow in stalks or clumps.",[10,3140,3142],{"id":3141},"modeling-in-maya","Modeling in Maya",[15,3144,3145],{},"After I had the texture atlas at an acceptable point. I went into Maya and used this as my modeling blueprint. I decided to use physical geometry as opposed to flat cards. I did this so I wouldn’t have to worry about over draw and also to give the blades more of a 3-dimensional shape. Cards are great for real-time but since that wasn’t my goal, I figured I could spare the extra polygons.",[15,3147,3148,3151],{},[224,3149],{"alt":341,"src":3150},"https://digitalcolony3d.wordpress.com/wp-content/uploads/2019/10/maya01-1.png?w=933",[224,3152],{"alt":341,"src":3153},"https://digitalcolony3d.wordpress.com/wp-content/uploads/2019/10/maya02-3.png?w=1024",[15,3155,3156],{},"Since I modeled directly from the texture atlas, I could planar project and use this as as my diffuse map. This made the lookdev process almost too easy.",[10,3158,3160],{"id":3159},"natural-scattering-in-houdini","Natural Scattering in Houdini",[15,3162,3163],{},"Now onto the fun stuff. Digging into that node graph. It’s a very simple setup. Basically I have three point cloud setups that represent low grass, medium grass, and high grass. Each of these randomly switch between 2 variations. All of the scale and density is driven by perlin noise and the rotation is completely random.",[15,3165,3166],{},[224,3167],{"alt":341,"src":3168},"https://digitalcolony3d.wordpress.com/wp-content/uploads/2019/10/fullgraph-1.png?w=1024",[15,3170,3171],{},"I’ll try and clearly describe my node graph from the top down. The image will be an overview and the text directly under will be a walk through of the process.",[15,3173,3174],{},[224,3175],{"alt":341,"src":3176},"https://digitalcolony3d.wordpress.com/wp-content/uploads/2019/10/importgrass.png?w=1024",[193,3178,3179,3182,3185,3188,3191,3194,3197],{},[43,3180,3181],{},"Each grass variation is imported one by one",[43,3183,3184],{},"They are then scaled down to match the units in Houdini",[43,3186,3187],{},"Each grass type is assigned it’s own unique group. This will come in handy later when I need to isolate the geometry.",[43,3189,3190],{},"I create an attribute that will later be passed to Katana for the shading process. I will go into more detail on this in the Katana section.",[43,3192,3193],{},"I create an attribute wrangle node that specifies the location of the grass in my scene. I will also explain this in more detail in the USD section.",[43,3195,3196],{},"All of the Grass is merged together. I have to do this because of the way the USD instancer node functions. The instancer node basically assigns a set of attributes to the geometry to allow the point instancer to work properly. If you assign this node to the individual objects one by one, it breaks the instancing and won’t cycle through your objects. Only one will be instanced.",[43,3198,3199],{},"To isolate the grass into separate clumps again, I use a blast node that deletes anything that isn’t in the spcified group.",[15,3201,3202],{},[224,3203],{"alt":341,"src":3204},"https://digitalcolony3d.wordpress.com/wp-content/uploads/2019/10/scatter-1.png?w=901",[193,3206,3207,3210,3213,3216,3219,3222],{},[43,3208,3209],{},"The A and B variations are plugged into a switch node. This is the Geo connected to the copy stamp. This node also has an expression that randomly switches between the variations to be scattered.",[43,3211,3212],{},"I use an attribute noise to control the density of the scatter points, this allows me to use noise to give the grass a natural growth pattern and also use ramps to have more control of the final look.",[43,3214,3215],{},"I use a duplicate of the same noise to control the scale of the grass. This way, the more dense areas will also have taller grass stalks.",[43,3217,3218],{},"I use a VOP Network for random rotation.",[43,3220,3221],{},"These attributes are passed to the points on the terrain",[43,3223,3224],{},"The copy stamp scatters the grass to these points",[15,3226,3227],{},[224,3228],{"alt":341,"src":3229},"https://digitalcolony3d.wordpress.com/wp-content/uploads/2019/10/scatters.png?w=1024",[15,3231,3232],{},"I did the same exact process for all three grass types, just adjusting noise to add variation. Once that’s done, I merge them together and export the result to a grass.usd file.",[35,3234,3236],{"id":3235},"camera-culling","Camera Culling",[15,3238,3239],{},"After initial tests with some truly horrendous render times, I quickly realized that the density of grass required for this scene would call for some serious optimization techniques. I talked to the FX lead at my studio on different ideas and he showed me this handy little technique.",[15,3241,3242,3245],{},[224,3243],{"alt":341,"src":3244},"https://digitalcolony3d.wordpress.com/wp-content/uploads/2019/10/camerafrustrum.png?w=491",[224,3246],{"alt":341,"src":3247},"https://digitalcolony3d.wordpress.com/wp-content/uploads/2019/10/houdini-1.gif?w=480",[15,3249,3250],{},"This setup takes the terrain and creates a group of all points inside of the camera frustum. Anything that is not included in this group, is deleted. This new geometry is then used to scatter points onto. This eliminates the overhead of processing grass that can’t be seen.",[15,3252,3253],{},"The resulting mesh is then exported to a terrain.usd file to be used later.",[10,3255,3257],{"id":3256},"utilizing-usd","Utilizing USD",[15,3259,3260],{},"USD is one of those industry buzzwords that everyone seems to be talking about and for good reason. It’s awesome! It allowed me to export full scene data directly from Houdini into Katana. Instances and all, it just works. Now there are plenty more reasons to adopt this format. You can send full light rigs or even materials between applications without rebuilding any node networks or putting any additional work into it. On top of that, multiple departments can simultaneously and non-destructively work with the same set of data.",[15,3262,3263],{},"Here’s my final shot.usd file open in Pixar’s USD View.",[15,3265,3266],{},[224,3267],{"alt":341,"src":3268},"https://digitalcolony3d.wordpress.com/wp-content/uploads/2019/10/usdshot02.png?w=1024",[15,3270,3271],{},"For the grass field, the only real USD features I used was passing instancing along to Katana and composing my scene.",[15,3273,3274],{},"What do I mean by “composing my scene?” Well USD allows you to layer files together. Think of stacking layers in Photoshop. This is especially great for studios. Imagine each department working on their specific jobs and stacking everything together into one single shot.usd file.",[15,3276,3277],{},[224,3278],{"alt":341,"src":3279},"https://digitalcolony3d.wordpress.com/wp-content/uploads/2019/10/usd.png?w=963",[15,3281,3282],{},"With this layering functionality, I could append my grass and terrain into one single file that could be passed into Katana. Notice that they are both added under the scene_ALL folder.",[15,3284,3285],{},[224,3286],{"alt":341,"src":3287},"https://digitalcolony3d.wordpress.com/wp-content/uploads/2019/10/usdprimpath-1.png?w=1024",[15,3289,3290],{},"A USD file is basically a text document that holds a list of attributes and the scene location is no exception. If you’re using Houdini to compose your scenes, you can simply add an attribute wrangle and change an object’s location in the scene.",[10,3292,3294],{"id":3293},"bringing-it-all-together-in-katana","Bringing it all Together in Katana",[15,3296,3297],{},"My Katana node setup is about as simple as it gets. My scene comes in, I set a few attributes, light the scene, create and assign some materials and finally render it all out to disk.",[15,3299,3300],{},[224,3301],{"alt":341,"src":3302},"https://digitalcolony3d.wordpress.com/wp-content/uploads/2019/10/katanafullgraph.png?w=758",[15,3304,3305],{},"I use a switch node to change my high res scene to a proxy version. This is especially helpful for lighting, when I need quick feedback for light direction/intensity and don’t want to calculate thousands on instances.",[15,3307,3308],{},[224,3309],{"alt":341,"src":3310},"https://digitalcolony3d.wordpress.com/wp-content/uploads/2019/10/switch.png?w=1024",[15,3312,3313],{},"Another workflow I adopted was assigning materials based on attributes.",[15,3315,3316],{},"In Houdini, I assign a string attribute called Material. And the value of this material is foliage.",[15,3318,3319],{},[224,3320],{"alt":341,"src":3321},"https://digitalcolony3d.wordpress.com/wp-content/uploads/2019/10/attributes.png?w=1024",[15,3323,3324],{},"I then use an expression to create a collection. This collection consists of anything in my scene that has the material attribute of foliage. This allows me to go back and add extra plants if needed. As long as I add this attribute to the new plants, the material will be assigned automatically.",[15,3326,3327],{},[224,3328],{"alt":341,"src":3329},"https://digitalcolony3d.wordpress.com/wp-content/uploads/2019/10/collection.png?w=761",[15,3331,3332],{},"All I need to do now is tell the material assign node to apply my grass material to the grass collection I created.",[15,3334,3335],{},[224,3336],{"alt":341,"src":3337},"https://digitalcolony3d.wordpress.com/wp-content/uploads/2019/10/assign.png?w=763",[15,3339,3340],{},"The lighting in the scene is also very simple. A directional light for my Key, a disk light for my bounce, and an hdri for my fill. The values are pretty high so that I can get that bright, “magical” disney lighting style.",[15,3342,3343],{},[224,3344],{"alt":341,"src":3345},"https://digitalcolony3d.wordpress.com/wp-content/uploads/2019/10/gaffer.png?w=761",[15,3347,3348],{},"After tweaking a few render settings, I just render it out, do some minor compositing in Nuke and we’re good to go!",[10,3350,3352],{"id":3351},"final-thoughts-and-resources","Final Thoughts and Resources",[15,3354,3355],{},"All in all I learned a lot during this project. I highly encourage anyone reading this to get comfortable with procedural software packages and read up on USD. These seem to be the direction our industry is heading so it’s best to stay on top of these trends.",[35,3357,3359],{"id":3358},"usd-resources","USD Resources",[40,3361,3362,3365,3368,3371],{},[43,3363,3364],{},"SideFX Explains USD",[43,3366,3367],{},"Pixar USD Website",[43,3369,3370],{},"USD Based Pipeline",[43,3372,3373],{},"USD at Animal Logic Academy",[35,3375,3377],{"id":3376},"houdini-resources","Houdini Resources",[40,3379,3380,3383,3386,3389],{},[43,3381,3382],{},"Camera View Clipping",[43,3384,3385],{},"Building USD for Houdini Linux",[43,3387,3388],{},"Building USD for Houdini Windows",[43,3390,3391],{},"Animal Logic Houdini USD",[35,3393,3395],{"id":3394},"katana-resources","Katana Resources",[40,3397,3398,3401,3404],{},[43,3399,3400],{},"Powerful Look Development in Katana",[43,3402,3403],{},"Geometry Tags in Katana",[43,3405,3406],{},"Intraware Australia",[35,3408,3410],{"id":3409},"artstation-inspiration","Artstation Inspiration",[40,3412,3413,3416,3419,3422,3425],{},[43,3414,3415],{},"Iwo Pilc",[43,3417,3418],{},"Romeo Costa",[43,3420,3421],{},"Greg Zdunek",[43,3423,3424],{},"Mickael Riciotti",[43,3426,3427],{},"Mikel Barron Bilbao",{"title":341,"searchDepth":342,"depth":342,"links":3429},[3430,3431,3432,3433,3436,3437,3438],{"id":3085,"depth":342,"text":3086},{"id":3109,"depth":342,"text":3110},{"id":3141,"depth":342,"text":3142},{"id":3159,"depth":342,"text":3160,"children":3434},[3435],{"id":3235,"depth":348,"text":3236},{"id":3256,"depth":342,"text":3257},{"id":3293,"depth":342,"text":3294},{"id":3351,"depth":342,"text":3352,"children":3439},[3440,3441,3442,3443],{"id":3358,"depth":348,"text":3359},{"id":3376,"depth":348,"text":3377},{"id":3394,"depth":348,"text":3395},{"id":3409,"depth":348,"text":3410},"2025-02-11T05:00:00.000Z","Learn how to create convincing grass while leveraging Houdini, Katana, and USD","/articles/how-to-texture-like-pixar/GrassUSD.png",{"subtitle":3448},"Learn how to scatter natural looking grass with Houdini and leverage Pixars USD format inside of Katana.","/articles/grass-field-usd",{"title":3072,"description":3077},"Articles/grass-field-usd",[3453,1112],"Houdini","j3X1rvnTvjZZ2OQO9D_kGnIrWVuGXx4vyHDrqcbIJkc",1777063455118]