Material Series
Version 1.1, Updated August 2025 using Octane 2025.2.1 and Cinema 4D 2025.3
~5,500 words, average read time: 25 min
About this guide
This is a follow-up to the Introduction to the Texture Projection & UVs guide. It applies the concepts learned in that guide directly to Octane, showing how the engine treats various projections and how to achieve certain effects. This guide was created using the Cinema 4D plugin, but it should be general enough to translate to Standalone or any other plug-in.
1.1 Update: Added Rest Attribute/Position in parts II and III.
Part I
High-level View
Before we get into the practical stuff, let’s get a 30,000 ft (9,144 m) overview of some key concepts that will make our lives easier when dealing with textures in Octane.
UVs are Still King
When applying materials to models, UV mapping (MeshUV Projection) still remains the best way to make sure our textures stay consistent and predictable when we deform, scale, or otherwise alter our models.
The rest of the available projections are useful when doing lookdev and for quickly building out static parts of the scene, but they have a higher chance of falling apart and glitching out once we start trying to scale or animate our models, or reuse them in other scenes.
Octane has a way to bake our final non-UV projected textures into UV-friendly versions which we’ll cover in another guide.
As of Octane 2025.1, the Rest Attribute system gives us another viable approach which we’ll cover here. There is a way to bake our final non- UV projected textures into UV-friendly versions which we’ll cover in another guide.
Per-texture Projection
Texture projection in Octane is done on a per-texture basis, not a per-material one.
This is great, because it gives us the flexibility to mix and match projections within a single material, and then scale, rotate, and move them all independently of each other (and the material itself).
In the example above we have a Universal Material using three textures with different projections: The Albedo channel uses a gradient generator node set to XYZ to UVW projection. Metallic uses a Moire Mosaic (set to Ring) with Spherical projection, and Bump has a Voronoi noise in a Cylindrical projection. When we combine all three, we’re ready for Fashion Week in NYC.
It’s not just a per-channel thing though, we can mix two textures together with different projections and feed that into any number of channels to make even more crazy combos.
Aspect Ratio
Most projections assume a 1:1 aspect ratio for the texture, but can use odd sized ones too. 1:1 is the most efficient aspect ratio for MeshUV because UV tiles are 1:1 - anything else would limit the ability to maximize the usable pixels.
Parallel Projection
Almost all texture projections in Octane are Parallel. This means:
Parallel lines will stay parallel regardless of how the texture or projector is rotated in 3D space
The texture won’t grow or shrink based on the distance from the projector to the model - it will stay at the same size regardless of where in space the projector is located. If we want the texture larger or smaller, we need to transform it rather than move the projector.
Most of the time parallel projection is what we want, because we’d rather rely on our scene camera to provide the perspective of all the objects and textures for it to look realistic. If a single texture is using a different vantage point for its perspective, it’s going to look really weird and distorted.
For more info on Parallel projection, check out this guide.
Texture Spaces
The default coordinate space for non-MeshUV projections (XYZ to UVW, Box, Cylindrical, etc) is Object Space. This uses the object’s axis as the center point of the texture. If we move the object around in space or rotate it, the axis goes with it, and the texture appears to stick to the model.
We also have the option of switching to World Space, which uses the global coordinate system. This pins the center point of the texture to world 0, and then as we move the objects through space, they only pick up the part of the texture they’re overlapping. Most of the time this isn’t super useful unless we’re trying to do something like map a single texture to a big conglomerate of objects.
MeshUV operates in a UV coordinate space that exists outside of the scene or model’s coordinates.
The mesh of the object is “unwrapped” and the polygons are laid out flat in a 1x1 square. The texture then overlays that square, and then whatever portion of the texture overlaps a polygon on the flat map also overlaps it on the 3D model.
This means that regardless of how the model is sized or moved in space, or however we move the object’s axis around, the texture always sticks to it properly.
More on that in the Intro to Texture Projections & UVs guide.
Object Axis
Non-MeshUV projections using the Object Space coordinate system rely on the location of the object’s axis to know where to start the texture tile. If this isn't in a logical place, we’re going to end up with weird and unexpected results.
The scene above uses a texture set to Spherical projection and Object Space. We can clearly see what happens when we move the object’s axis. This can be adjusted in the material as well, but it’s often easier to solve alignment problems by simply centering the object’s axis.
2D vs 3D textures
Octane supports both 2D and 3D textures.
Working with 3D textures can cause a lot of confusion, so it’s good to know which type we’re dealing with.
Bitmap textures are always 2D. Generated textures can be 2D or 3D.
The best way to test this is to drop a default cube into the scene, add a material to it, put the texture in a material and set the projection to XYZ to UVW. If the sides of the cube repeat the pixels back in space, it’s 2D. If more of the texture is generated on the side, it’s 3D.
A list of texture nodes (as of Octane 2025.2) and whether they’re 2D or 3D can be found here.
If we have a 3D texture and would like it to behave like a 2D texture, we can use the Baking Texture node. This takes the output of a generator and bakes it into a flat 2D texture prior to applying it.
One fun thing we can do with 3D textures is animate the W coordinate (T.Z) - with generated 3D textures like Marble, and Noise, the texture actually looks like it’s animating as it shows different 2d slices of the texture in sequence.
Bitmap vs Generated textures
Octane can import external bitmap textures, and also has a whole host of nodes that generate texture data. Bitmap textures are pngs, jpegs, gifs, mp4s, etc. They live on our hard drives and, and they’re run through an Image Texture node in Octane for best results.
Generated (procedural) textures are built on the fly using special texture generator nodes. A list of somewhat recent generated textures can be found in this guide.
The Scaling Problem
As we learned in the last guide, non-MeshUV projections are not aware of the model’s size. This means that textures project at a default size, and they can’t grow or shrink appropriately when we scale the model.
Different texture types behave differently when the scale doesn’t match the model’s size. Bitmap textures repeat by default (though we can change that behavior), and generated textures just generate more texture as the model grows, which also ends up looking weird when animating.
The best way to resolve this if we’re going to be animating the scale of our models is to bake any non-MeshUV projections down to MeshUV. A hacky workaround is to try to animate the scale of the texture to match.
There are now two ways around this: The Rest Attribute system is the easy way, and baking the textures to UV-friendly versions which is a more laborious way (but more compatible if we need to export for use in other apps).
Projection Mechanics
(my new band name)
XYZ to UVW, Box & Triplanar Projection
XYZ to UVW projection uses the X, Y, and Z axes of the object (or less commonly the world) to map the U, V, and W coordinates of the texture. This makes it the best projection for interacting with the W coordinate data of a 3D texture (all the stuff behind the main UV plane). As we can see above with a 2D texture, the edge pixels repeat back along the W coordinate (Z), while a 3D texture keeps generating more stuff to cover the model as it goes back into space.
Box and Triplanar both use six different projectors set 90 degrees to one another, each of which has a UVW coordinate set. This means regardless of whether it’s a 2D or 3D texture, we’ll mostly be seeing the U and V coordinate data, and rarely interact with or see W coordinate data.
Box uses the same texture on all six sides, Triplanar can use different ones on different sides. In these projections, W goes in toward the middle of the model, so we can get different patterns (different 2D slices of the 3D data) by moving a 3D texture on W (T.Z transform setting). Doing this with a 2D texture doesn’t do anything because the data just keeps repeating, so every slice looks the same.
Default Size - XYZ to UVW, Box, Triplanar
In Cinema 4D, the default size for XYZ to UVW, Box, and Triplanar projection is 200cm x 200cm x 200cm. This matches the default C4D cube size, but not the default plane size, which is 400x400.
If we drop a default plane into a scene and set the orientation to -Z so it’s upright and facing front, and use XYZ to UVW, Box, or Triplanar projection on a texture applied to it, it tiles as shown in panel 1 above.
If we reduce the size of the plane to 200x200 cm, the texture will fit perfectly since it matches the projection size. If we reduce it more (say 100x100 like in panel 3), it will start clipping because the texture is still projecting away at 200x200 and is not aware of the geometry. So to get around that, we’d have to reduce the size of the texture by scaling it to match - S.X & S.Y = 0.5 in this case - which brings the texture size to 100x100 cm to match.
Spherical & Cylindrical Projection
Both Spherical and Cylindrical projection were originally meant to map a flat image to a sphere, and they share some similarities, but also some key differences.
If we imagine a classic globe, the U coordinate maps to the latitude lines (red in the diagram above). The V coordinate maps to the longitude lines (green lines), and the W coordinate starts at the center of the model and moves out from there. Because it’s a 2D sheet wrapped around the model in both cases, we don’t interact with the W coordinate much.
These projections always produce a seam where the two vertical edges of the texture meet, and pinch points at the top and bottom where the top and bottom edges fuse to a single point.
While they both wrap around a model the same way, they’re still very different at the core. Spherical projection projects completely around the object from all angles, while cylindrical only projects around the sides.
Distortion
Cylindrical projection keeps the horizontal (U) lines equidistant from one another. This means that we can apply an undistorted image to an object using Cylindrical projection and it won’t go all wonky.
Spherical projection starts with the lines tight together along the equator but then they get further and further away as they get close to the poles. This works better with images captured or created with a spherical camera (when mapped on or in a sphere), but isn’t super useful for undistorted textures as we can see above.
Images meant for Spherical projection are mostly found as environment maps (HDRIs) and are meant to be projected inside a large sphere (an environmental light). Textures created to go on the outside of a sphere are much less common and are typically only found as planetary maps. The third main use for this is IES lights.
Default Size - Cylindrical & Spherical
Cylindrical projection has a default V dimension, but not a default U dimension.
This can get really confusing, but if we think through what the projector itself looks like (or how we visualize it anyway), it starts to make sense. The projection cylinder is infinitely tall, but doesn’t have a top or bottom. As a result, it doesn’t need a set U dimension - it just sort of shrink wraps around the model in that direction. It does need a V dimension though because we need some way of telling it where the “top” and “bottom” of the texture is before it starts clipping or repeating.
The default size for Cylindrical projection in C4D is 200 cm tall (V direction). Once we establish the height, we just need to squash or stretch the texture to appear correctly.
Spherical projection, on the other hand, shrink wraps the whole texture because it’s projecting in (or out) at all angles. This means there’s no default size, but the texture distorts if it’s not purpose-built for the projection.
Part II
Practical Stuff
Projection & Transform Nodes
Just about all Octane texture nodes have two input pins: One for a Projection node and one for a Transform node.
In Octane Standalone, there are multiple individual projection and transform nodes that can hook into these pins. The C4D plugin (and probably others), has one single Projection and one single Transform that plug into their respective ports. From there, we can choose which projection or transform type we want from dropdown menus.
One projection or transform node can drive multiple textures, which is pretty handy (and a good reason to use the node editor in C4D).
If no external Projection node is hooked up, Octane assumes MeshUV
projection most of the time (some textures are set to XYZ to UVW - this
spreadsheet notes which). If no external Transform node is hooked up, Octane assumes the texture will be at the default size and orientation set by that particular DCC’s plugin. (C4D is 200x200x200 cm for most projections, for instance).
Clipping, Tiling, & Border Mode
Before we start messing with the PSR values, we need to understand what’s going to happen to the texture when transforming it.
If our texture is generated like Noise, Woodgrain, Checkerboard, Tripper, etc, Octane will just generate more of the texture to fill the dead space when we scale it down. Depending on how the generator is coded, this could mean tiling, expanding, or just making more random stuff. Checks, for instance, will make more checkerboard pattern, Tripper will make more… uh… whatever acid-fueled thing it’s doing (seen above).
Bitmap textures are another story. There’s no “generating more of a texture” when we have a baked pixel grid. For now, we have to tell Octane what to do when it runs out of pixels.
The Border mode (U) and Border mode (V) options in the Image Texture (and Baking Texture) node allow us to specify what happens when we run out of pixels in the U and V directions independently.
Wrap Around is the default behavior - it just tiles the image indefinitely. This is great for seamless textures.
Black color or white color are good for compositing (think decals). There’s no “transparent”, so we need to use a blend mode to swap out the black or white similar to greenscreening or color keying.
Mirror can be helpful for quickly hiding tiling seams for things like noise or earth textures, but the Chaos node does a bit better job of this.
Clamp value repeats the edge pixels indefinitely and is good in certain circumstances where we don’t want to have to be super accurate in sizing a texture or object.
Since we can choose what happens on U and V independently, we can mix and match as well - say clamp value on U, but mirror on V.
Transforming textures
Transforming is the blanket term for altering the position (“translation” in Octane), scale, and rotation of the texture. Octane has two places where we can set transformations:
There’s an external Transform node which we saw at the top of this section that plugs into a texture’s Transform pin.
Most non-MeshUV projections have an Internal Transform section that has all the same controls, but works a bit differently.
Important: These controls will only show up with certain projections (XYZ to UVW, Cylindrical, Spherical, Box, Perspective, Instance Position).
Transform Node Controls
Both the internal and external transform areas have three sets of controls that we’re all too familiar with being 3D artists.
“Rotation” and “Scale” are terms we’ve come across countless times. The term “Translation” (The T where we were expecting P) might be new to some of us, though. It’s very close to what we know as Position, only it takes into account texture space (so T.X moves the texture along the curvy U axis in the illustration above, not along the straight world or object X axis). For our purposes, it’s probably just easier to think about it as Position.
Rotation works in degrees. That makes sense.
Scale works in float values (percentages). A scale value of 1 means the texture is at its default size (1 = 100%). The default size varies depending on the projection and DCC, but in C4D it’s generally 200 x 200cm x 200cm in non-MeshUV projections. If we change it to 0.5, it’s 50% of default. 2.4 means it’s 240% of default.
Translation also works in float values. A translation of 0 means the texture is in its default location in UVW space. Translation of 0.5 means it slides the texture half of its width (or height or depth depending on which axis we’re talking about). It can also go higher than 1, and depending on the border mode, this means it either keeps repeating indefinitely or the texture slides right off the geometry.
External vs. Internal Transforms
Important: The behavior of internal and external transforms rely on which projection we choose and whether our texture is 2D or 3D. They both operate a little differently to one another, especially when it comes to rotation.
Transforms with 2D Textures
If we go back to our trusty physical projector visualization construct, let’s envision a transparent piece of film over the lens that has our 2D texture on it. When the projector shines light through it, it projects it on our model.
The external Transform node affects our piece of film directly in this analogy. We can slide the film around in front of the lens (T.X and T.Y). We can also stretch or squash it along two axes (S.X and S.Y), and rotate it along one axis (R.Z). When we do this, the projected image shifts, rotates, grows and shrinks to match.
The film holder is fixed to the front of the projector, so we can’t move it (T.Z) or tilt it (R.X or R.Y) toward or away from the lens . It’s also a 2D piece of film, so we can’t stretch the thickness of it (S.Z).
Important This is a long way of saying The R.X, R.Y, T.Z, and S.Z controls in the external transform node do not do anything when attached to a 2D texture.
The internal transform controls in the Projection node changes the orientation of the whole projector in space relative to the model.
In our analogy here, we can move the projector along the U and V axes (T.X and T.Y), and it is pretty much the same thing as moving the film along those same axes in our external projection node.
It’s Hank Pym’s projector, so we can make the whole projector larger or smaller (S.X and S.Y) and it does the same thing as stretching or squashing the film.
Rotation is where we see the biggest difference. In the internal transform controls, we can tilt the whole projector on all three axes (R.X, R.Y, and R.Z) and also move it closer and further away from the object (T.Z), though the projector will need to be rotated on R.X and/or R.Y to see any effects from T.Z with a 2D texture
Where things get really squirrelly here is that our projector is parallel, and our texture - even though it’s 2D - actually repeats out indefinitely in the third dimension. This combo makes it really difficult to predict what’s going to happen, especially when the rotation angles get too high and when we’re using any projection aside from XYZ to UVW.
Important: Unless we’re after some weird abstract effect or really know what we’re doing, we usually want to stay away from the internal transform and just use the external transform node for our 2D textures.
Transforms with 3D Textures
Hopefully this analogy will hold together here…
Our super futuristic sci-fi projector can actually project 3D textures too. Instead of a piece of film bolted on to the front of the lens, a 3D texture would be more like placing a floating solid cube in front of the projector which magically projects a whole matrix of these cubes.
There isn’t much of a difference between internal and external transforms with 3D textures.
Rotation Order
The XYZ (UVW) values in Translation and Scale are independent of each other. If we move a texture up on V 0.5 and the over on U 0.5, it’s the same as if we first moved it over on U 0.5 and then up on V 0.5.
Rotation values are linked together and play off each other. Rotating something on X first, then on Y, then on Z gives different results than rotating it first on Y, then on Z, then on X.
We can see here that even though the X, Y, and Z values are the same on each globe, the rotation order puts them all in very different orientations even though the R.X, R.Y, and R.Z values are exactly the same.
Both the Internal Transform section and the external Transform node is set to the Transform Value type by default. This type of Transform node is set to the YXZ rotation order and can’t be changed. If we switch it to the 3D Transformation type, we’re given a dropdown that we can choose from.
Important: The R.X and R.Y values still don’t work on 2D textures even if we switch transform types, but this does allow us to change the rotation order on 3D textures if we want.
Why would we want to change the rotation order? Let’s say we’re animating something like an eyeball texture and we want to control where it’s looking. If we have the wrong rotation order, it’s going to be a massive pain to target a point in space, but if we switch it to something that makes more sense (maybe XYZ instead of YXZ), it may be easier to control.
The UVW Transform Node
This is a separate node that comes after the texture node that also allows us to further transform the position, scale, and rotation of any texture piped into it. This is useful if we’re making a complex texture with different projections or transforms and just want to nudge the whole thing over or rotate it.
Important: This node is also necessary if we’re doing any kind of modification to an HDRI (like color correcting it or distorting it). The UVW Transform node must be the last node in the chain prior to going into the Environment tag, or the built-in commands to rotate it on X or Y will break.
Rest Attribute
The new (to 2025.1) Rest Attribute system is a way to quickly generate a UV- like map out of the model’s vertices (ignoring its real UV layout) so textures stick to the model when it deforms or scales.A workflow for how to set this up in C4D is in the next section of this guide.
A few caveats:
- Important: This isn’t a perfect replacement for getting the UVs right and baking proper textures, especially in a pipeline/production situation. It’s an “oh #$%@, the client needs some quick renders by 3pm” or “I’m a solo artist that doesn’t share source files and if it looks good it is good” type of solution.
- It should be the LAST step of the process prior to animation or final tweaky placement of the objects. Any kind of modeling/altering of the object (putting it in an SDS, etc) can break it
- If the model is already altered after the rest position has been set, and we remove the cached state (delete the tag), the texture will re-project and it will look different than it was when we re-set the state. Getting the texture back the way we had it means scaling the model back to its original size (if we can remember what that size was) or adjusting the Transform values of the texture to try to match it. Neither are particularly fun, so we should plan ahead or keep backup copies.
Part III
Setup Walkthrough & Special Projections
Triplanar Projection Setup
Triplanar projection is an enhanced version of Box projection. That means there are six projectors aimed at the model (left, right, front, back, top, bottom). Unlike Box, we have the ability to set a different texture on each projector and also blend them together. This whole construct is known as a “blend cube”.
For Triplanar projection to work, we need a projection node attached to each texture we’re using that’s set to “Triplanar”, and also a dedicated Triplanar node that determines which texture goes where and how the blending works.
Simple setup:
Attach a Projection node to a texture and set the Projection type to Triplanar
Create a Triplanar node and drop it between the texture and the material
Mess with the Blend Angle until the edges blend together nicely
Advanced Setup:
In the Triplanar node, uncheck “Single Texture”
Connect different textures to different sides. +Y is the “top”, -Y is the “bottom, +X is the “left”, etc. One texture can feed several sides (as seen above).
Optional: Add a Transform node to the Triplanar node - this modifies the blend cube itself.
When we modify the blend cube with a Transform node, the T (translate) and S (scale) values work the same way they do in Box projection - each texture will scale up or down, and move along U and V (and W if it’s a 3D texture).
Rotation is where things get interesting - this rotates the entire blend cube around the model’s axis, so all of the textures seem to slide around on the model and the blending changes based on the blend angle we set.
Important: The blend cube affects all textures equally: If we need to translate, rotate, or scale an individual texture, then we need to hook up a different Transform node to that texture’s node and rotate it prior to feeding into the Triplanar node.
Rest Position Workflow
Rest position lets us build an on-the-fly pseudo UV map so our textures can scale and deform with our models.
- Hook up a Projection node to each texture that needs to “stick”. One Projection node can drive multiple textures and it’ll still work fine.
- Set the Projection node to anything other than MeshUV (no need for this if we were using MeshUV projection).
- Get the texture at the right scale, position, etc. using the a Transform node.
- Important: Check the “use rest attribute” box in the Projection node for each texture we want to be affected.
- Add an Octane Rest Position tag (Tags>Extensions>OctaneRender…>Octane Rest Position Tag, or hit shift-C to search for “Rest Pos”) to any object that has the texture on it.
- In the Octane Rest Position tag, click “Store rest position”. The tag icon will change from yellow to green showing that it’s caching data.
- Scale or deform the object to test that it works.
Setting up Perspective Projection for Camera Mapping
Perspective projection is the only projection type in Octane that is not parallel right out of the box (OSL can probably be made to do this too). What this means is that when the projection is rotated, it distorts and foreshortens.
Let’s try to understand this a bit better with a camera mapping setup. We’ll need a few things to get started:
An object or set of objects we’re going to be projecting on. The default size of perspective projection textures is complicated, so we’re going to have to wing it with a Transform node.
A different object that is going to do the projecting - an Octane Camera works really well for this because we can look through it to see what we’re doing. This isn’t strictly necessary - we can use the Projection Node’s internal controls to try to do the positioning and rotation manually, but that’s very tedious and difficult.
A material with a texture in it
Open the material we’re going to put on our target object, find the texture(s) we want to apply the projection to and create a Projection node attached to the projection pin. Let’s set this to “Perspective”
Important: Set the Coordinate space to World Space, otherwise this is going to get really confusing really fast as the textures are calculated with each object’s axis taken into consideration
Drag the source object we created (probably a camera) into the unlabeled field under External Transform.
Important: Flip S.Z by setting it to -1 in the Internal Transform section As of this writing (Octane 2025.1), parallel projection in Octane for C4D flips the Z axis. In order to make sense of what we’re seeing, we need to flip it back.
Look through the projector camera (click the reticle [+] next to the camera).
Create an external transform node and pipe it into the Transform pin of the texture. Use that to scale the texture to the right size. We could have done this in the internal transform section of the Projection node as well, but we already scaled it to -1 on Z so it’s more annoying to do it that way.
Now as we move the camera around, the texture follows the camera object. If we look through a different camera, it looks all crazy distorted.
Special Projections
These are ones that Octane can do that we probably won’t run into on a daily basis. Sample Position to UVW (used for Global Texture AOVs), Instance Position (used for particles and cloner systems), and OSL/Delayed OSL (used for… wait for it.. OSL) are all well and truly out of the scope for this guide and may be covered in future, more advanced guides.
Matcap Projection
Matcaps above were sourced from https://github.com/nidorx/matcaps
Matcaps (Material Captures) use an image of a rendered sphere as a reference for creating a fake material of sorts. It uses the normals of the mesh to determine where on the matcap image to pull from. The rendered sphere also gives the engine hints about the lighting and reflections.
This is kind of a cheat that allows for very fast application and rendering of complex-looking materials in realtime engines or in tasks like sculpting where speed is far more important than realism while building a model. Since matcaps have lighting built-in, they can clash with the scene lighting and look out of place, so it’s best suited for single model lookdev.
If we’re using matcaps, we want to use matcap projection to make sure it works properly. We also need to make sure all our normals are aligned and facing outward (which we should always do anyway, but it’s especially important here).
Color to UVW & Distorted Mesh UV Projections
These allow us to distort the UVs of a texture by using a second texture.
Being able to predict what Color to UVW is going to do is difficult, so this is just an exercise in “I want some cool unique texture on my thing so I’m just to mash buttons and feed in different textures until I see something I like”.
Distorted Mesh UV is a lot more predictable because there are more controls at our disposal. We can limit the distortion to position, scale, and rotation, and we even can go more granular with x and y coordinates.
Important: as of this writing, the sliders in this section are a bit off. Rotation, for instance, is on a 0-1 scale, but since it’s degrees, this means it ranges between 0 and 1 degree (instead of 0 and 360). When experimenting, try going outside the range of the sliders.
Wrap Up
If you made it through this guide, you should have a pretty good understanding of how texture projection in Octane works.
Author Notes
OG049 Projection and UVs in Octane Version 1.0 Updated Aug 2025 using Octane 2025.2.1 and Cinema 4D 2025.3.2
This guide originally appeared on https://be.net/scottbenson and https://help.otoy.com/hc/en-us/categories/201718003-OctaneRender-Support-Guides
All rights reserved.
The written guide may be distributed freely and can be used for personal or professional training, but not modified or sold. The assets distributed within this guide are either generated specifically for this guide and released as CC0, or sourced from CC0 sites unless otherwise noted and attributed.