4/12/24, 1:15 PM Intro to Houdini Intro to Houdini Intro to Houdini Basics Proceduralism Structure Interface Creating an object Create a geometry object from scratch Hotkeys Animation Display Options Geometry in Houdini Attributes Ideal Houdini Workflow Importing Workflow Alembic Velocity Orientation SOPs - Surface Operators POPs - Particle Operators POP Network Source POP Force Attractor Collision Drag Property Color Controlling collisions Advect By Volumes Kill Blending the sourcing of particles Metaballs DOPs - Dynamic Operators Structure of a DOP network https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 1/86 4/12/24, 1:15 PM Intro to Houdini Intro to Houdini Objects Attaching data Solvers DOP Import Affectors and relationships Errors Volumes Standard Houdini Volumes OpenVDB Volumes Common VEX code VOPs - VEX Operators Common nodes VOPs Examples Normalizing Normals Normalizing Normals + Adding Random Length Mixing Normals Adding Noise to a surface Rotating a noise by another noise Using noise to determine which points emit and which don't Creating the Particle Scale control Controlling attributes through a ramp Rotating the N or up with a matrix ROPs - Render Operators Rendering Optimized Rendering Generating IFDs Mantra Procedurals Delayed Load Procedurals (Obsoleted by Disk Packed Primitives) Creating Delayed Load Procedurals Alembic Geometry Procedural Animated Geometry Packed Primitives Deep Holdouts (DSM) Other Optimizations Dicing Optimizations Per Object Properties Optimizing Volumes Reducing Noise Mantra workflow Lighting Pipeline Caching Dicing https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 2/86 4/12/24, 1:15 PM Intro to Houdini Rendering Particles Render Layers Intro to Houdini Object Masks Motion Blur Motion Vector pass WorldP pass Ambient Occlusion UV pass SHOPs - Shading Operators Basics Shaders Structure of a material Output collect Layers Compute Lighting Displacement Output Displacement Bounds Surface Output Principled Shader Global Variables Surface Color Layering textures Displacement Texture Texture Displace Displace Along Normals Combining Normal maps UV and ST utan and vtan Setting vector space matrix Rest Position Parameters / Bind Ramp Parameter Color Correction Understanding noise & expression parameters Useful Expressions Errors Examples Scattering points Particle Normals Particle Rotation Particle Pscale https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 3/86 4/12/24, 1:15 PM Intro to Houdini Intro to Houdini Blood splatter Ground Crack Procedural brick wall Sparks Bullet hitting a wall and pieces coming off Vortex Effect Dissolve Effect Unsorted Creating a procedural forest Particles: Forming a teapot Hard surface modeling Wall fracture Particles and Explosions Dust and Smoke Fluid emitting source Rigging objects for DOPs Packed Primitives Constraints (Spring) Glue Constraint Pin Constraint .rat files HDR’s in Houdini Cloth Simulation Common Expressions Expression variables Basics Proceduralism ● A step by step process to achieve a final result (like a recipe or instructions) ○ You create steps - each with a specific operation - each is called OPERATOR. ○ Each operator is a node. ○ A series of operators will give you the final result. ○ The order of the operators matters, changing them changes the final result Structure ● Directory structure - Directories are called CONTEXT. ○ There are several contexts like Object, particle, dynamics, shader, etc. ■ SOPs - Surface Operators ■ POPs - Particle Operators https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 4/86 4/12/24, 1:15 PM Intro to Houdini Intro to Houdini ■ DOPs - Dynamics Operators ■ VOPs - Vector Expression Operators ■ ROPs - Render Operators ■ CHOPs - Channel Operators ■ SHOPs - Shading Operators ○ To create geometry, you create an Object context, and inside a Geometry object. ○ Within the Geometry object, you can create operators. ○ Contexts are interconnected, you can go from Object to Shading. ○ Each node has a path, like: /obj/MyObject/Sphere The directory structure looks like this: Houdini (Root) Object (Context) Geometry (Object) Sphere (Operator) Edit (Operator) Transform (Operator) Create Attributes (Operator) Displace (Operator) Interface ● 3 main panels ○ 3D Viewport ○ Network editor (lower right) - Where you create objects & operators ○ Parameter editor (top right) - The parameters of the objects & operators ○ At the top of each panel it says in what level you are, like OBJ for example. ● Viewport ○ Top corner of the viewport shows what view we are seeing - click to change ○ No Cam - Click and select a physical camera or drag camera operator into view ○ Top right corner - the button with 2 shapes = change display settings for objects ● Parameter editor ○ Sets the settings for the operators ○ Middle mouse click and hold on the labels and hover over the ladder, then move left or right to move all of the values ○ The same on top of a box to only affect that box value ● Network editor ○ The 2 grey boxes on top of the icons are the input and outputs. The top one is the input, and the bottom one the output. You can click on one output and then the input of another operator. ○ Always change the display flag to see what each operator does. ○ Use the bypass to hide one of the operators in the network ○ To disconnect, left click input and click outside https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 5/86 4/12/24, 1:15 PM Intro to Houdini ○ If red hashes appear, it’s because the nothing is being inputted into the operator, so nothing is being displayed. Intro to Houdini ● Object icon ○ Blue flag = the display - turns on/off display ○ Pink Flag = Template object ■ Ctrl + click the template flag to make it template but also shaded! Footprint flag. ○ Green flag = freeze object ● Operator icon ○ 4 flags ○ The blue one is the same ○ Pink flag = template/ghost image of the operation ○ Red flag = Locks the node of the operator ○ Yellow flag = Bypass - it ignores the operator but doesn’t delete it. ● ○ 1 - Select Geometry, lights, cameras, particles, etc. ○ 2 - Selects within an object: points, edges, primitives, vertex, etc. ○ 3 - Select tool (S) ○ 4 - Manipulation tool, have it on to perform operations, like extrude, paint, etc. ○ 5 - Allows you to switch between Context or Object Level. If it’s in Object Level, all new objects will be created in different Geometry nodes, meaning they will be different objects. If Context is selected, the objects will be created inside the same Geometry container. ○ 6 - Turn grid on or off ○ 7 - Toggle point visibility ○ 8 - Toggle point numbers https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 6/86 4/12/24, 1:15 PM Intro to Houdini Intro to Houdini ○ 9 - Toggle primitive numbers Creating an object ● Network editor -> TAB key ○ Left click twice to lay it down ○ A geometry object is created ○ If opened, the operator node appears. ○ Every OBJECT is a container, if you go inside the container, you see all the operators (nodes). ● Using the shelf ○ Click on the Sphere and a bounding box will appear, it moves only in X and Z, to move it on Y hold down. Press Enter to snap it to the middle. ○ Hold Ctrl + click on the shelf button to create the object in the Origin. Create a geometry object from scratch ● TAB -> Geometry -> Geometry ○ Delete the file01 node ○ TAB -> choose a new operator, like sphere ○ Set settings on the parameter editor ○ Change from primitive to polygon ○ Frequency = resolution ● Adding another operator ○ TAB again, choose a new operator ○ Connect both nodes Hotkeys ● ESC = Go back to view mode and stop using the tool ● W = Wireframe mode ● Spacebar + ○ G = Zoom on selection ○ H = Zoom extent all ○ 1 = Perspective view ○ 2 = Top view ○ 3 = Front view ○ 4 = Right view ○ 5 = UVs ● Q = repeat operation ● D = display settings ● T = Translate Tool ● E = Scale Tool ● R = Rotate Tool ● S = Select Tool https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 7/86 4/12/24, 1:15 PM Intro to Houdini ● 2 = Point mode ● 3 = Edge Mode Intro to Houdini ● 4 = Primitive Mode ● 5 = Vertices ● 0 = Toggle Selected Connected Geometry ● Alt + B = Maximise window ● Shift + Click = Add point to curve ● Operators hotkeys ○ Enter/ i / double click = See all operators inside object ○ U = Go back up to object level Animation ● Hold down Alt and click on the field to set a keyframe. ● Procedural animation ○ sin($F*6) ○ $F means frame number ○ sin, oscillates between negative and positive Display Options ● You can create custom displays to visualize different attributes. Select the type (Generic, Text or Vector) and set the attribute to the one you want to visualize. Geometry in Houdini ● Points ○ They are simply a vector. They have 3 coordinates, X, Y and Z. ■ A vector is a direction from a point: X, Y, Z ■ It also has a magnitude ● Think of it as: the direction to where I am going and how fast I am going. ○ They have no geometry or surface ● Primitives ○ Equation for a surface ○ Houdini works with any kind of geometry, it doesn't have to be a polygon, it can be a primitive or a point. ● Vertex ○ The vertex has no position in space (you can check in the details view, there is no P attribute) ○ Their only attribute is what points they are attached to. ○ UVs are stored in the vertices. ○ In a typical geometry, 1 point will have 4 vertices, 1 coming from every surrounding polygon. ● Voxel ○ Similar to pixels. Pixels are 2D and they are represented by squares. Voxels are 3D, so like 3D pixels, and instead of a grid of 2D data, they are a 3D grid. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 8/86 4/12/24, 1:15 PM Intro to Houdini ○ Each voxel has a density (transparency). If you zoom in a lot, you won't see a hard line like in pixels because Voxels are points and they interpolate and blend. The whole bounding box that contains Intro to Houdini Voxels is filled with voxels, but only the ones that represent the geometry have density, so the space which seems empty actually has voxels but they don't have any density (like pixels with 0 alpha). ● Details ○ They aren't geometry, they only store 1 parameter per attribute. Attributes ● Attributes can be a floating point, a vector, an integer or a string. ○ Floating point: number with a decimal value like 1.3 ○ Vector: direction in X, Y, Z ○ Integer: Full number with no decimals, so 1, 2, 3. ○ String: Series of characters (they are enclosed in quotes) ● They can be stored in Points, Vertices, Primitives and Details. ● When you create an attribute, you also have a Local Variable that you can use, which you can call with the $ and typing your attribute in capital letters. ○ Note that when you are inside POPs and make your attribute, it won't create a Local Variable, you have to do it yourself! Just click on Create Attribute and call it the same name, but remember to turn off Write Values! Ideal Houdini Workflow ● The main advantage of Houdini over other softwares is the proceduralism. The idea is that you can load any geometry or animation into your scene and have a procedural system where you can connect and change the input whenever you want and it will still work. ● Always try to work procedurally, so if you can avoid the Edit SOP, Paint SOP, and any other node that would need to be re done if the input geometry changed. ● Try to do as much work as you can in SOPs! Try to control most of your particles and dynamics simulations from SOPs by feeding those contexts with attributes that you created in SOPs. ● Always check for the scale in Houdini, if the scale is not real, forces like gravity and the simulations will act differently. Create a box of 1 in every dimension (that represents a meter, Houdini should be in meters), and make sure your scene is set to scale. Then you can scale out the output. ● Work in different Geometry nodes and try to keep it clean and separated. Use Object Merges to move things from one Geo container to another. ● Have your effect in a different Geometry node also! Just Object Merge the things the objects that you have modified and need from different nodes. ● Work step by step. Focus on the most important parts of your shot, and do one effect at a time. ● Break down the effect, and really work on each part isolated. So if you have a gun shooting at a wall and pieces coming off, first do a system for the bullets. Then make a simple emitter from a shape like a circle https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 9/86 4/12/24, 1:15 PM Intro to Houdini emitting the pieces. Then make a system for the dents of the wall. When everything works, you can start connecting it. Intro to Houdini ● Use Nulls at the end the stream and write it in capital letters so its easier to find when importing in somewhere else. ● Remember that the main focus is MOTION, after you have created your systems, you will have to work several days just tweaking parameters to get the sims to look natural. Importing Workflow ● When importing geometry use the file node and use OBJs. ● When importing animation use Alembic files (Alembic node), also for the cameras. ○ Alembic files are packed by default, so remember to convert it to polygons. ○ Cameras have a default resolution, remember to change it. ● Dont change the file that is being imported. Only add a Null and turn all the flags off. ● Create a Geometry node and do an Object Merge to bring in that geometry. Start to modify it in that node. This way you always keep the original one and you can change it whenever you want. ○ Set the Object Merge to Transform Into This Object to get the transformations of the object from object level. ● Connect all imported geo into a Null and control the scale from there. Alembic ● Houdini supports demand-loading Alembic data, meaning that it can display geometry without storing a copy in memory, and Mantra can stream geometry instead of loading it all into RAM. ○ When working with heavy geometry, you can load only part of the Alembic at a time. ● Alembic can be imported with the Alembic SOP or the Alembic Archive object. ○ Alembic SOP ■ Will load the entire scene into a single piece of geometry ■ Slower for loading animated geometry since the geometry must be deformed, rather than loading new object transforms. ○ Alembic Archive ■ Will create an object level hierarchy representing the Alembic scene. ■ Will provide faster playback for animated geometry since animated object will only be updated on frame changes. ● Alembic geometry can be loaded as demand-loaded Alembic primitive or actual Houdini geometry. ○ Alembic primitive uses very little memory and can be transformed, but the geometry can’t be edited. ○ Loading as Houdini geometry lets you move points but uses more memory. Velocity ● The velocity is a vector. It has 3 components: X, Y, Z. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 10/86 4/12/24, 1:15 PM Intro to Houdini ● You can calculate the velocity of an object with the Trail SOP. ● Velocity isn't the same as speed, but you can calculate the speed based on the velocity. Intro to Houdini ● length($VX, $VY, $VZ) ○ Will return the speed of a point. Orientation ● The normals determine the direction where it faces and the up vector will determine in which way the object will point up. ● The normals are a vector, they have direction and magnitude. The way they point is the orientation of the object. ● To make the normals have an outward direction, set them to TX, TY and TZ. The way the normal is calculated is that “an imaginary line” is drawn from the origin to the coordinates of each point. The direction of that point is the direction of the normals. ● To make the normals of an object point in the direction of another one, you have to subtract them. ● TX2 - TX (point sop) will make the normals point at the direction of each object. Subtracting 2 vectors will give the direction between them. ● Houdini uses the Z axis when copying, so if you copy something and its facing another way, its because the object wasn't facing in the Z direction. When copying geometry onto points, Houdini looks for a point normal to determine in which position the copied geometry will face. Once it has the point normal, it sets a local axis, which is always the Z axis. ○ It will match the direction of the Z axis with the direction of the normal. ● Normalization means making all the directions the same magnitude(or normalizing values between 0 and 1 for floats). It will make the normal length 1. ● Houdini uses the cross product function to calculate the normals based on the vectors of the points that make a primitive. ○ The cross product needs 2 vectors and it creates a third vector that will be perpendicular to the first 2 vectors. ● Apart from the normals for the direction, Houdini uses another attribute, which is the up vector, it will determine in which way the object will point up. SOPs - Surface Operators ● The SOP context in Houdini can be compared to programming in the sense that there are data structures (variables) such as boxes, tubes, spheres, which have all the information about points, primitives, normals, etc. and then there are functions and methods that are applied through nodes. ○ A function can be a polyExtrude. On the input it gets fed data (points & primitives) which it uses as arguments to execute the function. The function then returns a result (extruded geometry) which is passed on downstream to another function. ● You can create compound objects which are: Box, Tube and Sphere ● You can also create other types of geometry like Torus, Grid and Platonic Solids (which include Teapot, Pyramid, etc.) https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 11/86 4/12/24, 1:15 PM Intro to Houdini ● Geometry created in Houdini has no normals, you always need to give it a normal. For this use a Point SOP and turn on Add Normals or use a Facet SOP and turn on Post-Compute Normals. Intro to Houdini Object Merge ● Used to merge objects from other places. Always set Transform to Into This Object to get the transformations of the object. Scatter ● Scatters points in the surface of the area. ● If you want random points in every frame, then use rand($F)+0.1. 0.1 is the seed of the expression, change it in every component. If you want to scatter points every X amount of frames use if($F % X == 0,1,0) and replace X by a number. ● If you are making an emitter for POPs you probably want to use the Random Seed and randomize the seed every frame, so use an expression like $F. ● You can also randomize the Number of Points with a random expression. ● You can scatter points based on an attribute, so points that a value of 0 in that attribute won't be scattered. ○ Type the name of the attribute in Alternate Attribute and set the Attribute Bias to 1 to only scatter based on that attribute. Point SOP ● Useful for adding Color, Y vector and Normals. Set it to Add Color or Normals and then in the parameters you can use expressions. ○ For color, you can visualize an attribute that you created by using its local variable $ATTRIBUTE. ○ Inside particle tab you can add Up Vector which will create 3 new attributes (UPX, UPY, UPZ). The attribute is calld up. You can delete all the others and just set the upy to 1 so it points up. ○ You can have the normals pointing in the direction that it is moving by using the $T variables. You can also randomize it, ● In the particle tab, you can add Velocity and Particle Scale (pscale). ● The custom tab allows you to change the value of an attribute that already exists. Set the name to the attribute that you want to change and use the first scalar value parameter if its an integer or a float. Use the first 3 if its a vector, or use the string parameter if it is a string. ○ You can't modify an attribute that you are using in the same Point SOP in the Color, Vel, N, etc. Just make a new Point SOP below. ● The Point SOP has 2 inputs, so it can blend attributes. ● Attributes in the 1st input are TX, NZ, etc. but on the 2nd input they are called TX2, NZ2, etc. ● In the T attribute for example, you can add the expression $TZ * (1 - $ATTRIB) + $TZ2 * $ATTRIB ○ This would have the attribute drive the blending, and if its a gradient for example, it would move them apart more and more every frame since the $ATTRIB is constantly increasing and it is being multiplied by the Translate Z. Note that one side has to be negative! Add ● You can add points and connect them to create polygons. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 12/86 4/12/24, 1:15 PM Intro to Houdini ● Use a space between every point number and a - if you want to include the points between those values(1-10). Intro to Houdini ● You can extract points from other objects by using the point expression. ○ point("../OBJECT",45,"P",0) ○ Object is the object that has the point you want to copy, 45 is the PT, “P” is the attribute from where you want to copy, and 0 is the component (0=X 1=Y Z=2). Paint ●a Poly Frame ● It computes the tangent of the curve. The tangent is the direction the curve is travelling. By default its stored in another attribute, but you can change it to N it will be stored in the normal attribute. ● It creates normals based on the style that you select. First edge will have the normals pointing in the direction of the following point. Remember to set the Tangent Name to N and turn off .Normal Name if you want the Normals to point towards each other. For Each ● There are currently 2 for loops in Houdini as of version 15: ○ The For Each Subnetwork used to be the only one, but it's being replaced by the new method. The For each subnetwork can iterate over groups, primitives, attributes or numbers. ■ For Each Group will iterate through every group, if you dive inside the subnetwork, there will be an each node that will be displaying only 1 group. ■ For Each Attribute value will iterate through every attribute value. This is used a lot with the name attribute to iterate through every piece. ■ For Each Number will iterate a fixed amount of times. ■ The Each node inside the subnetwork: ● The Value[0] field holds a stamp expression that has the current iteration number. So whenever you need to use the current iteration number you can copy that expression. ○ The For Loop (Or For Each Loop) ■ The For Loop will act as a Feedback loop while the For Each loop will act as a Merge results loop (or in this case Fetch pieces). They are the same nodes, only that the default options are changed depending on which one you make. ■ The geometry to be processed should be plugged into the first input. ■ To access the current iteration number, you have to select the Block Begin and click on Create Meta Import Node. ● The iteration as well as other handful values are stored as a detail attribute in the new node. You can use a detail expression to query them. ● Feedback loop vs Merge loop ○ By default the For Each subnetwork will act as a merge loop. What this means is that it will output all the inputs it loops through merged. This is good when you are iterating over primitives or objects based on the attribute, since it will isolate each of them in every iteration, apply an https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 13/86 4/12/24, 1:15 PM Intro to Houdini Intro to Houdini operation, and then merge the current piece back to the final output. Once it goes through every piece, you end up with the whole geometry again. ■ Using a merge loop with 1 piece of geometry will result in the same geometry being copied and merged every iteration. ○ The feedback loop will return the same geometry with the operations applied and feed it into the next iteration. Unlike the merge loop, it won’t merge it as a separate geometry, it will just feed it back into the next iteration. Copy SOP ● Allows you to duplicate objects. ● It has a second input where you can plug in any geometry and it will use the points as the position where the geometry from the 1st input will be duplicated. ● When copying geometry on to points, Houdini looks for a point normal to determine in which position the copied geometry will face. Once it has the point normal, it sets a local axis, which is always the Z axis. ○ It will match the direction of the Z axis with the direction of the normal ● Stamp function: ○ What it does is allows you write down expressions to modify the object you are copying and it applies it upstream. So if you want to have 10 different sized spheres, you won’t create 10 spheres, you have to go into the Stamp function and turn it on, and then give the function a name like “sphereSize” and in the value you can type in any expression like rand($PT*8)*2 and then if you go to the transform below the sphere and go to uniform scale, you have to type an expression to link it so: stamp(“../copy1”,”sphereSize”, 0) what it does is you go up one level ../ and then select the copy SOP name, and then the name of the stamp, and then the last 0 means, if there’s an error and it can’t be found, use 0 as a value. ● You can do the same for any parameter, like color, size, height, rotation, etc. ○ For color, a nice way is to go to the Point SOP where you are adding color, edit the interface and add a Ramp (color) into the node, and call it whatever you want, and then give make it constant and just select the colors you want to use. Then in the stamp, make a function like “sphereColor” and in the expression type rand($PT*2) or whatever, and then in the COLOR value of the point type: chramp(“nameOfRamp”, stamp(“../copy1”,”sphereColor”, 0), 0) ■ You can do exhelp chramp () to see what it does. ■ chramp expression needs 3 arguments: the name of the ramp which is inside the same node (that’s why there is no ../ because it’s in the same node, if it wasn’t you would need it). Then the number between 0 and 1 which defines what color of the ramp (thats where you use the stamp expression to get the random value from the copy sop) and finally the last argument is 0, 1 or 2, which stands for R G B so in the red channel you will use 0, green 1 and blue 2. ● rand($PT/$F) will give an even more random number. ● Ceil () or floor () will make it an integer. Delete ● Allows you to delete primitives / points based on expressions or groups. ● You can use an expression to animate the way that points are displayed. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 14/86 4/12/24, 1:15 PM Intro to Houdini Convert ● Converts any geometry to any kind of geometry that you want. Intro to Houdini Divide ● If you use the default settings it will triangulate the geometry. To actually divide in quads and not affect the geometry, turn off Convex polygons and turn on Bricker Polygons. Decrease the Size to have more divisions. Subdivide ● Not like divide, it actually just subdivides the mesh more and more and smooths it. Blendshape ● It takes in several inputs. It looks at the point position of the first input geometry and compares it to the corresponding point number in the second input and blends each point with its corresponding point. ● Requires the same number of points! Timeshift ● Removes the time dependency at the specified frame. It removes the animation of the object, leaving it in the position of the frame. Cookie ● Takes 2 inputs, the geometry to cut and the geometry to cut with. ● Sometimes it doesn't work and you get a big polygon in the side. Clip ● Like a cookie but you can't have a geometry to cut with, its just a plane and you cut through that direction only. ● Advantage over cookie is that it doesnt fail. Ray ● Projects rays from each point of the 1st input in the direction of the normal and places the point in any geometry that it collides with from the 2nd input. IsoOffset ● Converts the geometry into a volume. This is good to have before a scatter if you want to have points also inside the geometry and not only in the surface. A must for fracturing geometry so the inside also gets fractured in smaller pieces. Tetrahedralize ● You can create convex hulls or tetrahedralize geometry. Attribute ● Good for renaming attributes and deleting attributes. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 15/86 4/12/24, 1:15 PM Intro to Houdini Attribute Transfer ● Allows you to transfer an attribute from one object to another. Its really good to create parameters like Intro to Houdini transferring the impact into the ground, or making a crack through the ground. ○ Make sure both sides have the same attributes. The side that receives the attribute needs to have it created anyways and set to 0 so it transfers smoothly. ● Set the radius and blend to what you need. ● If you have color, also make sure both sides have color. Attribute Promote ● Allows you to transfer the attribute class and “promote” it from point to primitive for example. You can just transfer the attribute in the classes, not between objects. Attribute Copy ● Allows you to copy attributes from different geometry. Attribute Create ● Just for creating attributes. Set the class and type. Switch ● Good for connecting several objects and then lets you switch using a slider of integer numbers. 2D ● Curve ○ Easy way of making a line. Click to make points and after hitting enter you can edit them. Don't worry about making it perfect. ● Resample ○ It adds points to a curve with even spacing. SOP Solver ● Creates a Feedback loop. It takes always the previous frame as the input for the current frame. ● The Solver contains a DOP Network with a SOP Solver. ● It will cache un-feedback frames of the simulation while inside the Solver. You have to go up one level and then reset and cache to see the feedback simulation. ○ An example would be to have 2 objects with different colors and one of them is transferring the color. If you want the color to accumulate over time while the object is moving, you would use the Attribute Transfer inside the SOP Solver. Blending Normals Direction ● To have more variation in the normals, its nice to randomize their direction. The workflow is normalizing the normals which all point in the same direction, then adding a Point SOP to randomize their direction, and then in a VOP SOP you can mix them. ● Normalize the normals in a VOP SOP. Create a Point SOP and randomize the normals direction with the fit01(rand($PT+0.1),-1,1) expression. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 16/86 4/12/24, 1:15 PM Intro to Houdini ● Create a new VOP SOP and plug the first VOP SOP into the first input, and the Point SOP in the second one. Intro to Houdini ● Create an Import Attribute node, set it to Vector, type N in the Attribute, and set the OP Input Index to 1 (0 is the first VOP). ● Add a Parameter called mix so you can control the amount. ● Add a Mix node, connect the Global N first, then the Imported N, and finally the mix parameter into the Bias. Output it to the Normals. ● Now you can control how much they mix from the Mix variable. Signed Distance Field (SDF) ● An SDF is a volume that computes what is inside and what is outside. ● You can convert geometry to volumes with the Iso Offset SOP. Make sure to set it to SDF and in the Construction tab, invert it if you want the inside to be positive and outside negative. ○ When converting geometry to volume, it needs to be manifold, otherwise you will get errors. ○ You can turn off Laser Scan if your geometry isn't manifold. ● The value inside the SDF is not 1 or 0 by default. The boundary is 0 and then the density is travelling in and increasing towards the inside point until it reaches 1. ● The gradient of a volume is the direction in which the volume gets denser. Copying using VOPs ● You can copy geometry onto points without using a Copy SOP. Basically if you transform points in VOPs into the position of another point, then it will act as a copy SOP. ● First you need to have several copies of the geometry you want to copy, and make sure they are all on the origin. ○ To move every fractured piece onto the origin, you can assemble the geometry and just keep the points (the centroids) and store them in a new attribute. ○ Unpack the original geometry and then promote the name back to points and simply do an attribute copy of the new position attribute making it match the name attribute. ■ Just do a Point VOP and subtract the original P by the centroid P you calculated and this will shift every geometry to the origin. ○ If you need more geometry, you can simply copy all the fractured pieces in place. ■ Make sure your pieces are fused when you create the new name attribute based on connectivity. ● To make sure you have the same amount of objects as points to copy to, add a Blast SOP and delete based on the name. If the name piece is bigger than the total amount of points. ○ @name>`npoints(“path”)-1` ● Connect the geometry into the first input of a Point VOP and the points to copy to into the second input. ○ Get the name attribute (which should be an integer and match exactly the point number of the template points) and use it as the point number of the second input. ■ Get the P, N, up (if there is) and pscale of the second input using the name attribute as the point number. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 17/86 4/12/24, 1:15 PM Intro to Houdini ● Normalize the N and get a 3x3 matrix using the Look At from {0,0,0} to the normalized N and with an up of {0,1,0} or the up attribute if there is. Intro to Houdini ● Extract Transformations and get the rotation. ● Add a Transform Matrix and plug the original P into the Pos and then the P of the template points into the translate, the extracted rotation into rot and pscale into scale. ○ Feed the result into the output P. ● VEX code for doing it: ○ int newPt = i@name; ○ vector newPos = point(1, "P", newPt); ○ vector newN = point(1, "N", newPt); ○ float newPscale = point(1, "pscale", newPt); ○ ○ matrix matN = lookat({0,0,0}, normalize(newN), {0,1,0}); ○ newN = cracktransform(0,0,1, {0,0,0}, matN); ○ ○ @P *= maketransform(0,0, newPos, newN, newPscale, {0,0,0}); ■ Store the new attributes into variables (load them using the corresponding point number that you get from the amount of pieces of geometry. ■ Do a lookup to compute the rotation matrix and then extract the rotation. ■ Transform the original position by multiplying it by a 4x4 matrix with the new position, normals, pscale and pivot. Fracturing ● The most common way to fracture an object is with the Voronoi Fracture. ● The Voronoi Fracture node takes the geometry to fracture as the first input and then the points where the geometry will be fractured. ○ Every point will be the centroid of each piece. ● To also fracture the inside of the geometry, you can convert the object to a volume with the Iso Offset and then scatter nodes. ● For even better looking fractures, add a rest node in the original geometry and then add some noise to it. Afterwards, scatter points and fracture it. ○ Then simply move every point back to the rest position. POPs - Particle Operators ● Use the old Popnet (Particle Operator Network) in the beginning while learning. ● Particles only use points, no primitives. The idea is that you work with points and then use the copy sop to apply your geometry into each point. ● You can't use expressions in VOP POPs. ○ You can create a new attribute before VOPs with the same name and it will override the VOPs attribute. In the Create Attribute node you can actually use expressions. ■ Useful to create an Amplitude attribute before VOPPOPs and control the amplitude through an expression. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 18/86 4/12/24, 1:15 PM Intro to Houdini ● Controlling particles through Volumes is much better than using some of the old operators. Intro to Houdini POP Network ● The Popnet is empty inside by default. ○ Create a Source POP and load the emitting points. ● Instead of writing the path to the object, you can use the Use First Context Geometry, Second, Third, and Fourth. They represent the inputs of the Popnet, so if you connect your emitting points in the first input, simply choose First Context. If you use a collision mesh, connect it in the second input and select load Second Context. ● Check the Emission Type. If its Points (ordered) and points don't change there will be a visible pattern, you can set it to Points (random) if not. ● Remember to test both $ID and $PT in particles. The difference is that PT is just the point number, and after particles died, the number is reused. So if you want to use a unique value, use the ID variable. Make sure its turned on in the Source POP in the Add Attributes tab. ● The order of the operators is irrelevant in POPs. ● Source POP ○ Birth ■ Birth is controlled by impulse activation or constant activation. ■ Impulse activation means that the particles are birthed in an “impulse” whenever the impulse activation is set to 1. You can either set an expression in the impulse activation so that its active every X number of frames, or just leave it on 1 and have an expression on the scatter sop. ● if($F % 20 == 0,1,0) ● 20 means that it is emitting every 20 frames only. Change the number to the amount of frames that you want to have between every emission. ■ Constant Activation means that it will constantly emit particles in every frame. ■ When using one or the other, remember to set the other to 0. ■ Impulse Birth Rate is the number of particles that are born in every frame that there is an impulse. ■ Const. Birth Rate is the number of particles that are born every frame if you use constant activation. ● $NPT (and make sure you scatter a random amount of points in the Scatter SOP) ■ Life expectancy is how many seconds the particle will be live before dying. If you are working with bullets or rocks or something that doesn't die, just leave it on the default that is 100. If you are working with fluids, then you probably want to change the life expectancy. ■ Life variance means that the particles will live X seconds more or less than the life expectancy. ■ $LIFE ranges between 0 to 1. ■ $AGE age of the particle in seconds. ■ $LIFESPAN life expectancy in seconds. ■ The life attribute has 2 values, 0 and 1. Life 0 is the age of the particle ($AGE), and life 1 is the lifespan ($LIFESPAN). https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 19/86 4/12/24, 1:15 PM Intro to Houdini Intro to Houdini ■ $LIFE = $AGE / $LIFESPAN ○ Attributes ■ Use inherited velocity will use the Velocity of the points, and if there is no velocity, it will use the Normals for velocity. Normals are a vector, so they have direction and magnitude (the magnitude is the length of the normal). ■ You can add velocity on top of the normals by setting it to add to inherited velocity. ■ Add variance to your velocity so it looks natural. Variance is the plus or minus difference with your velocity. A variance of 10 will add and subtract 10 to the velocity, so it will have a range from any velocity between your velocity -10 to your velocity + 10. ■ Set initial velocity will only consider the velocity of those parameters. ○ Add Attributes ■ Make sure you turn on Add ID Attributes if you want to be able to use the ID local variable. ● Force ○ To create gravity, simply add a Force POP and set the Y force to -9.8. Try never to change it, unless you have tried every option. ○ Create a separate Force if you want to add another force such as noise. ■ Play arround with the amplitude, frequency and offset. You can animate the offset. ■ The noise affects the velocity of the particles. ● Attractor ○ Needs a geometry source to attract or repel the particles. ○ The attractor is dependant on the number of points of the geometry. The particles flow from point to point. ○ If display doesn't work, switch viewport to H 11 (but remember to switch back, playback works bad). ○ The attractor geometry should have a Point SOP with the following Force attributes: ■ Radius: everything inside the radius will be affected ■ Radial Force: will push the particles towards the attractor, or away from the attractor. ■ Edge Force: will push along the direction of the curve ○ The particles can overshoot the curve and not go along the attractor geometry because the Forces are modifying the acceleration of the particles and the radial influence isn't enough in some places. Thats why, always use it together with a Drag POP! ● Collision ○ Plug the collision geometry into the second input, and in the Collision node, set Geometry Source to Use Second Context Geometry. ○ If the collision geometry is static, then there is no problem and it has to be left as it is: Static Geometry. ○ If the collision geometry is animated, the geometry has to be triangulated! So before connecting the geometry into the Popnet, add a divide SOP to make it into triangles. ■ Remember to change the collision to Deforming Geometry. ○ The collision tolerance can be used to increase the collision geometry if there are intersecting particles. Its a threshold for when a particle is considered to have collided (distance based) It basically https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 20/86 4/12/24, 1:15 PM Intro to Houdini Intro to Houdini makes the collision geometry thicker. ■ If set to 10, it will consider particles 10 units away to have collided. ○ In behavior you can choose if you want it to Bounce on Collision, die or stick. ○ The gain tangent is how much it slides and the gain normal is how much it bounces. ○ Under Attributes you can enable attributes such as Hit ID or Hit Time. ○ If the collision geometry is at the same place as the emitting geometry, the Collision POP won't be of much help. ● Drag ○ The drag applies force the opposite direction the particles are travelling. You can use it like air resistance to the particles and you have the option of applying it only to Linear Velocity and also Angular Velocity, so its good to have 2 Drag nodes, to control each drag node individually. ○ The mass of the particles will affect the drag. By default is set to 1. ● Property ○ Allows you to modify various attributes, such as mass. ■ Houdini doesn't like masses that go below 0.1 or negative value, particles will go crazy ● Color ○ By default it will color the points based on the Lookup, which is set to their frame (their age). You can lookup any value, such as speed or velocity. ■ The color only goes from 0 to 1, so any number higher than 1 will start to loop again. ■ If you get flickering its because of that. ● Fit the value ● Controlling collisions ○ You can use an SDF (signed distance field) to control the position of the particles. It can check the position of the particles and if its inside the boundaries of the collision geometry, they can get deleted. ○ Create a VOPPOP and make a Volume Sample From File Operator. Connect the Point Position into the Sample Position. ○ Promote the Geometry File parameter and use the op:/obj, etc and select the SDF. ○ Create a compare operator and if it is less than 0. Create a Two Way switch. Connect the Compare into the condition. ○ Add a Volume gradient file and also connect the volume file and connect the particle position. ○ Create a multiply and multiply the gradient by the amount. Plug the vector first. ○ Create a negate and connect the multiply to the negate to invert it. ○ Finally add the negate with the point position and connect it to the first input of the Two way switch. Just connect the point position into input 2. Connect the output to the Point position output. ● Advect By Volumes ○ Advect means move. It moves particles based on a volume. ■ Modifies the velocity, force and position attributes. ○ Update Force means its modifying the acceleration of the particles (like the attractor). It acts as a Force POP. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 21/86 4/12/24, 1:15 PM Intro to Houdini Intro to Houdini ○ Update Velocity It will just set the velocity to the value from which its sampling the volume. ○ Update Position will directly affect the position of the particles ○ Velocity Scale will control the speed of the particles. ● Kill ○ If the rule evaluates to anything other than 0, it will return True and kill the particles. ○ Useful for deleting particles that go beyond a point or that collide with some object. Blending the sourcing of particles ● Blending the sourcing of particles is very common. For example, if you want an arm to emit particles based on its speed, it will only emit when the speed is higher than the number you specified. ● The problem is that the arm might be moving 1 meter in 1 frame, and 20 cm in another frame, so you will get a cluster of particles in one part, and very few in another. ● First of all, add a scatter so the point number is the same in every frame. ● Create a timeshift (set the frame to be $F - 1) and then feed the scatter into the first input of a Point SOP and the timeshift into the other one. ○ Edit the position expression with fit01(rand($PT + 43.545), $TX, $TX2) ■ This will create a blendshape, and it will scatter the points between the previous and current position for every frame. ● The first frame will return an error because there is no previous frame to blend, so there are 0 points. For this, create a switch connected to the original scatter and the other one with the Point SOP. ○ npoints(“timeshift path”) == 0 ■ If the number of points for the operator is = to 0, then it will use the scatter input, if not, it will use the point sop. Metaballs ● Metaballs are a method of creating an organic-looking surface. They are blobs of density made up of equations. When 2 metaballs overlap, Houdini adds their fields together so they get combined. They change their shape to adapt and fuse with surrounding metaballs. ● The Particle Surface Fluids is made up of metaballs. Output it from the Popnet to make the particles look like liquid. ○ Change the Step Size, but SAVE before and use it carefully because if the size is too low Houdini will crash! ○ Play with the Surface Thickness. DOPs - Dynamic Operators Structure of a DOP network ● DOP networks are a Data Framework, which means that it has nothing to do with SOPs. In DOPs there is only data, there are no functions and methods (no actions occur with the nodes in DOPs), it's just building up data that will then be fed to a solver.. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 22/86 4/12/24, 1:15 PM Intro to Houdini ○ An easy way to see the difference is to open the Details View, which looks completely different from the one in SOPs. Intro to Houdini ■ The Details View shows all the data in the simulation and it updates every frame (close it or collapse it when simulating because it slows down the playback). ● A DOP simulation runs on 2 passes (This process happens every time at each time step): ○ The first one gathers all the data needed for the simulation (such as dependencies and relationships) starting from the node with the display flag and going upstream. ○ The second pass gives the data to the DOP parser which makes the solvers perform the simulation. ● Since you are only working with data in DOPs, the order of the nodes doesn’t matter as in SOPs (Kind of, read the warning). The way that the data is read is determined by the display flag. ○ For example, if you have gravity at the end of the network and you set the display flag to the node before, there will be no gravity. Instead, you can either set the display to be on the gravity node or just place the gravity node anywhere before. ○ Warning! This doesn’t mean that having one gravity node upstream will affect everything!!!! It will only affect everything above it, so if there is a merge node after the gravity and it has more objects, they won’t be affected by the gravity. ● Data is passed on through green connectors, while the gray connectors represent the object through the network with each node attaching data to the object. ● To have a better understanding of how DOP works, you can use the Apply Data node. The way it works is, it has an input for an object, and then you can connect all the data that will be attached to the object on the other input. ● Expressions such as $F and $T work differently in DOPs, you can use $SF and $ST (simulation frame and simulation time) instead. Objects ● A DOP Object is simply a container for data (such as geometry). ● Initializing the transformations of the geometry can be done in 3 places: https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 23/86 4/12/24, 1:15 PM Intro to Houdini ○ RBD Object (Second preferred option) ○ Geometry object transform (Most preferred option) Intro to Houdini ○ SOP Transform (Least preferred one) ● Creation Frame ○ The creation frame specifies at what frame the object will be created, thus at what time the simulation will begin. ○ The input always has to be a frame number! So using expressions like $F % 20 == 1 (which would create the object every 20 frames) won’t work because it is not returning a frame number (just returns 0 or 1). ■ Instead you can use if($F % 20, 0, $F) ○ You can create several objects at the same time with the Number of Objects: ■ If you want to offset the position of every object, you can use rand($OBJID * 230) * 10. Every object created has a different ID which will be used to offset its position ($OBJID). ○ Note that when creating different objects, the names will all be the same by default because the Object Name is set to $OS (operator string), set it to $OS$OBJ for each object to have the name of the operator and then the ID number! ● Create Active Object ○ The create active object option will make the object static if its turned off. ○ If you create an Active Value DOP, you can choose when you want the active object to be turned on or off. ■ If the Active value is set to Set Always, it means it will update the object every frame and set the Active value to whatever it is. So if you use an expression like $F > 20, for the first 19 frames the value will be 0 so that will be fed to the object, so nothing will happen, but in frame 20 it will be set to 1 and the object will be active. ■ Set initial will only set it in the first frame, and if it is off in the RBD object, then it will stay off. Attaching data ● The nodes which apply data to an object have the option of controlling when the data (green connector) will be applied to the object data (gray connector). ● By default it is set to Set Initial, which means that it will set the data only once in the first frame of the simulation. ● If you have deforming geometry, or geometry changing over time, then Set Initial won’t work because it will only set the data in the first frame but it won’t update. ● Set Always will update the value at every frame. ● Set Never will never change the value, not even on the first frame. Solvers ● They are the engine, they calculate how the objects will behave considering all the other data attached to them. ● The solver that controls an object is attached as another piece of data. You can't control an object with multiple solvers, but you can attach a solver that itself uses multiple solvers (Blend solver). https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 24/86 4/12/24, 1:15 PM Intro to Houdini ● Blend solver ○ Runs multiple solvers and blends their effects based on the blend factor data on each object. Intro to Houdini ■ The Blend Factor node attaches blend factor data to each object. ● Multiple solver ○ Runs multiple solvers in order on the same objects. ● Switch solver ○ Similar to the Switch node, but it routes objects to different solvers based on a piece of switch data on each object. DOP Import ● Most of the times what you get from DOPs is simply transformation data, that's the only thing you use DOPs for, to calculate that data and then apply it back to the geometry. ● The DOP network will import the geometry of the objects used in the simulation and then simulate their motion. This import is done through the object nodes. ● After simulating, the original geometry object will import the transformations from the simulation back into the object, and this is done through the DOP Import node. ● This is why the AutoDopNetwork has its display flag off by default, because it won’t render. What you end up rendering is the actual geometry with the transformations calculated in DOPs. Affectors and relationships ● The Affector Matrix shows the interaction between every object with each other. ○ Green means the objects interact mutually. ○ Blue means only one object affects the other. ■ The table should be read from the side and then above, meaning that the object that appears on the side is affected by the one on top (if its blue), but the object on top isn’t affected by the object on the side, it only affects it. ○ Everything in the Affector Matrix is caused by the data from the Relationships rollout. ● The Relationships rollout menu displays all the objects that create relationships or are affected by relationships. ● Merge nodes create relationships between dynamic objects! They aren’t a simple Merge node like SOPs. ○ Merge nodes determine if the objects have a collision relationship, 2 way relationships or 1 way (only 1 affects the other), etc. ● In one-way relationships, affectors are solved before the affected objects. ● In mutual relationships, the relationships are solved simultaneously (kind of). Errors ● Rendering with motion blur can change the result of the simulation! ○ The sub stepping can end up affecting the simulation, so the best way is to cache the simulation and then use a Time Blend geometry node. Volumes ● Volumes allow you to store values for Voxels in space. ○ Voxels are like 3D pixels. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 25/86 4/12/24, 1:15 PM Intro to Houdini ● Volumes are used to create clouds, smoke and fire, and also to store simulation metadate like velocity fields and collision fields. Intro to Houdini ● There are 2 types of volumes: Standard Houdini Volumes and OpenVBD Volumes. Standard Houdini Volumes ● They are made up of a box with position, orientation and size and are subdivided into a 3D grid of voxels, each storing a value. ● There are 3 types of volumes which store different information in the Voxels: ○ Scalar Field (density) ■ Stores a single numeric value for each Voxel. ■ Useful to represent smoke where the value of every voxel represents the density. ○ Signed Distance Field (SDF) ■ Stores a value for each voxel that determines if the voxel is inside or outside the fluid. ■ Each number represents the distance to the fluid, creating a gradient. ● Everything inside the fluid is greater than 0 while everything outside the fluid is smaller than 0. ■ Used to represent fluids. ○ Vector Field ■ The Vector Field stores a vector at every voxel, and its represented using 3 scalar fields. ■ Commonly used for the velocity field of a gas simulation ■ VDB Vector Merge converts 3 Scalar Field volumes into a Vector Field volume. OpenVDB Volumes ● VDB volumes use no memory for “empty” voxels. ● Does not require a container specifying the volume, it can extend infinitely. Common VEX code ● Integer to string ○ itoa(@ptnum) ● Get the min and max values of an attribute, fit them to 0-1 and then control it with a ramp ○ float tmp = fit(@width, detail(1, "width", 0), detail(2, "width", 0), 0,1); ○ @width = chramp("thickness", tmp); ● Load a point attribute ○ point(index, “attribute”, point number); ● Get the distance between 2 points ○ @width = distance(@P, point(0, "P", 0)); ● Delete based on probability ○ if (rand(@ptnum * 45) > @keep) { removepoint(0, @ptnum);} ● Randomize normals ○ @N = set(fit01(rand(@ptnum * 34), {-1,-1,-1}, {1,1,1})); ● Noise functions ○ (Position * frequency - offset) * amplitude https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 26/86 4/12/24, 1:15 PM Intro to Houdini ● Anti Alias Flow Noise in VEX ○ #include <voplib.h> Intro to Houdini ○ vop_fbmFlowNoiseFV(@P * freq - offset, roughness, maxOctaves, flow, flowRate, advection) * amplitude; ■ You need to include the voplib header file. ■ Check difference between FV, FP, VV and VP suffix! ● Linear Interpolation (Mix VOP) ○ lerp(value1, value2, amount); ● Look up matrix ○ lookup(vector from, vector to, vector up) ■ Computes a rotation matrix ● Extract transformation ○ cracktransform(int trs, int xyz, int component, vector pivot, matrix) ■ trs is an integer for the order of translate, rotate scale. 0 is trs. ■ xys is the order of rotation, 0 is xys. ■ The component is which component you want to extract 0 = translate, 1 = rotate, 2 = scale. ■ Pivot usually 0. ■ Transform matrix from which to extract it from. ● Make transformation ○ maketransform(int trs, int xyz, position, rotation, scale, pivot) ■ Multiply the position by the matrix VOPs - VEX Operators ● VOPs is basically a replacement for expressions, its just more intuitive, faster and more powerful. ● VOPs is extremely fast to process, way more than using Houdini expressions. Its accelerated vector scripting ? that compiles the code into low level math. It is much faster than using Houdini expressions and also more powerful since it has more options. ● You can't use expressions in VOPs parameters. ○ You can create a new attribute before VOPs with the same name and it will override the VOPs attribute. In the Create Attribute node you can actually use expressions. ● Green boxes represent a vector. ● Blue an integer. ● Dark green a floating point value. ● What you are doing in VOPs is visually programming in VEX. You can actually right click and check the VEX code of what you did. ● Promoting a parameter in VOPs will make it appear outside the VOPs when you click on the node and let you modify it from there: Promoting parameters makes them a VARIABLE that requires user input. If you do it inside VOPs every time, it will compile the code every time and regenerate everything, which can take a while. Instead, promoting parameters just changes the variable and does not require VOPs to recompile the code. ● Parameters let you create your own variable that will appear in the VOPs when you go out of it and you can modify it. This way you can create sliders that affect an attribute. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 27/86 4/12/24, 1:15 PM Intro to Houdini ● Constant are like parameters but you don't have access to them outside VOPs and they don't change. ● When using Noise, remember to set it to 2D or 3D! Intro to Houdini ● When multiplying a vector by a float, remember to have the vector first! ● To see the list of attributes in VEX, open the command prompt and type: vcc -X sop Common nodes ● Vector to float ○ Divides a vector into its 3 components (X, Y, Z). ○ Useful if you want to apply an effect into only a certain axis. ■ Example: Add noise in X and Z. ● Clamp ○ Clamps values between 0 to 1 (or whatever number). Good if you want to get rid of negative values. ● Fit ○ Fits values into a min and max values. You can create variables for the Min and Max to control them outside VOPs. ○ Connect the input values into value. ● Mix ○ Mixes 2 values. It has a bias parameter which can be controlled with a variable. ● Multiply ○ Multiplies all the values that are connected. You can always add a third input which is a parameter that controls the amplitude of the result between the 2 inputs. ● Multiply Constant ○ Multiplies by a constant number. Always use it before the random and multiply by a high number to get a very random number. ● Random ○ Gives a random number between 0 to 1, like the rand expression. ● Add Attribute ○ Same as Create Attribute in SOPs. You can create attributes to plug in your effect and output them. For example, you can create pscale, width, alpha, etc. ● Import Attribute ○ Allows you to import attributes that you created yourself that aren't there by default. ○ Also great for importing attributes from different OP Input Indexes. ● Ramp ○ Great for having control over an attribute. You can modify it outside VOPs. ■ Control width, alpha, color, pscale, etc. ○ Use the Spline ramp for float points and the RGB ramp for vectors. ● Add ○ Adds different values together. The order doesn't matter. ● Subtract ○ Subtracts values. Check that the order is properly done because its a subtraction! ● Volume Gradient File https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 28/86 4/12/24, 1:15 PM Intro to Houdini ○ It needs to point to a node or read a file to sample the gradient. ● Volume Gradient Intro to Houdini ○ It can just look at the gradient of a volume plugged into the inputs. Matrix Transformations ● Introduction ○ A matrix is a rectangular grid of numbers arranged into rows and columns. ○ If you think of vectors as a 1 dimensional array (just as a row or column), then a matrix can be thought of as a 2 dimensional array (with both rows and columns). ○ A vector is an array of scalars, and a matrix is an array of vectors ■ [ 0, 1, 0 ] ● The above is a vector. Its 1 dimensional (row). ■ ● The above is a matrix. It has 2 dimensions (rows and columns) ○ A matrix can be used to describe the orientation, scale and position of an object in space. ○ Transformations are described through a matrix, not using rotations, or degrees. ● 3x3 and 4x4 matrix ○ A 3x3 matrix describes orientation and scale but not position. ○ A 4x4 matrix describes orientation, scale and position. ○ An identity matrix is a square matrix where all the diagonal elements are 1 and the other elements are 0. ■ Multiplying a matrix by an identity matrix leaves the matrix unchanged. ● It’s like multiplying a number by 1. ○ We mentioned before that a matrix is an array of vectors. If we create the vectors of a 4x4 identity matrix, we actually get an axis gnomon! https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 29/86 4/12/24, 1:15 PM Intro to Houdini Intro to Houdini ● A matrix can be thought of 4 points in space. Imagine the axis gnomon like above. ○ (0,0,0) - (1,0,0) - (0,1,0) - (0,0,1) ● Rotating an object will only affect the rotation components, but the position does not. ● When you translate an object, only the translate component is affected, the other 3 rotation vectors don’t change. ● A matrix defines rotation as a position ● The relationship of these vectors between each other is what defines the rotation in 3d space. ● The scale of the object is the length of each of these vectors in relationship to each other. ● Applying a transform matrix in VOPs ○ To apply a matrix transformation to an object you need to get the position and at least 2 axis (up and N). ○ First apply the scale! Doing scale after rotation will give the wrong result. ■ To get the scale, you can get the length of the x, y and z vectors and plug them into a float to vector. ■ Add a Make Transform VOP and connect the scale vector into the scale input. ○ Now you have a 4x4 matrix with the correct scale but with no orientation or position. ○ To get the orientation, use a Look At VOP and connect the N to the to input and the up into the up input. Make sure the 2 vectors are normalized. ■ Set the from to be 0,0,0 ○ This will output a 3x3 matrix with the correct orientation. ○ Multiply the scale matrix with the orientation matrix. ■ You can optionally convert it into a 4x4 matrix before multiplying, but the result is the same. ○ To get the position, add a Translate VOP and connect the 4x4 matrix that has the right scale and orientation and finally plug the position of the object into it. ○ To transform the current object into that place, multiply the P by the 4x4 matrix and plug it into the output P. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 30/86 4/12/24, 1:15 PM Intro to Houdini Intro to Houdini ● Transform static geometry using transform points ○ When dealing with a RBD sim, or any kind of non-deforming animation that has the same point count, the proper workflow is to get the transform matrix from DOPs and then apply it to the high res geometry. ■ The reasons why you might want to do this: ● You can apply the transform to high resolution geometry ● You can cache the sim by simply writing out the points (way faster than caching 100k pieces every frame). ○ After DOPs, you want to transform the input geometry from the Dop Import node. The geometry that comes into the DOP import should be 1 point for every object. ■ When dealing with packed geo, you can grab the geo that’s going into DOPs and make a foreach loop and delete all geometry but add a particle system. Then simply add default N and up vectors. ■ You should end up with a point cloud with N and up vectors and a name point attribute. ■ Create a goto_pt integer attribute which is just simply the point number. ■ Finally, promote the name to a primitive. The Dop import will transform the geometry by matching the primitive name attribute, so if it’s on a point it won’t transform the geo. ○ After the dop import, timeshift the point cloud to the first frame and then connect the animated point cloud and the rest one into a point vop. ■ Make a matrix out of the animated and the rest points by using a look at with the N and up, and then translate it by the corresponding P. ● You should end with 2 matrices. ■ Invert the rest matrix and then multiply the rest matrix (child) by the animated matrix (parent). ● This is your transform matrix. ■ To transform the geometry (must be unpacked), you would have to attribute copy the goto_pt attribute based on the name. Then in the vops you would get the animated and rest points from the second and third input and you would use the goto_pt attribute for their point number input. ■ You can now multiply the objects P with the matrix and output the position. ● Delayed load transformations ○ Write out the static packed geometry as an alembic and load it back it. ○ Save the matrix from the step above in an attribute and connect the alembic into a point wrangle and connect the xform pts in the second input. ■ matrix M = point(1, "M", @ptnum); ■ @P *= M; ■ ■ matrix3 rest_M = primintrinsic(0, "transform", @ptnum); ■ rest_M *= matrix3(M); ■ setprimintrinsic(0, "transform", @primnum, rest_M); ○ The P will only affect the translate, to fully affect the objects you have to modify the transform intrinsic attribute which is a matrix 3. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 31/86 4/12/24, 1:15 PM Intro to Houdini Intro to Houdini ○ The IFDs will still reference the alembic file on disk, so they will be very fast and easy to generate. VOPs Examples ● Normalizing Normals ○ Connect the Normals into a node called Normalize and connect it to the Normals Output. ○ If you want to control the amplitude (speed) of the Normals, you can create a new parameter called amp and then create a multiply node and connect the Normalize node and then the amp parameter. Then connect it to the N Output. ● Normalizing Normals + Adding Random Length ○ Normalizing normals will make every normal the same length, thus the same speed when going into POPs. To randomize it, connect a random from the Point Number, and then Multiply the Normalized node by the Random. You can still have the amplitude as a 3rd input and then connect all into Out N. ■ The random node doesn't look very random by default since the value is noise. What you can do is create a Multiply Constant and multiply it by 100 or a high number, this will make the noise pattern very different in each point and it will look random. ● Mixing Normals ○ Normalize the normals in a VOP SOP. Create a Point SOP and randomize the normals with the fit01(rand($PT+0.1),-1,1) expression. ○ Create a new VOP SOP and plug the first VOP SOP into the first input, and the Point SOP in the second one. ○ Create an Import Attribute node, set it to Vector, type N in the Attribute, and set the OP Input Index to 1 (0 is the first VOP). ○ Add a Parameter called mix so you can control the amount. ○ Add a Mix node, connect the Global N first, then the Imported N, and finally the mix parameter into the Bias. Output it to the Normals. ○ Now you can control how much they mix from the Mix variable. ● Adding Noise to a surface ○ Use always the Anti Aliased Flow Noise node to create noise. ○ Set it to 2D or 3D Noise! ○ If you want to add noise to the position, you need to connect the P into the AAF Noise and then into an Add node, and add the original Position with the AAF Noise and then connect it to the Out P. (Also CD to visualize it) ○ Promote the Amplitude, Frequency, Roughness and Offset. ○ If you want noise in only certain axes, make a Vector to Float, which will divide the Vector into its 3 components (X, Y, Z) and then connect the ones that you want to use into the AAF. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 32/86 4/12/24, 1:15 PM Intro to Houdini ● Rotating a noise by another noise Intro to Houdini ○ Create a noise with an amplitude of 4.5 and fit it from -1 : 1 to whatever angle you specify. ○ Create a parameter and make it from float to vector and plug it into the max and then negate it and plug it into the destination min. ○ Make a Transform Matrix with the original position and plug the fitted noise into the rotation amount. Use the new position as the input position for the new noise pattern that you want to apply. ● Using noise to determine which points emit and which don't ○a ● Creating the Particle Scale control ○ The pscale attribute controls the size of the particles, and just turning it on wont give a natural effect. To have the shapes have a variation in the size, its good to have a spline ramp that controls the size of every piece. ○ Add a multiply constant and a random from the PT and connect it to a ramp. ■ Set the ramp to spline, since its a float value. ○ Multiply the ramp by a new parameter called amp and then output it to a new attribute called pscale. ○ A way of having even more control is to use a fit node instead of a multiply. So plug the ramp into the value of the fit node, and create a min and max parameter, and connect them to the destmin and destmax. ● Controlling attributes through a ramp ○ Import your attribute, such as a gradient, through an Import Attribute node. Then connect it to a ramp. ■ Make sure to set it to spline if its a float value, and RGB if its a vector. ○ Connect the ramp into a fit, mix, add, multiply, etc. and then output it either to another attribute such as pscale, or width, or just a default one. ○ The ramp can determine if the attribute gets affected or not! ○ If you have a gradient attribute and connect it to a ramp, and then have AFF Noise from the P and you multiply them together and then ADD them again with the original P and Out to P, your ramp will control in what parts of your object there is noise. ● Rotating the N or up with a matrix ○ If you feed a vector like the N or up into the translate of a Make matrix it will turn them into points (?). ○ You can then rotate it by an axis (Say the N) and then either extract the translation and feed it back to the up or N, or multiply the matrix by the attribute and normalize it before feeding it back. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 33/86 4/12/24, 1:15 PM Intro to Houdini Intro to Houdini ROPs - Render Operators Rendering ● Create a ROP Network and inside it make a Mantra node. ○ In the Mantra node you can change the render settings ○ Also check on every Geometry the Render tab to make sure you render the objects you want. ● Create a Camera and connect it in the Mantra Node ● Set the Frame Range. ● To turn on motion blur, you have to turn it on in each specific geometry and on the render settings. ○ Inside the Render tab of the Geo, go to Sampling and turn on Geometry Velocity Blur. ○ In the Mantra node -> Properties -> Sampling and Allow Motion Blur. ● In Mantra Objects tab, choose the objects to render under Force Objects. ● Under Forced Matte also choose the object. ● Increase the sampling under Properties, Sampling, Pixel Samples. ○ 9x9 for displacement or high frequency textures ○ 5x5 limit for production quality. ● Before using Diffuse Limits, use Min Reflect Ratio in the Shading tab, to send more rays in dark areas. More efficient than using diffuse limit. Stay below 0.5 ● For bright speckles, reduce Color Limit. It will decrease the max amount of light allowed in the system. ● If you have motion blur or dof, increase Motion Factor. It controls the shading quality and depending on the motion blur or dof it can decrease the shading quality dramatically. ● Use velocity motion blur instead of deformation blur to reduce IFD generation time and size. ● Set Cache Memory Ratio to 0.75 under Rendering - Render, ● Import the camera as FBX! ○ Alembic does the wrong aperture! ○ The F-stop doesn’t get transferred, it’s always to 5.6 by default. Te F-stop needs to be divided by 100 as the camera. ○ The Focus Distance has a bug and doesn’t have to be scaled down! Optimized Rendering Generating IFDs ● IFD stands for Instantaneous Frame Description. It stores the scene description in a file which Mantra then reads. ● You can use Blosc-compressed IFDs to get very small and fast IFDs. ○ .ifd.sc ● When you generate an IFD, Houdini stores a copy of the geometry in memory and then writes it out. However, when using delayed load type primitives (Alembic or Packed Geometry), only a single point with attributes is put into the ifd file. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 34/86 4/12/24, 1:15 PM Intro to Houdini ○ The attributes the bounding box information, transforms, etc. ○ When Mantra hits the bounding box, it will then load the primitive from disk. Intro to Houdini ● The best way to keep IFDs small is to reference external geometry or procedurally generating geometry using procedurals. ○ If you generate IFDs and the geometry in the scene are packed disk primitives (Make sure to select Load As Packed Disk Primitives on the file node!), then it will have a reference to the packed disk primitives. ■ It won’t store a copy of each geometry, only the transforms and attributes. ■ I made a test exporting 400 teapots as full geometry and it created a 34mb IFD file. ■ If I packed the teapot before copying and then loaded it as packed disk primitives, the IFD was just 8.7kb. ● Packed Disk Primitives use less disk space and network IO. ● To create the IFD, create a Mantra ROP and go to the Driver tab and turn on “Disk File”. ○ Click on Render To Disk and it will save the IFDs instead of rendering with the Mantra command. ○ Make sure all your render settings are final, since these are the settings that will be used by Mantra when it renders the IFD! This includes the output path! ■ Changing the settings means you have to create the IFDs again. ● When the IFD is generated, Houdini won’t look inside the packed geometry (which would be slow to do) to see what material attributes it might have. This means that it won’t know what shaders to include in the IFD, and only when Mantra unpacks to render them it will find out it might not have all the required shaders. ● To include all the materials on the IFD, go to the Mantra ROP and under the Render tab, set Declare Materials to Save All SHOPS. ○ This way all materials will be included in the IFD and will be available for any procedural to use. Mantra Procedurals ● A mantra procedural is a program that is run prior to the lighting and shading. They are used to build geometry on the fly in the same way that Houdini can build geometry procedurally. It’s one way of dealing with lots of geometry. ● The great advantage is that geometry is created only when it’s needed. ○ You can feed Mantra a few thousand points and it can create millions more on the fly. Delayed Load Procedurals (Obsoleted by Disk Packed Primitives) ● Mantra needs to have a copy of the geometry in memory and then write all the data into an IFD, and then load the IFD. For very heavy geometry, saving the IFD ahead of time and only having Mantra load it can save a lot of time. ○ Note that Mantra writes and reads IFDs per frame. ● A delayed load procedural is a shader that fetches an object’s renderable geometry from disk at render time, replacing whatever geometry was inside the object. ○ The object can be just proxy geometry or even be empty. ● Mantra will only load the geometry when a ray hits a bounding box, as opposed to loading the whole geometry in memory for every frame. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 35/86 4/12/24, 1:15 PM Intro to Houdini ● Displacement shaders aren’t very efficient in delayed load instances since displacement will force Mantra to create separate geometry for each instance. Intro to Houdini ● Try to avoid using displacement shaders on delayed load instances. Displacement forces mantra to create separate geometry for each instance, decreasing the benefits of referencing. If you must use displacement, micropolygon rendering is better because the renderer can throw away the displaced geometry when it’s done rendering it Creating Delayed Load Procedurals ● In SHOPs create a Delayed Load Procedural shader ○ Set the file name pointing to the geometry on disk. ○ Back in object level, go to Rendering and then Geometry and point to the delayed load shader in your Procedural Shader. ● By default the Delayed Load Procedural has the Bounding Box set to No bounding box required. ○ This will make Mantra attempt to read the bounding box from the geometry file on disk. If no bounding box information is found, the entire file is read in. ■ By default geometry is written out with the bounding box information included. ● Since the delayed load procedural will override the geometry inside the object, you can create an Add node and turn on the render flag. This way it won’t have to load any geometry and then replace it by the delayed load. Alembic Geometry Procedural ● It will create alembic primitives directly in Mantra. ● Create an Alembic SHOP pointing to the alembic file on disk. ○ Go to the render tab in Object level and point to the Alembic shader in the procedural shader. Animated Geometry ● As opposed to .bgeo files, Alembic is only 1 file. Rendering motion blur requires to capture models over an interval of time. Including the current geometry plus at least one other point in time (depending on your samples) can make the IFD size very big. ● When using an Alembic cache, the motion blur will be sampled from the same cache at two different points in time, but it won’t have to copy the geometry to the IFD. ○ When rendering bgeo geometry, a copy of every sample is included in the IFD. ● Another valid option which involves more network IO is to render packed disk primitives to get small sized IFDs. ● Houdini supports demand-loading Alembic data, meaning that it can display geometry without storing a copy in memory, and Mantra can stream geometry instead of loading it all into RAM. Packed Primitives ● Packed primitives generate geometry at render time. They are used to decrease the amount of memory when interacting with Houdini. ● Mantra treats packed primitives as instanced https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 36/86 4/12/24, 1:15 PM Intro to Houdini ● Packed primitives have information about geometry embedded inside of them as: ○ Geometry stored in memory Intro to Houdini ○ A reference to a piece of geometry ○ A file path to geometry stored on disk. ● Packed primitives can’t be edited because they are references! You need to unpack them back into geometry. ● There are 2 types of packed primitives: ○ In-memory packed primitives ■ It’s created using the Pack SOP and it stores the geometry in memory. ■ It will create a Packed Geometry Primitive with a reference to the current version of the geometry. ■ The embedded geometry is just a reference to content in memory. ● Copying the geometry only copies the reference rather than the geometry itself. ● The reference is shared among all the copies of the packed primitive. ■ Advantages: ● Use less memory ● Easier to transform ● Can be drawn more efficiently in the viewport or rendered by Mantra. ○ The viewport simply draws the same data multiple times with different transforms rather than drawing each geometry. ■ Packed doesn’t mean compressed or smaller! The original geometry is kept in the RAM as well as a bit of memory for every reference. ● This is why packing a single primitive isn’t more efficient than using the original geometry. The benefit comes from the representation of a large number of copies that share the referenced geometry. ○ Packed disk primitives ■ A packed disk primitive embeds a reference to a file on disk and at display or render time it is read from disk rather than always keeping it in memory. ● In the File SOP, set the load parameter to Packed disk primitive. ■ It works exactly like in-memory primitives, only that every copy is just a reference to the disk file. ● The downside is that they are less dynamic. The only way of editing them is to unpack them and copy the file data into memory. ■ Mantra can stream the data from the disk file as needed instead of copying into memory, reducing memory usage. ● IFDs are much faster to generate and smaller on disk since it’s only writing the reference to the file on disk. ● Packed Fragments ○ When you pack geometry that has a name attribute, each piece of geometry that has the same name value will become a packed fragment primitive. ■ The packed fragment will contain a reference to the original geometry, this means that every fragment references the same original geometry. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 37/86 4/12/24, 1:15 PM Intro to Houdini ■ The difference between each fragment is that they each refer to a subset of the original geometry. Intro to Houdini ● Displacement and subdivision surfaces ○ Displacement and subdivision surface rendering is the same for packed geometry as for standard geometry. ■ Mantra will dice the geometry into smaller primitives until there’s 1 primitive per pixel. ● Objects closer to the camera will have more dicing. ○ When instancing with packed geometry, Mantra will load and dice each object / instance individually, which means the geometry is no longer shared. ■ The main benefit of rendering instances is that geometry is shared across all instances, but this is lost with displacement and subdivision surfaces. ■ This can be avoided with a Share DIsplacements Between Instances render property to the object containing the instances. ● This will use the highest level of dicing necessary for the scene on one instance and then share the diced geometry between all instances. ● One disadvantage is that far away objects will get too much dicing. In this case the instances can be split based on distance from camera and so you get 2 different highest dicing levels. ● You can also unpack the instances close to the camera, which will remove them from the highest necessary dicing level. Deep Holdouts (DSM) ● Very useful when rendering in different render engines. It allows you to render out a holdout and use the image sequence as a holdout as opposed to using the objects at render time. ● Also useful when a holdout is very heavy to render every time. You can just do it once and use the render sequence. ● Create a Mantra node and go to the Deep Output tab and set the Deep Resolver to Deep Shadow Map. ○ Set the DSM File to where you want to save the holdout. ○ Save it as a .RAT (EXR won’t work) ● DCM (Camera) hold a lot more information than DSM. The DSM only holds the depth. The DCM are used for deep compositing and are huge. ● In the Objects tab of the Mantra node, make sure you don’t render anything except the holdout. Select the holdout object on the Force Objects. ○ Also remove all the lights and turn off Headlight creation. ● Make sure the motion blur settings are exactly the same as the settings for your final render. ● The output picture can just be a jpg, it’s a useless image. The important file is the one specified in the DSM File. ○ Set the output picture to `strreplace(chs(“vm_dsmfilename”), “.rat”, “.jpg”)` ● Make as many ROPs you need for every holdout and render them out. Every object needs it own DSM. ● Create a DSM Merge ROP and select all the Deep Shadow Maps you have rendered. ○ Save the merged output as a .RAT file. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 38/86 4/12/24, 1:15 PM Intro to Houdini ● Create a new camera and parent it under the render camera (Or use a fetch if it’s an Alembic and then connect the new camera to the Fetch) Intro to Houdini ○ If you can’t see anything, turn off the display of the Fetch and Camera. ○ Make sure you set all the settings to be the same as the render camera (even the resolution) ● In the new hold out camera, load the DSM image sequence as a Background Image. ○ Go to the Render Properties of the camera and add the Background Image as Matte parameter (under View). ○ Enable the new parameter. ● Back in the original Mantra render node, now you no longer need Forced Matte objects, so you can delete them. Also, you need to update the camera to render from the camera with the deep holdout. ○ However, to keep the same lighting and shadows, you need to have all the other objects as phantom objects. ○ You need to have in the Mantra that is rendering the geo everything else as phantom, and in the DSM mantra have every object that's in the DSM as a phantom to have correct lighting. ● You can merge multiple DSM’s using the Merge DSM ROP. ● If storage of the DCM is a problem, you can try compressing it using the DMC Compression property (It’s a lossy compression). ○ You can also use the DCM Z Storage parameter and change it from 32 bit to 16bit. This might cause stepping and buzzing in the animation. ○ A final optimization is using the DCM Z-bias parameter and increase it so samples within that value are merged. ● When generating DSM for volumes you can use the DMC Interpolation parameter and set it to Continuous volume. Other Optimizations ● A good way to optimize a scene is to divide geometry that isn’t overlapping. Every object node has its own bounding box. Every time Mantra sends a ray, it will check if it hits a bounding box. If it hits a bounding box, it will load the geometry inside of it to do the calculations. ○ Even if the geometry is spatially separated inside the object node, they will have a bounding box that encapsulates everything. ○ Dividing the geometry into different object nodes will make their bounding box smaller, making the rays do less work when looking for objects. ● Use ray-predicing. Turning on ray-predicing will cause all displacement shaders to be run before rendering begins. This allows for optimal subdivision structures to be built since mantra already knows the exact position of displaced polygons when rendering begins. Unfortunately, using this option can balloon memory usage, since dicing is normally resolution-dependent (i.e. larger images will use more memory). ● Turn off True Displacements and True Ray-Displacements. This treats displacements as bump maps (that is, it does not create new geometry). ● Use velocity motion blur instead of deformation blur to reduce IFD generation time and size. ● For PBR rendering, you can increase the Min reflect ratio to send more rays in dark areas. If you're using PBR, you should try this before increasing the diffuse limit since it’s more efficient. You should stick to values less than 0.5. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 39/86 4/12/24, 1:15 PM Intro to Houdini ● Decreasing Noise level will decrease the noise level by forcing mantra to keep sampling until the variance is less than this value, or the Max ray samples has been reached. Intro to Houdini ○ It will only increase render time in "problem areas" rather than globally. It helps in dark areas such as contact shadows that can have a lot of noise. ○ Decreasing noise level makes the render much slower. ○ Note that the default Noise level is 0.05, while analog film grain probably corresponds to a noise level of approximately 0.08. ● Decrease Color limit if you have bright speckles in PBR renders. It will decrease the maximum amount of light allowed in the system. ● For lights that only affect part of the scene, enable the Active Radius and set it to the maximum radius of effect for that light. ○ When shaders are executed outside the active radius, they will ignore that light source entirely improving rendering performance. Dicing Optimizations ● Increasing Dicing Flatness will try to represent flat surfaces with fewer polygons. ● Decrease Z-Importance to reduce the detail on displaced surfaces viewed edge-on by the camera. ● Note that there are some parameters just for scanline (micropolygon) and others for ray tracing! ● Decrease Ray Shading Quality to make bigger micro polygons (less shading and less sampling will occur) ○ Shading Quality is only for scanline rendering! It won’t do anything for RT or PBR. ● Decrease Ray Shading Quality Multiplier to reduce the shading qualities in the scene for all objects. ● Turn on Ray predicing (at the expense of a lot of memory usage) to speed up ray tracing of diced surfaces. Per Object Properties ●A Optimizing Volumes ● Remember that you can add properties to objects (and even primitives) to give them customized values for these properties. For example, you can set a lower noise level for an important object. When you are rendering geometry with a certain amount of transparency, you can use the opacity limit to stop the current ray if the opacity threshold is met. The Opacity Limit parameter is located on the Render sub-tab of the Properties tab of the mantra output node. By altering the Opacity Limit, you will only get a 1-5% decrease in render time. The default value is already pretty aggressive, so be careful to avoid adding unwanted artifacts. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 40/86 4/12/24, 1:15 PM Intro to Houdini ● Mantra doesn’t export planes for lights that have zero intensity (because they're not sent to Mantra in the first place). This can cause problems if you're animating the intensity because it will cause a missing frame when Intro to Houdini the intensity is 0. ● You can add the light to Force lights (or even put a * in that field) on the Mantra render node’s Objects tab to force Mantra to render the light even at zero intensity. Reducing Noise ● Pixel Samples = Primary Rays ● Min/Max Ray Samples = Secondary Rays ● BSDF Types = Diffuse - Reflection - Refraction Direct Samples = Pixel Samples * BSDF Types * Min/Max Ray Samples ● Example 1 ○ Pixel Samples 3x3, BDSF Type just diffuse shader, 1 max ray sample ○ 3x3x1x1=9 ● Example 2 ○ Pixel Samples 3x3, BDSF Type diffuse + spec shader, 1 max ray sample ○ 3 x 3 x 12x 1 = 18 Indirect Samples = Min/Max rays x Quality && Noise / Quality ● Example 1 ○ 1 Max Ray x 2 Diffuse Quality & 0.1 Noise / 2 Diffuse Quality ○ 2 indirect rays & 0.05 noise https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 41/86 4/12/24, 1:15 PM Intro to Houdini Intro to Houdini https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 42/86 4/12/24, 1:15 PM Intro to Houdini Intro to Houdini Mantra workflow 1. The image is divided into tiles 2. The scene geometry is loaded into the RAM. ○ Delayed load procedural geometry is loaded only for the current bucket 3. Geometry is diced (Only if it’s a subdivided surface or it has displacement) until it's small enough to shade (1 primitive per pixel by default) ○ Controlled by Shading Quality i. Value of 1 means 1 micropolygon per pixel. ii. In ray tracing this will only affect smooth surfaces (only if render as subdiv is turned on) and for displacements. It won’t affect shading quality! iii. Shading quality increases geometric quality, not texture. 4. Displace geometry shader is evaluated ○ Watch for Displacement bounds i. For too much displacement you can turn on re-dice displacements 1. Option is turned OFF by default. Render parameters! 5. Opacity is calculated for the current patch 6. PBR modes ○ Primary rays (Pixel Samples) per pixel are shot i. Primary rays control the overall quality (mainly the shape and accuracy of the objects). ○ Secondary Rays i. At least 1 secondary ray is shot for every primary ray. ii. These rays compute lighting, reflections and refractions. iii. They originate from the hit location of the primary rays. ○ Direct secondary rays i. They deal with lights. ii. They go from the hit location to the light source. iii. At least 1 ray is sent to every light iv. Determine if a surface is in shadow and if not, lighting is calculated. v. Noise caused by direct secondary rays are usually found in shadow falloff and specular highlights. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 43/86 4/12/24, 1:15 PM Intro to Houdini vi. Optimization: Spotlights, point lights and distant lights only represent a single point/direction Intro to Houdini from where light is emitted. This means that one sample is enough to determine their contribution. On the other hand, area lights and environment lights emit light from a surface instead of a single point. The variations of color, light and occlusion across the surface make it necessary to be sampled multiple times in different places to get a final contribution. ○ Indirect secondary rays i. They deal with objects and their surface properties. ii. They go from the hit location to directions determined by the shader attached to the object. 1. Refraction rays will travel through objects 2. Reflections rays will bounce 3. Diffuse rays will scatter in a random direction within a hemispherical distribution iii. They compute refraction or reflection iv. Noise caused by indirect rays is usually found in soft reflections of very bright specular highlights on other objects. ○ Surface shader is run on each ray hit to get the color value. ○ Primary rays are controlled by the samples (3x3 by default, 5x5 top limit, 9x9 extreme) 7. Micropolygon mode (very inefficient for high polygon models that are small/away) ○ Dice polygons into micropolyons of roughly pixel size. ○ Surface shader is run on every vertex and blended to get surface color. 8. Shading process 9. Shaders are programs the renderer runs to calculate various aspects of rendering such as the color of the surfaces. 10. Displacement, surface, light, shadow and fog shaders ○ PBR is a shading process (so it can work in micropolygon or RT, it’s independent) ○ PBR computes the BSDF of the surface (incoming light direction and viewing direction as inputs, and outputs the magnitude of the reflected light) 11. For each shading sample ○ Direct lighting contribution for all lights in the scene. i. 1 shadow ray towards every light and 1 ray for reflections of lights. ○ Based on the BSDF, indirect ray is calculated and if it hits a surface, then the contribution to the current surfaces color is calculated. ○ Output of the BSDF is the final surface color. 12. Rendering Volumes ○ Direct rays sample the volume multiple times while travelling through it. ○ Indirect rays are also sent multiple times as the ray travels through the volume. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 44/86 4/12/24, 1:15 PM Intro to Houdini Intro to Houdini ○ When a ray travels through a volume, it does it in steps. The forward rate at which it moves is determined by the Volume Quality. i. In each step it evaluates the shader and accumulates the density of the volume. ii. Since the density values vary through the volume, nearby rays calculate different values so noise is introduced. 1. More direct and indirect rays need to be sent in order to fix it, or reducing the steps through the volume. ○ Stochastic transparency will separate the accumulation of density values from the shading samples. i. The amount of sampling can be greatly reduced as variations in lighting information is less obvious than variations in density. Lighting Pipeline ● Import your alembic geometry using an Alembic SOP and set it to create Primitive Groups for “Name Group Using Transform Node Name”. ○ You need to make sure that in Maya every node has the correct name in the transform node. ● Have a Null in the object context and scale it by 0.01 to make the objects from Maya real world size. Make this Null the parent of every import node. ● Object merge the geometry into another Geometry node and set the Transform to Into This Object. ● Unpack the Alembic geometry. ○ Convert it to Polygons. ○ Use a Facet to Post Compute Normals. ○ Add a Trail to Compute Velocity. ○ Add a Time Shift and delete the expression and set it to 1, then create a Rest position and connect it into the rest. ● Create your object IDs attributes. ● To give each primitive a name attribute corresponding with it’s group name, run a For Each loop through the groups and set the Group Mask to * if not it won’t iterate. ○ Inside, create an Attribute Create and set the Name to name, Primitive class and String type. ■ Set the value to be a channel reference of the Cull Group of the Each1 node. ● `chs("../each1/group")` ● Create an Assemble SOP and turn off Create Name Attribute and turn on Create Packed Geometry. ○ Create a Group Copy and connect the Assemble into the first input and the Object merge into the second one. ■ Set it to copy every Primitive Group with the *. ● Create an Attribute Copy and also connect the second input into the Object Merge and set the Attribute to Match to name and attribute name to path. ○ This will copy the original path attribute which holds the hierarchy of every primitive. ● Create a final geometry node and call it RENDER plus the name of the object and object merge the output of the previous point. ○ Write out a bgeo sequence and load it. ○ Add a Packed Edit and set the visibility on. ■ Now you can go to the Data Tree and in the Object Appearance menu you can assign materials. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 45/86 4/12/24, 1:15 PM Intro to Houdini Caching Intro to Houdini ● Add a ROP Output if some node is slowing everything down. ● Set the start and end frame to $FSTART and $FEND. ● Initialize Simulation will start the caching at frame 0 in case you are in frame 50, if not it will cache from the frame number where you are. ● Add a File node and make a relative reference to the rendering path of the ROP Output. Dicing ● Blah For absolutely physically correct light, you should turn Normalize light intensity off, and set Attenuation to "Physically correct". Rendering Particles ● Turn on Motion blur in the Geometry node and in the Mantra Sampling. ● Connect your camera ● Add Pscale in the particles to control their size and also color. Render Layers ● You can have as many mantra ROPs as you want. Connect all of them and always render the last one so it overrides the settings of all the others. Object Masks ● If you want to create Matte IDs you need to create an attribute for every object. If you want to do it per object you need to do have a point attribute. ● Basically you want a vector 4 attribute (RGBA) and you want every object to have a value of 1 in each channel. ● Create a Point Wrangle in SOPs and set it to run over points and create a Color parameter. ○ p@matteIDA = set(chp("matteID")); ■ This creates a point attribute called matteIDA and it initializes it to the value of the color parameter (called matteID in this case). ■ You want the Point Wrangle to have a group mask so that only the selected objects get the assigned value. ● Repeat for every channel, so create 4 Point Wrangles and change the group every time (It’s a good idea to set the group name in the operator name and set the group to be *$OS). ● If you have several object IDs, you can create a new attribute called matte02 and do the same. At the end, use an Attribute copy to merge the attributes together. ● If you only want to set attributes to the whole object, then you can do it on the detail level. ● The next step is to create a parameter VOP inside every shader that is being used and import the matte attributes and export them always. Make sure it’s set to Vector4. ● Finally, create output for the image plane and give it the name of the attribute (matte01) and set it to Vector4. You can change the channel name to ID_A. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 46/86 4/12/24, 1:15 PM Intro to Houdini ● Look into procedurally creating extra IDs Intro to Houdini Motion Vector pass (for Nuke) ● Create 2 Get Blur P nodes and set the value to 1 and 0. ● Add a Transform VOP to each and connect the output of the Get Blur P into the from. ○ Set both transforms from current to ndc (screen). ● Subtract the Transform with the Get Blur P value of 1 with the other Transform output. ● Add a Null and change the name of the data to ndcvec ○ Create a Snippet and write: ■ vector res; ■ renderstate("image:resolution", res); ■ ndcvec *= res; ○ Output it as a vector parameter ● Look into: In the Image plane settings set it to have a Gaussian soft filter (3x3). ● In the Rendering parameters in Mantra, at the bottom of the Sampling tab there is an Allow Image Motion Blur option. ○ By default it’s turned on, which means it will apply the motion blur to the beauty. Turning it off will calculate the motion blur and apply it to the motion vector passes but it won’t apply it to the beauty render. WorldP pass ● Import P and Transform from current to world and output it as a vector parameter. ● 32 bit float and Closest Surface. ● minmax min filter. Ambient Occlusion ● Create a Dirt Mask VOP inside the shader and output it to a vector parameter and set it on the image plane. UV pass ● Create a UV Coords VOP and plug it into a parameter and export it was uvs or whatever. Make sure it's a vector and 32 bit. Shops - Surface Model Shader The default diffuse reflectivity (or intensity) of the surface model is 0.5. However, when rendering using light sources with non-physical attenuation (for example, a default point light), pixels can have values higher than 0.5, especially where the light hits the surface directly. Even though the image appears brighter, the actual surface reflectivity is still 0.5 – the brighter image is the result of a higher default intensity for these light types. In particular, the following non-physical light source types will do this: Point/spot lights with No Attenuation on. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 47/86 4/12/24, 1:15 PM Intro to Houdini Distant/sun lights Intro to Houdini Area lights with No attenuation and Normalized Light Intensity to Area on z Depth: Sample Filter: Closest Surface. Set the pixel filter to “closest sample filtering” = “minmax min” for no anti aliasing or feathering of edges which cause useless depth information. pixel filter: minmax idcover = object with most pixel coverage (no filter) z depth from mantra in Nuke far=0 Export components -> diffuse specular refract volume coat You can see them in the Extra Image planes They are actually created in the shader if you want to change the names. You can set any image plane to be by component and it will create an output for every component specified in the Extra Image Plane export components. You can also use Light Exports and export the image plane for every light. You can have 1 material for different objects and override the parameters per object. Assign the material in Object level and click on the Drop down arrow and select either Create all local material parameters to override all of the parameters or Select and create local parameters. SHOPs - Shading Operators Basics ● SHOPs stands for shading operators and it contains all the shaders in the scene that will be used to render your objects. ● All materials are created in a VOP network, and they are actually VEX code. ○ You can right click a material and select View VEX Code to see it. ● All the nodes in the SHOP context are actually materials, not shaders. A material is a container of shaders. ○ By default, Houdini comes with a material palette (Alt + G) which you can use to start off. ○ The most used materials are the Principled Shader and the Mantra Surface Shader. ■ The Principled shader is based on the Pixar Disney Shader while the Mantra Surface shader is based Side Effects attempt on a physically based shader and it's built on the Model Surface Shader. Shaders ● Principled Shader ○ The principled shader is a physically based shader created by Disney and it’s starting to be used in a lot of render engines. ○ The advantage is that it’s very artist friendly and it’s energy conserving. ○ The disadvantage is that it can’t do refractions. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 48/86 4/12/24, 1:15 PM Intro to Houdini ● Surface Model Shader ○ It was introduced in H10 and it’s Side Effects attempt at a physically based shader although it has Intro to Houdini some bugs and it doesn’t always conserve energy. ○ It can do refractions and SSS unlike the principled shader, but some basic operations can break the energy conservation. ■ “imagine you have only 2 components diffuse and specular and no fresnel just plain 2 simple 100% layers and you have specular mask like b/w checker, 99% of artists will expect white parts to be 100% specular and black 100% diffuse, but in Surface Model you need you will get ■ white parts 100% diffuse + 100% specular -> conserving => 50% both ■ Black parts 100% diffuse + 0% specular -> conserving => 100% diffuse” - anim, OdForce ● Glass Shader ○ Physically based glass shader ● Skin Shader ● BSDF - Bidirectional scattering distribution function ○ A probability model / function that describes how light is scattered by a surface ■ Usually split into BRDF and BTDF (Reflection, which we care about, or transmittance, which is for subsurface scattering). ○ Bidirectional because it can compute the ray from the camera to the light, or from the light to the camera. ○ Based on the incidence angle, what’s the outgoing angle? Structure of a material ● If you want to make your own material, you can create a Material Shader Builder which will create a VOP network with all the input and output nodes you will need by default. Output collect ● A shader determines how a 3D object is rendered. It's not only it’s color, but also its reflectivity, displacement, emission, and several other things. ● The output collect gathers all the shaders within the VOP network. A material needs at least a surface shader, that's the minimum requirements to render an object. ○ The surface shader defines the properties of the object that give it its “look”, so it’s the color, reflection, roughness, etc. A surface shader has no information about the displacement of an object, only how it looks! ○ Since the normal is included in the surface shader, the bump and normal maps are part of the surface shader. ● The second most common shader type is the displacement, which describes the normals and position of an object. ○ The displacement output is the one that gathers the displacement that affects the object. It carries no “color” or “surface” information, only the position of the surface and the normals. ● Other shaders that can be created in Houdini are Light, Fog and Geometry. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 49/86 4/12/24, 1:15 PM Intro to Houdini Layers Intro to Houdini ● Throughout the network, all the shaders can be connected into a struct data type called Layer (orange color). The layer contains the BSDF, opacity, emission, position, normal and layer alpha. ● At any point the layer can be packed or unpacked to access its components. ● The 5 nodes for handling layers are the following: ○ Layer Pack ■ The layer pack can take the BSDF output of a shader like the principled shader as an input, and also the P and N data from a displacement texture, and pack it into a layer. ○ Layer Unpack ■ Layer unpack lets you unpack a layer into the components that make it up, which is useful if you want to modify certain component. ○ Set Layer Component ■ This node lets you set a component to an already packed layer without having to unpack it, change a component, and pack it again. ○ Layer Mix ■ Allows you to blend 2 layers together. This is the way to mix 2 physically based shaders. ○ Layer Composite ■ Allows you to blend 2 layers like the Layer Mix but it offers more options. ■ By default it will use the layers alpha if connected, and if not it will use the Aa and Ba (A and B’s alpha inputs) to combine the layers. ● A over B composites A over B. ● A inside B restricts A to the areas of B’s alpha component. ● A outside B restricts A to the area outside of B’s alpha component. ● A atop B composites A over B but only where B’s alpha exists. ● A xor B makes the two layers mutually exclusive. If their alpha components overlap, the overlap is removed. Compute Lighting ● It computes lighting using PBR and splits the layers into the components required for surface shading. ○ In non-PBR modes, it computes the lighting using the BSDF provided through the F (or the F inside the layer). The result is the surface color output as Cf and then the emission Ce is added to Cf. ○ In PBR it computes the lighting based on the BSDF and doesn’t do any computation with the Cf. ● It will unpack the layers so they can be plugged into the Surface output. Displacement Output ● The displacement output has an input for the Position and the Normal of the geometry. The output is a displacement shader. ● Here is where the displacement is connected so then it’s calculated and output as a displacement shader that can be plugged into the Output collect. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 50/86 4/12/24, 1:15 PM Intro to Houdini Displacement Bounds Intro to Houdini ● If you are displacing your geometry in your shader and you haven’t modified your displacement bounds, you will notice you get a strange artifact: the whole geometry will have holes. ● By default, Mantra calculates a bounding box for every object it renders, so that it only calculates what is inside and no extra computation time is wasted on areas where there is no geometry. ○ The problem is that when you have displacement, and the geometry is extruded outwards, it will go beyond the bounding box and this is why you get the holes. ● So change the size of the bounding box, you need to change the vm_displacebound attribute. There are several ways of doing this: ○ Create a Mantra Surface material and go inside it and copy the properties node that is plugged into the output collect. Go back to your material and paste it and connect it to the output collect. ○ Create a properties VOP and go to Edit Rendering Parameters and type displacement in the Filter and expand the Mantra and Shading folder and look for Displacement Bound and drag it into your parameters on the left side. ● Once you have your parameter, you need to fine tune it until it fits all your displacement. The size of the bounding box will affect the memory and render time, so change it until it’s big enough to have the displacement inside but don’t make it larger than it needs to be! ○ A good rule of thumb to start is to make it ⅔ of the absolute displacement Surface Output ● Requires a color (Cf), opacity (Of) and BSDF input in order to generate the surface shader that will then be plugged into the output collect. Principled Shader ● In the principled shader or the surface model shader, you have your parameters to control the surface of the shader. ● baseN is the input for the normals of the surface, and it’s where you would connect your bump or normal map. ● basecolor is the input for the diffuse, and you can use either a constant from the parameters, or you can connect your own texture. ● The rest of the parameters such as metallic, reflect, roughness, etc. are all floating point, meaning they will only accept a grayscale map. Global Variables ● It provides outputs for the current VOP network. There are different variables for different contexts. ● The 2 main contexts are surface and displacement, and they are the ones that appear by default. ○ P = Surface Position (From the camera, not world) ○ N = Surface Normal ○ Ng = Surface Geometric Normal ○ Cf = Surface Color ○ Of = Surface Opacity ○ Af = Surface Alpha ○ I = Direction from Eye to Surface https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 51/86 4/12/24, 1:15 PM Intro to Houdini ○ s = S coordinate ○ t = T coordinate Intro to Houdini ● You don’t have to connect the P and N on every input, it will use the global P and N by default. ○ However, if you want to provide a different P or N from the global one, you do have to connect it. Surface Color ● Use the Surface Color VOP to load textures. The node itself is made from the texture VOP, but adds more functionality on top. ● Always plug the S and T variables into the scoord and tcoord parameters. ● When loading grayscale textures, turn on Monochrome output and set it to luminance. ● By default Use Base Color is turned on, and if you turn on Use Texture and load a texture, it will multiply the texture by the value of the base color. ○ A base color of 0 will cause the texture to be black! And a 0.5 will make the texture darker! Always turn off Use Base Color, or set it to 1 so it doesn’t affect the texture! ● The way the Source Color Space works is still unclear. Setting an 8 bit texture in sRGB color space to Automatic renders properly. But if you want to multiply it or do any operation, it doesn’t seem to be working in linear space. ○ Set it to linear, then multiply/screen/overlay and once you are done you can add a power node and set the exponent to 2.2 ● If you want to tile the textures, you can’t simply multiply the S and T coordinates. Create a Tiled Boxes VOP and connect the global S and T into the input S and T. ○ Output the ss and tt parameters into the S and T of the Surface Color. ■ Another alternative is to already build it inside the Surface Color and update the OTL. ○ Use the S and T Width to adjust the tiling. Note that it’s the opposite than in Maya, smaller numbers make the texture tiled more times. Layering textures ● To combine 2 textures together you have to use the Color Mix VOP. ● It will take 2 RGB vectors as input and it has a bias parameter where the mask can be connected. ● Connect the color output from 2 different Surface Color nodes and you can use either another Surface Color as the bias if you want to load a mask texture (Set it to monochrome, since the bias has a float input) or you can use some noise pattern as a mask. Displacement Texture ● This node is the equivalent of the Surface Color for the displacement, normal and bump. ● Load the displacement, normal and bump textures through this node. It will automatically output the P and N value for the texture. ● Set the offset to 0 in displacement. ● When dealing with displacement, the output P and N of this node have to be plugged into the layer P and N and eventually make their way to the Displacement Output. ○ For normal and bump maps, only use the out N and connect it into the baseN of your surface shader. ● To add displacement to a layer, use a Set Layer component and connect the P and N. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 52/86 4/12/24, 1:15 PM Intro to Houdini ● This texture is made up of a texture VOP and a displace VOP. ● The normal map has a Normal Space option (0 to 1) or (-1 to 1). It should always be set to 0 to 1 for 8 bit Intro to Houdini textures since all softwares that render a normal map will encode it into the 0-1 space. However, some floating point images can be saved to go from -1 to 1, so that would be a case to change the normal space. Texture ● This node shouldn’t really be used, it’s better to use the Surface Color or the Displacement Texture node which build on top of the texture node. ● One thing to note is that the texture node has a parameter to blur the texture, so you can dive inside the Surface Color or Displacement Texture nodes and promote it. ○ Other than that parameter, most of them are already promoted on the Surface Color and Displacement Texture. Displace ● The displace node takes has a value input that is a RGB texture and it converts into the the surface normals and surface position. Internally it calculates what the new normals are based on the texture. ○ If for any reason you can’t use the Displacement Texture, then this is the next node you should use since it can calculate N and P. ● Inside the displace node, it calculates bump, normal, displacement and vector displacement in the following way: ○ Bump ■ It starts by picking the red, green, blue or luminance channels depending on what you select for the Texture Channel parameter. It outputs the selected channel and adds it with the offset parameter. ■ The added value is then connected into a Displace Along Normals as the amount. ● The global P and N are used, unless different inputs were provided. ● Bump Only has to be checked so the bump is calculated. ■ The scale parameter is connected into the displace along normals and this will output the normal vector for the bump. ● The P isn’t affected in the bump, so the global P is output so no change takes effect. ○ Normal ■ It takes the RGB value of the input texture and starts by setting the Normal Space depending on the value of the parameter. ● The inline code is including the voplib header and using the vop_fromUnitNormal function. ■ Next, the normals are flipped if any of flip x or y were enabled. ■ The normals are then multiplied by a matrix of the chosen vector space and then normalized. ● To get the matrix, the normalized N and the vector space are used to output the matrix for either world space, object space or tangent space. ■ The dot product is calculated with the N and branching in a different direction the cross product also with the N. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 53/86 4/12/24, 1:15 PM Intro to Houdini Intro to Houdini ● The dot product is then output to a Trigonometric Function to calculate the Arc Cosine and the cross product is normalized. ■ The output from each branch is merged with a quaternion, with the dot product output being the angle and the cross product being the axis. ■ A Spherical Linear Interpolation with an initial quaternion of 0 and the second quaternion being the output of the quaternion just calculated. ● The scale parameter is used as scale. ■ The output is then connected into a quaternion rotate which also has the N as a vector input. ■ The result of this is the output normal vector, while the P remains the global P output since the normal doesn’t affect it. ○ Displacement ■ It takes the selected channel (R, G, B or luminance) based on the texture channel parameter and uses it as the amount input for the Displace Along Normals VOP. ■ The output N and P from the Displace Along Normals are the actual values for the displacement which can be used. ○ Vector Displacement ■ It takes the selected channel (R, G, B or luminance) based on the texture channel parameter and multiplies it by the scale. ■ The output is then multiplied by the matrix with the selected vector space. ■ The result is then added with the global N and the result is the output P for the vector displacement. ● To get the value of N for the vector displacement, you need to add a Shading Normal VOP after the add and connect the result to the P. ○ The output of the Shading Normal is the N value of the vector displacement. Displace Along Normals ● This is the lowest level displacement node, and it’s inside the Displace VOP. It only calculates displacement or bump. ● Use this node when you want to use a procedural bump or displacement based on a noise. ○ Connect the value of the noise into the amount. ○ Turn on Bump Only if you don’t want a displacement map, by default it will calculate the displacement. ● This node can’t be used to calculate a normal map or a vector displacement map. ● If you want to get the displacement or bump of a texture, try not to use this node, use the Displace or Texture Displacement which does it automatically for you. Combining Normal maps ● I still couldn’t find a way to combine the normals output that get calculated from 2 different Displacement Texture VOPs. The only way I know so far to combine normal maps is to combine the textures. ● To combine the textures, use 2 different Texture VOPs to load your normal maps. Connect the S and T values and set the color space to linear. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 54/86 4/12/24, 1:15 PM Intro to Houdini ○ For some reason, setting it to automatic so it knows its sRGB won’t convert it to linear and it will do all operations in sRGB space. Intro to Houdini ● Connect the textures to a vector to float each, and then overlay the red and blue channels from each texture and multiply the blue channels. ○ Convert the floats back to a vector and finally add a power with 2.2 exponent to convert it back to sRGB. ● At this point you can keep layering your result with other normal maps. ● Connect the output of your final combined textures into the value input of the Displace and set the displace type to Normal. ○ The output will be your calculated normal which can be plugged into the baseN of your surface shader. And this is the structure of an overlay node: https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 55/86 4/12/24, 1:15 PM Intro to Houdini Intro to Houdini UV and ST ● The UV attribute from the geometry doesn’t come as a global variable and has to be imported. ● You can get the UV coords by using the UV Coords VOP (preferred method). ○ You can also get them by creating a Shading Layer Parameter VOP and setting it to UV Coordinates (Which is actually how the UV Coords VOP is built). ● UV and ST mean the same thing, so if you have the UV stored in a vector, you can just take the first 2 components and those will be your U and V or S and T. ○S=U ○T=V ● Sometimes using the S and T from the global parameters won’t work (check if this depends on the context type). ○ If a texture or mask isn’t working and doesn’t look correct connect the S and T variables or the UV if it takes a UV input. utan and vtan ● utan and vtan are used to compute the direction of anisotropy. ○ The anisotropy direction is relative to the orientation of this vector. ● utan is the main surface tangent and vtan is the surface bitangent. ● They can be computed using the Compute Tangents VOP . ● Look into the Export Tangent Normals subnetwork found inside the Principled material or the Mantra Surface material and copy it. ○ The advantage is that it has an inline code to compute the tangents with displacement and bump baked. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 56/86 4/12/24, 1:15 PM Intro to Houdini Setting vector space matrix Intro to Houdini ● To get the vector space matrix you need the surface normal and the UVs. ● Tangent Space ○ Use a Compute Tangents VOP and connect the UV and N as inputs. Create a vector to float from the utan and vtan and create a Float to Matrix VOP. ■ Connect the 3 float outputs from the utan into the first 3 inputs. ■ The next 3 inputs for the Matrix should be the 3 vtan floats. ■ The final 3 inputs should be the 3 components of the normal. ○ This matrix is now the tangent space. ● Object Space ○ Create a Make Space Transform VOP and set it From Object to Current. ○ Connect the output to a Matrix 4 to a Matrix 3 and this in now your object space matrix. ● World Space ○ Create a Make Space Transform VOP and set it From World to Current. ○ Connect the output to a Matrix 4 to a Matrix 3 and this in now your object space matrix. Rest Position ● When dealing with deforming geometry (or geometry not animated in object level) you need to use the rest position instead of the surface position. ○ Using the surface position as inputs for textures or noises will result in “swimming” textures since the position changes every frame. ○ Instead, use the rest position as input whenever the P is required. ● Requires testing: ○ You can import the rest position by creating a vector parameter and setting the name to rest. ○ The other way is to create a Rest Position VOP. Parameters / Bind ● Difference between parameters and bind ● Use a Parameter VOP or a Bind Export to export variables to Mantra. ○ If you have any attribute you want to access in Mantra in an Image Plane, then you have to import it from the geometry and export it. ● Set the name and type to be exactly the same as the attribute name in your geometry. ● Change the export type to always. Ramp Parameter ● Instead of using a parameter which only offers the option of a slider, you can connect a Ramp Parameter into any input to control that value with a ramp. ○ Use RGB Color Ramp for vector inputs and Spline Ramp for float inputs. Color Correction ● Use this node to remap values of textures. Connect the output color into the Color In. ● For floating point textures, even though a vector is connected, since only luminance is used the Hue and Saturation won’t have an effect. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 57/86 4/12/24, 1:15 PM Intro to Houdini Intro to Houdini ○ Stick to using the value to remap grayscale textures. CHOPS Useful Expressions ● You can do most of the operations that the CHOP nodes do just using expressions in the Expression Chop. ○ The Expression CHOP unlike VOP CHOP has feedback. It has processing of the current frame and a feedback loop. ● $V = Current Value ○ ic(0, $C, $I) ■ Is the same as $V but the expression has more control. ● $I = Current Index ● $C = Current Channel ● ic(1, $C, $I) ○ Reads the incoming channel of the second input. ● ic(0, $C, ice(0) - $I) ○ Reverses the values ● sin($I) ○ Sine wave ● $C % 2 ● oc($C, $I - 1) + $V Understanding noise & expression parameters ● Noise has some inherent properties: ○ Its static ○ Its an irregular pattern ● Based on the position of a point, noise will return the value of the noise in that coordinate. ● Height is the same as saying amplitude. Its a multiplier to the original range of the noise function. ● There are different types of noise functions and they have different ranges: ○ Perlin ■ Range between 1 and -1 ○ Sparse Convolution ■ Range between 1.7 and -1.7 ○ Alligator ■ Range between 0 and 1 ● Frequency is how frequent it is. There is a point where the frequency is so high that it stops having influence in the detail. ● Low frequencies means big patterns, less repetitive. ● High frequencies will create small patterns more repetitive. ● The amplitude controls the intensity of the noise pattern. ● Fractal depth is how many iterations of noise there is being applied. How many layers of noise there is https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 58/86 4/12/24, 1:15 PM Intro to Houdini ● Roughness is a multiplier of how much each layer will contribute to the previous layer. Its a multiplier for the fractal depth. Intro to Houdini ● Animating the offset ○ $F * SPEED ○ Speed is a number that controls how fast the offset moves. To get a slow movement use a value like 0.01, and to get a fast movement use higher values like 1. ● Curl Noise is a cheap way of getting swirling patterns. ○ The points will “curl” around coordinate points. ○ A nice way of getting a curly puff is to make it have a lot of curl noise and reduce gradually. Create a new attribute before called amp and set it to $LIFE. This new attribute will override the VOPs amp. ○ Turbulence like Fractal Depth, its how many layers of noise are applied, and roughness is the multiplier for it. ■ To control the roughness you need to create an attribute outside the Voppop. ● Folding noise ○ Using an absolute VOP will make the noise more discontinuous. ● Sharpening and softening ○ Using the power VOP you can soften or sharpen the curve of the noise patterns. Useful Expressions ● Remember the random expression only gives a POSITIVE value between 0 to 1, fit it from -1 to 1 to have positive and negative! https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 59/86 4/12/24, 1:15 PM Intro to Houdini ● Channel referencings (ch) is linking 2 values together. ● Using a line with a Point SOP and the sin, cos, tan expression in the position variables is a good way to see a Intro to Houdini visual representation of what they do. ● For using Velocity , you should use length expression. ● Parameters that require a file to be loaded can use an operator if you use the OP expression with the full path. ○ op:/obj/geo1/example ● AND = && ● OR = || ● $F * 0.1 ○ 0.1 controls the frequency, a high number will have a higher frequency. Good for scatter SOP since you can't use other variables like PT or ID. ● $PT / ($NPT -1) ○ This expression is for having a gradient across a line. It divides each point by the total number of points and gives it a value between 0 and 1. If you check the details view, every point will start going higher and higher until it reaches 1. The -1 after $NPT is because the point number starts at 0, and to have the exact number we have to reduce 1. ● if ($ATTRIBUTE < TIME, 1,0) ○ This expression is useful to animate the gradient. If the attribute is bigger than or smaller than a value, then it will change color. This will create a constant / linear animation of the value. ○ Create a parameter in the interface called animation, and then replace time by a channel reference of the value. ○ Remember to animate the value. ● ifs() ○ Returns a string ● $TZ * (1 - $ATTRIBUTE) + $TZ2 * $ATTRIBUTE ○ Useful for blending 2 positions in the Point SOP and have them be driven by an attribute. It basically multiplies the position of the first one by an attribute (which can be a gradient for example, so it increases more and more), and adds it to the position of the second input which is also being multiplied by the attribute. In this case one is negative so they move against each other. ● if($F % 20 == 0,1,0) ○ Great for Scatter SOP or Impulse Activation in particles. The expression evaluates the frame number, and if when the F is divided by 20, the result is 0, then the result will be 1, if not 0. If used to emit particles, they will be emitted every X amount of frames that you replace 20 with. ● fit01(value, min, max) ○ If you need a value to be between certain numbers, then use this expression and fit it within the required value. ● sin($F x N) ○ The sin expression always returns a value between -1 to +1. ○ This expression will cycle from -1 to +1 back and forth. ○ The N is the speed at which it cycles: a 0.01 value will be very slow, while 1 or 10 will make the sin cycle very fast. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 60/86 4/12/24, 1:15 PM Intro to Houdini ● abs(sin($F x N)) ○ This is the same as the above, only that since we use the absolute value, so only POSITIVE values, Intro to Houdini it will start sharp and slow down towards the end, and then slow in when it goes back, and also finish abruptly. ○ A nice trick is to create a Decay parameter, which will make the value decay over time. Just create a Decay parameter in the User Interface and set the expression to: ○ abs(sin($F x 10)) * ch(“./decay”) ○ You will need to animate Decay going from 1 to 0 in the timeline. ● fit01(rand($PT+0.1),-1,1) ○ This expression can be used to randomize normals. Note the fit expression in the beginning which fits the value into -1 and 1 so the normals can point in the negative direction also. 0.1 is the seed of the random expression, so change it in every component of the vector. ● bbox(“../OBJECT”,D_ZSIZE) ○ Set the size of an object to the size of the bounding box of the object selected in the path and then you can choose which direction X,Y or Z. ● point("../OBJECT",PT,"P",0) ○ Extracts the position of a point. Object is the path to the object that you want to extract. PT is the point number that you want to extract, “P” is the attribute, in this case position and 0 is the vector component. 0=X 1=Y 2=Z ● length($VX, $VY, $VZ) ○ Will return the speed of a point. ● fit01(rand($PT + 3), $TX, $TX2) ○ Will blend between the 2 point positions and scatter random points inside the area to which it was fit (min = $TX and max = $TX20 ● $PT == $F / x ○ Can be used in the Delete SOP and it will delete the point number based on the current frame. Its a good way of getting a progression. ● ch(strcat(chs("../camProject"), "/tx")) ○ Concatenate 2 strings and then evaluate them Errors ● If your effect takes forever, check the time dependency by MMB on the node and if you dont have time dependency but its turned on, then that is the issue. ● Matching the point number of an object that has a delete expression based on an attribute, thus has different point numbers in every frame. ○ Scatter SOP! Will scatter the same amount of points every frame. Examples Scattering points ● Attribute transfer method https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 61/86 4/12/24, 1:15 PM Intro to Houdini Intro to Houdini ○ In cases where you need to emit points when a surface is hit (for example a hammer hitting a wall), one method to scatter points is to transfer the hit attribute. ○ Always work with the primitive that will emit points! You don’t need the whole object, only the primitive that will touch the other. The first step is to delete all the geometry except the primitive that will emit the points and the one that is hitting it. ■ Have enough subdivs on the surface where you want to transfer the attribute! If that is not possible because it would require a very dense mesh, simply scatter points! ○ Create a hit attribute and set it to 1 for the hitting object and 0 to the surface that will be emitting points. ○ Transfer the hit attribute and then scatter points. ■ To make the amount of points scattered dependant on the velocity of the impact you can calculate the length of the velocity and then fit it to a 0 to 1 value. ● Inside the scatter you can create different parameters to hold these values. For the above you can create a velocity and scale parameter. ● You only need 1 point to calculate the velocity on the moving object, so the best is to create a point on the centroid of the object and then calculate the velocity with a trail. ○ You can calculate the length/speed with the vlength expression, which needs a vector as an argument, so you can use the vector3 expression as a parameter and use a point expression to get the velocity attribute for every axis. ● Play around with the source min and source max values of the fit. ■ You can also create a min and max attribute which will represent the amount of points you will scatter depending on the impact. ■ To only emit points when the object hits the surface but not when the object is moving back (such as a hammer hitting and then bouncing back. You don't want points when the hammer is going back) you can create a new parameter that will act as a switch and change between 0 to 1. This will be used as a multiplier for the density scale, so when it’s 0 it won’t scatter. ● You can evaluate the velocity of the z axis and if its negative (meaning it's coming back) you can set it to 0. ■ Scatter based on density scale and fit it between the min and max values. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 62/86 4/12/24, 1:15 PM Intro to Houdini Intro to Houdini ● Delete points underneath a surface ○ In a lot of cases you won’t want to scatter points right underneath the surface, only around them. This is done using mainly a ray sop. ○ Create a ray sop and cast the points from the direction of the surface to the object that is hitting it (where there shouldn’t be any points). Turn on Create Point Group. ■ Make sure you only keep the geometry closest to the surface, you don’t want to ray cast all the points onto every part of the object because some of them might be far away of the ground so points are actually scattered in that area! ○ Delete all the points inside of the rayHitGroup. ● Emitting points for volumes ○ After transferring the hit attribute, you want to create a frame attribute and store the current frame number. ○ Add a For Each loop and make it loop on each number and set it to the frame range where points are being scattered. ■ Inside, copy the X value expression of the Each node and make a new Time Shift and plug it into the input. Set the Frame to be the expression of the Each X value. ● stamp(“..”, chs(“../forstamp”) + “1”, 0) ○ Since we will be creating a volume, we need a density attribute, so inside VOPs create a new density attribute. ■ Import (or create) a magnitude attribute and fit it to to 0 to 1 and then plug it into a spline ramp. ○ Connect the spline ramp to a new density attribute. ■ You can connect the density attribute to the Cd to visualize it. ○ Delete Non selected points if $F == @frame (or whatever the attribute holding the frame number is called). https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 63/86 4/12/24, 1:15 PM Intro to Houdini Particle Normals Intro to Houdini ● The normals are very important since they will determine the direction and velocity in which the points will travel. The best is to use VOPs to control the normals. ● You only have to calculate the DIRECTION and the MAGNITUDE. ● The workflow is to calculate the direction first and always try to add some noise to vary it. Once the direction is done, you can work on the magnitude, which means you just need to multiply the direction by a value. Direction ● If you have a hit and want to have points emitting outwards from the surface, you need to subtract the position of one object with the other one and the normalize it. ● To blend the direction of the normals between this outwards position and the direction of the surface, you can mix them with the normals of the object and then add some noise on the bias. ○ For the noise simply create an anti aliased flow noise with an amplitude of 4.5 and simply fit it from -1, 1 to 0,1. Play around with the frequency, offset and roughness You can promote the destination max to affect how much the normals will be blended. Magnitude ● Every point should inherit the velocity of the impact, so the length of the normal should be related to the velocity. To do this you can import the velocity of the impacting object and get the length. ■ You can multiply the output of the mix (which sets the direction) with the length (speed) of the impacting object and finally you can add some noise to vary them. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 64/86 4/12/24, 1:15 PM Intro to Houdini ● To calculate the magnitude of one single object, you can create a Time Shift and set it to $F -1 and then use that as the second input for VOPs. Inside VOPs simply subtract the current velocity by the previous Intro to Houdini frame velocity and calculate the length. Particle Rotation ● Rotation can be achieved in several ways. One way which is hard to make and shouldn’t be used is to control the rotation in the 3 axis, which is done using the orientation attribute. An easier way is to just spin the particle on a selected axis, which is done with the rot attribute.. ○ You will want to end up having an orient/rot attribute after the particles, which will be used by the copy sop for the orientation/rotation of the objects. ● The final goal is to get an axis and an up vector and turn them into a quaternion inside VOPs. ● First calculate a random vector by creating a random node (and set it to 3D point) and output it from the point number. Remember to multiply them to change the seed. ○ Always fit the random from 0 to 1 to -1 and +1 to have positive and negative values! ● Create a second random vector and calculate the cross product with the first random and normalize it. This will be the up vector. ● Normalize the second random vector and create a Look at node. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 65/86 4/12/24, 1:15 PM Intro to Houdini ○ Connect the to, to the normalized vector and the up to the normalized up vector calculated previously. Intro to Houdini ○ Create a matrix to quaternion node and export it as a rot attribute. ● For the axis vector, simply create a 3rd random vector, fit it, normalize it and export it as an axis attribute. ● All the attributes from above will need to be used inside POPs to create angular velocity. ○ Before setting the angular velocity you need to make sure you have a birth group (and don’t preserve it). ■ When applying angular velocity, it gets applied every frame, so you only want to apply it once when the particles are born. ● Create an Angular Velocity node and set the Source Group to the birth group. ○ Randomize their velocity with a rand expression and fit it to whatever values you want the velocity to be (the velocity is in degrees per second). ○ Set the Axis to be $AXISX, $AXISY and $AXISZ so it uses the axis we created in VOPs. ● Add a Torque node (it needs to be there to then add a Drag node that will stop the rotation, if not it wont work). ● To make the particles stop rotating when they reach the ground, you need to have a collision group and don’t preserve it. ● After the collision pop, create a drag and turn off linear velocity and turn on angular velocity. ○ Set the Source group to be the collision group and set the scale strong enough to until the particles stop spinning. ● Make sure you delete the normal and velocity attribute after POPs if you want the copy sop to orient the objects using the rot attribute! The N and v attributes have higher precedence. Particle Pscale ● Inside VOPs, create a random float vop from the point number and connect it to a spline ramp. ● Simply multiply the ramp by a promoted parameter that will be used to set the scale. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 66/86 4/12/24, 1:15 PM Intro to Houdini ○ Export the result to a float attribute called pscale. ● The ramp is used as a lookup table to set the size of every piece. It represent the distribution of the Intro to Houdini scale of each point. ○ Remember to make an exponential curve in the ramp because that is how things in nature look. The pieces will look more real if they are distributed this way. You have a lot of small pieces and the amount of big pieces increases exponentially. Blood splatter ● Create an emitter such as a circle and add a normal to it. Scatter points. ● Popnet, add gravity and make the velocity is varied. ○ Add a force node with noise, and here is what make it look like blood. Tweak the parameters until it looks like blood. ● Add a Particle Surface Fluids SOP after the Popnet and adjust the step size. You can smooth it afterwards. Ground Crack ● Create a surface to fracture like a box and with a curve draw the crack. Resample and smooth the curve ● Poly Extrude (Global tab) the curve in the direction that you want the crack so it cuts through the geometry. ○ Make sure you go all the way across the geometry in every axis. ● Use a transform to have it in the middle of the surface you want to fracture. Set the Y to -$CEY. ● Use a cookie to cut through the surface. You will need 2 cookies, 1 for one side and one for the other. ○ Use the User defined option and select between Inside A/B and Outside A/B. ● Create “crack” attribute after the curve. Set value to $PT / ($NPT -1) so the attribute carries a gradient of the line. ● Point SOP and add color using local variable $CRACK that we created to visualize the gradient. Set G and B to 0 or 1. ● Add a Point SOP and in the Custom tab, and in Name 1 type crack. This allows you to edit the value of an attribute. Set the first scalar value to if($CRACK < 0.4,1,0). ○ The expression will remove the smooth gradient and make it either 1 color or the other. So if the crack attribute is bigger than the number that you put after the <, it will change color. ● Create an Attribute Transfer node and transfer the crack from one side to the other. You want to also have a crack attribute with value 0 on the side of the cookie, and connect the curve with the gradient in the other side. ○ Set the radius and blend. ○ Make sure you have a CD and a crack attribute in both sides so they blend smoothly. ● Group each side of the crack, call it sideA and sideB. Add a transform for each one and move them apart. Set the transform to affect only the group. ● Add a Point SOP and connect the unaffected geometry in 1 input and the separated geometry in the other one. This will blend the attributes and split the ground apart. ● In the T attribute fadd the expression $TZ * (1 - $CRACK) + $TZ2 * $CRACK, and replace the Z with corresponding axis. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 67/86 4/12/24, 1:15 PM Intro to Houdini Procedural brick wall Intro to Houdini ● Create a rough surface with VOPs or a Mountain SOP and then draw a curve where you want the wall to be. ○ Move the curve up in the Y axis so its above the ground ○ Remember to resample and smooth it. ● Create a Ray SOP and plug the curve first and then the ground. ● Create the brick that you will use and then add a resample after the Ray SOP and here we will set the length of every point to be the same as the length of the brick. So set the length to bbox(“../brick”,D_ZSIZE). ● Create a Poly Frame SOP after the Resample so we get every point to have its normals pointing towards the point next to it. Set the style to First Edge and turn off Normal Name and instead turn on Tangent Name and set it to N. ● Add a Copy SOP and copy the bricks into the points. ● To make the next row of bricks be offset, branch off after the Poly Frame and add a Delete Node and delete point 0 based on pattern. ● Add a Point SOP and plug first the Delete SOP and on the second input the Poly Frame. ○ This way we will average the position of the points so they are offset. ○ In the Position of the Point SOP, set it to ($TX + $TX2)/2. This will grab the position of the poly frame points and add it to the position of the delete and then divide by 2. This will offset the points! ● Add a Copy SOP between the brick and this Point SOP. ● To move the bricks up in the 2nd row, add a xform and set the TY to be at the height of the brick. bbox("../OUT_BRICK",D_YSIZE) ● Now you can merge the 2 rows and add a Copy SOP and just duplicate them in Y using bbox("../OUT_BRICK",D_YSIZE)*2 Sparks ● To scatter points only on a certain area create a new attribute called Sparks, and in the Paint SOP just override it and paint where you want the emitter to be. In the scatter node, scatter based on the Sparks attribute. ● Add normals, normalize them and randomize the direction in VOPs. ● Add a Popnet and connect everything. Use Impulse and have it be active only 1 frame every a certain amount of time. Bullet hitting a wall and pieces coming off ● Import the geometry of the gun and delete everything except the primitive from where the bullets are emitted. ● Create a new attribute called bullet and add normals. ● Scatter SOP, but since its bullets, we only want it to emit 1 point. Use the if($F % X == 0, 1, 0) and set X to every how many frames a bullet is emitted. Also randomize the Seed and make sure you scatter based on the bullet attribute with 1 bias. ○ You can also use a curve tool and draw where you want the impact points to be. ● Add a VOP SOP to just normalize the normals of the bullet and add an Amplitude parameter to control the length. ● Add a Popnet and also connect the collision geometry. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 68/86 4/12/24, 1:15 PM Intro to Houdini ○ Make sure the life expectancy never ends and that the bullets stick on the collision. ○ In the Collision node, turn o Add Hit Time Attribute. Intro to Houdini ● After Popnet add a Create Attrib and just type hittime (the one that we created in POPs) and turn on Write Values. This is just to create a local variable for the attribute since we created it inside POPs and by default it doesn't create the local variable. ● Add a Delete SOP and use the expression: $T > $HITTIME + X ○ X is the amount of seconds after the impact that the debri will appear. ○ This will create points that will be the emitters of the debri ● Add a Point SOP and just invert the normals by adding - before the N expression. Vortex Effect ● Create a circle to emit the points and connect it to a Pop network. ○ Source: Set velocity and emit from edges. ○ Alternatively, you can connect the Scatter from the Cone into the Popnet. ● Make a cone defining the shape of the vortex, convert it to a SDF (Iso Offset) and scatter points. ○ Make sure the Top of the cone and the circle are at the same position. ○ You can add a Mountain SOP to the cone (Make sure to fuse the caps) ● Add a VOP SOP (1st input Scatter, 2nd Iso offset) and create a Volume Gradient and connect the Point Position to it. ○ Create a Constant vector with Y = -1 and then create a Cross Product VOP. ○ Normalize the Gradient. ○ Connect the Vol Gradient and the Constant to get their cross product and then Normalize it and output it to the Normals. ● To make the Vortex suck the particles in, you have to make the normals point inwards as they were before, so you can mix the Volume Gradient with the Cross Product to control how much they go inwards. ○ Promote the bias parameter. ● To make them point down even more, create a new Mix and connect the constant with Y -1 and the normalized cross product ○ Create and Add and add both Mix operators. Normalize the output and output it to the PT N. ● To add the direction of the vortex, you need to create a volume, so make a Volume SOP connected to the Cone. Set the rank to Vector. ○ Reference the sampling of the SDF. ● Create a Volume from Attribute SOP so you can transfer the normals into a volume. and connect the first input into the new volume, and the second one into the scatter (points). ○ Set the attribute to N. ● Null at the end, and back in POPs, make an Advect By Volumes and call it. ○ Advect means MOVE. It moves particles based on a volume. ○ Update Force means its modifying the acceleration of the particles (like the attractor) ○ Update Velocity It will just set the velocity to the value from which its sampling the volume. ○ Velocity Scale will control the speed of the particles. ● Add a Force after the Advect By Volumes to add some noise. ● To kill all particles that go beyond the vortex add a Kill POP and set the Rule $TY < 0 https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 69/86 4/12/24, 1:15 PM Intro to Houdini ● To animate the tornado, you can create a Line the same height as the Cone and create a Lattice to deform it. ○ Connect the Cone in the first input, the line in the second one. Intro to Houdini ● Create a Twist SOP and deform the line and connect it into the 3rd input of the Lattice. ○ Set the Lattice to Point tab and turn on Viz Point Specific Radi. Increase the size until it fits the cone. ○ You can add a Sin expression in the Twist strength parameter. ● You can also feed in the Popnet into the Lattice to deform the points instead of the cone before it. Dissolve Effect ● Start by loading the Alembic into the scene. In order to have the object be dissolved, it needs a noise pattern to dissolve uniformly, but before adding a VOP sop, you need to add a Time Shift to freeze the animation, if not the object will swim around the noise and it won’t stay in place. ○ After the Time Shift add a Color sop and make it black so every point has a Cd value of 0. Connect the color into a SOP Solver. ● The SOP Solver will make the noise accumulate and increase until it changes completely to 1 color. ○ Inside the Solver add a VOP sop which is adding Turbulent Noise from the PT position with the current color and it is being fed into the Cd. ■ It has to add the current noise with the current CD value in order for it to increase every frame since this is happening inside a Feedback loop (it will add the value on top of itself) ■ Animate the Amplitude going from 0 o 1 and also the Offset so that over a period of time, the white value of the noise will have covered the whole object. ● Going back to the File with the Alembic, add a Trail sop to compute Velocity and then add an Attribute Copy with the Trail and the Solver connected. ○ Transfer the Color attribute. ● Add a Delete sop and delete non selected by expression if $CR < 0.95. ● Group by expression everything $CR > 0.9 and then delete non selected based on the group, which will result in a small edge from where the dissolve is moving along. These points will be the emission points. ● Add a Scatter SOP after the Delete and set it to Compute Number of Points so its uniformly spread out. ● So far we only created points on the surface of the object, but not inside. In order to create more points inside, create an ISO Offset and connect it directly into the File sop. ○ Scatter points insidet the volume and set the color to black. ● Create an Attribute transfer and connect the old scatter into the second input and the new one into the first one to transfer the point color and velocity into the new points. ○ Add a delete, group and delete as before with the same expression but set it to Points instead of Primitives. ● Merge the old scatter with the new points and write out the points for faster playback. ● Create a POP Network from the Scatter SOP and set the Birth Rate to $NPT (*0.1 if you want to have a fast preview) and set life expectancy and variance. ○ Set Points to Random and Use Inherited Velocity. ● To drive the behaviour of the particles we will use fluids to affect them. Using the shelf tools, create a Smoke Container. ○ The smoke container has a smoke object (everything in Dynamics starts from an object, it is responsible for the initial data, initializing attributes and fields) that is then fed into a solver, in this case a Smoke Solver. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 70/86 4/12/24, 1:15 PM Intro to Houdini Intro to Houdini ○ The Resize Container will set the size of the container to where the fluid is automatically (but we don't need it, so delete it). Pyro Simulations Source ● Animate the shape of the object where the volume will be sourced from. ○ Use a Trail SOP to compute velocity if you want to have vel fields. ● Use the Fluid Source SOP to generate volumes to feed into a Pyro Solver. ○ To generate a volume from the surface of a geometry, use the default “SDF From Geometry” method. ○ If your input is only points, use Stamp Points. ● The division size controls the resolution of the volume ○ Note that doubling the divisions requires eight times the memory. ● Add Noise to the density and Curl Noise to the velocity. Pyro Solver ● Disable the Shape Tab and use microsolvers instead, it gives more control. ● Gas Microsolvers should be connected to the Velocity Update input. ● Enable the Rest in the Rest Fields tab and set Frames Between Solve to 10 and Rest Advection Rate to 1. ○ Remember to add a rest field in the Smoke Object. Source Volume ● Goes together with the Fluid Source DOP, source the volume from here. ● Set the velocity to Add instead of Copy so it’s added to the current velocity in the simulation. ● Animate the Scale Source Volume / Density parameters to animate how much influence they have during the simulation. Setting them to 0 will stop adding density/velocity into the simulation. ● Make sure the SOP to DOP bindings match the volumes you created in SOPs. ● You can mask where the velocity is applied in the masks tab. By masking it with the density, the velocity will only be applied where there’s density being added into the simulation. ○ Not masking the velocity will add velocity everywhere in the simulation (Except where the value of the voxels is 0), which is often good because it will disturb the air ahead of the smoke. Smoke Object ● Only use the smoke object to set the division size and set the maximum size of the smoke container. ○ Using Division Method By Size has the disadvantage that when you change the size of the container, you are increasing the resolution and slowing down the simulation. ○ Use Max Axis as division method ■ This way it will keep the same amount of voxels ■ 600 production quality ■ 300 good for testing ● Use the Enforce Boundaries to clamp the container in any axis ○ Clamping only -Y will look like the volume is colliding against the ground. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 71/86 4/12/24, 1:15 PM Intro to Houdini ● To add a rest field, go to the Initial Data tab and turn on Add Rest Field. Intro to Houdini Dynamic Resize ● Use the Gas Resize Fluid Dynamic DOP in the Pre-Solve input of the Pyro solver. ○ This node will create the smallest possible container around the smoke simulation and increase it as the smoke moves around. ○ The size of the container is determined by the Field Cutoff. If the value of the density is smaller than the cutoff, the container will scale down until it reaches areas that have a density value above the cutoff threshold. ● The default Max Bound method is Initialization Static. This means it will use the size of the Smoke Objects container size as the maximum possible size. ○ If Clamp to Maximum is turned off, the smoke will be allowed to expand to whatever size it gets to. ○ You can also use Initialization Dynamic to make the container move (For example meteor trails) ● If the container is too small and it’s cutting the volume, you can provide a Tracking Object, which the node will use as the minimum size. ○ To provide a tracking object, create a bounding box of your source volume in SOPs using the Bounds SOP. Dissipation ● The dissipation microsolver recreates how smoke dissipates in the atmosphere. It’s controlled by Diffusion and Evaporation Rate. ● The diffusion is a control for blurring the density outwards. It dissipates small particles in the air that move away from each other ● The evaporation rate (in seconds) removes density from the simulation. ○ An evaporation rate of 0.1 means that 10% of the density will disappear/evaporate after 1 second. Turbulence ● The turbulence microsolver adds velocity into the simulation and pushes the density around. ○ This can be useful to create very violent forces but also very light breezes of wind that affect the smoke when it starts to lose its velocity. ● The velocity trails show the velocity in the course of 1 second by default ○ The streamer length is in seconds ○ Every voxel actually stores 1 vector ○ Turbulence visualization shows only the velocity of the turbulence NOT the velocity of the simulation! ● The pyro solver only adds turbulence where there is density, it doesn’t waste resources adding it to empty voxels. Disturbance ● Applies noise in the velocity fields in an area determined the the Block Size. This is the main way to get rid of mushroom looking volumes. ● The Disturbance value is how powerful the disturbance is. ● The Cutoff value means that disturbance will be applied to voxels that have a value that’s lower than the cutoff value. ○ This will disturb the edges of the smoke. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 72/86 4/12/24, 1:15 PM Intro to Houdini ○ If the value of the voxel is less than the cutoff value, disturbance will be applied. ● Set the Disturb Field under Bindings tab to “vel” and enable “Disturb Field is Vector Field”. Intro to Houdini ○ The Threshold Field is the field that will be looked at for the Cutoff value. ● A good technique is to have multiple Disturbance microsolvers that act on different block sizes (Big, medium and small sized chunks). ○ Create 3 disturbance microsolvers and merge them together (Value Hints: 0.3, 0.1 and 0.03) ● The Control Fields allow you to lookup a volume field and it will apply the lookup curve to the values between the Control Range. ○ The Control Influence determines how much the control field will influence the disturbance. A value of 1 will completely control it while 0.5 will influence it half as much. ○ Set the Maximum control range to match the cutoff when using density. ○ If the field has a value of 1, then apply the disturbance field at its maximum. ● A different technique is to use the velocity field as the Control Field to apply disturbance to the parts of the simulation that are moving the fastest. ○ The faster the smoke moves, the more disturbed it should be. ○ By default the Control Field expects a scalar field, so you will have to go inside the digital asset and modify this. ■ Go inside the Disturb Vector Field DOP and inside look for the control_field parameter. Change the type to Vector and use a Length VOP to get the speed. ● The Division Size of the simulation needs to be low enough to be able to see the effects of the disturbance. Divergence ● Divergence makes the volume expand, like in an explosion. ○ Used in situations where smoke was confined and is suddenly released. ■ Examples: Train chimney, factory, cannon firing, etc. ● To add divergence into the simulation, you have to create another source. Wherever the source is, the volume will grow. If you use the default density, it will cause all of it to expand equally. To make it grow in some small parts, just create small blobs. ○ From the Fluid Source used to create the Density, create a Volume VOP and simply multiply the noise with the density. ● Create another Source Volume in DOPs and merge it with the density Source Volume before connecting it to the Post-Solve Input of the Pyro Solver. ○ Use the Expand preset ○ Change the SOP to DOP bindings to use the proper volume name. If you are using density, make sure you source density into divergence. ○ Animate the source volume to control when the expansion will happen. Rest Field ● A rest field stores the position of a volume. It is used to apply noise to a volume. ○ The rest field will be advected based on the velocity, same as with the density. ● The rest field works the same way UVs work for applying texture to geometry. It lets you apply a texture noise that will flow with the density. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 73/86 4/12/24, 1:15 PM Intro to Houdini ● The smoke will advect a coordinate system through the simulation creating some sort of “uvs for volumes” which will allow you to texture the smoke. Intro to Houdini ● On the Dop Import field, remember to import rest and rest2 fields! ● The Frames Between Solve is the amount of frames the rest will be advected before resetting. It can be set to higher values for very slow moving sims. Change this value if your noise pattern keeps jumping. ○ If the value is too high the texture will start stretching ● The rest 2 field prevents the texture from popping when the rest field is reset (determined by the Frames Between Solve). ○ The rest 2 field is offset and resets when the rest field is halfway ● The rest and rest 2 ratio are kept as detail attributes and store how much the 2 fields should blend. Collisions ● Create an SDF and also store the velocity attribute as well. ● In DOPs use a Source Volume and set it to collision. Since it’s a VDB and SDF’s are the opposite, set the Scale Source Volume to -1. ○ Remember to change the SOP to DOP bindings. ● Preview the Collision in the Smoke Object. ● Optional: Mask velocity using density ● The Pyro Solver has parameters to affect collisions under Relationships/Collisions ○ Correct Collisions ■ Prevents density from going inside a collision volume. Sometimes it’s useful to leave it off. ○ Extrapolate into Collisions ■ Gives a sense of stickiness Pyro Shader ● Remap the density in the Shape Tab of the Smoke Field by turning on Use Lookup Ramp ● When applying noise, never use the Offset method, only use Scale (Field * Noise) ● Use the Unified Noise VOP on some geometry the same size of the volume to preview the noise. ○ Use Bias to keep more values near 0 to keep empty holes. ● The scattering phase parameter gives a control over what kind of particles make up the volume. ○ Steam or clouds, are made of of little droplets which transmit light, so light goes through. ○ Black smoke absorbs light. ○ Values higher than 0 will simulate light passing through the volume (Use 0.2 as max) while values lower than 0 will prevent light from travelling through the volume. Rendering ● Volumes are sampled using ray marching. Once a primary ray hits the surface of a volume, it will continue to march through the volume sampling different voxels. ● Volume Quality controls the amount of voxels that the ray will march through. A higher number means more voxels will be sampled. ○ 1 / Volume Quality = Total Voxels Per March ○ A value of 0.25 means that the ray will advance 4 voxels in every march https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 74/86 4/12/24, 1:15 PM Intro to Houdini ○ A value of 1 means that the ray will advance 1 voxel in every march, meaning it will sample every voxel in its path. Intro to Houdini ■ Another way to think about it is how many steps the ray will hit when it goes through the volume. Will it go through one voxel at a time, or will it take bigger steps skipping 10 voxels at a time. ● Increasing Stochastic Samples will increase the shading quality in transparent areas. This is a good parameter to change to increase sampling in noisy areas as opposed to just increasing pixel samples. ● To enable real light scattering in volumes, set the Volume Limit to 1. ● There’s a volume filter on the geometry node which allows you to change how the volume will be filtered at render time. ○ The default value is set to Box Filter with a value of 1. ○ Gaussian and 1.5 is recommended for low resolution volumes (Especially when you have stepping). However it increases render time significantly. ● A good way to optimize render time when using indirect lighting, is to limit what lights contribute to the indirect component. ○ Environment lights are the most expensive to compute. If the effect it has on the indirect lighting is minimal, you should remove it from the indirect lighting contributions. ○ Go to light contributions, and click on the + to add one. Select Indirect lighting (“indirect”) and then turn off the check box. Unsorted Colliders Temp ● export HOUDINI_BUFFEREDSAVE=1 ○ Set the variable when saving over the network Creating a procedural forest ● You need a geometry to scatter points (grid) and an object to copy. You can add noise to the surface. Copy the objects into the points. ● Create a merge and plug the copy into it and the ground into the second to see the ground again. ● Add an attribute create between the mountain and scatter and call it pscale. ● Add a paint node switch on override color and write pscale in the field ○ change merge mode to add or subtract ● Create a LSystem node and plug it into the copy instead of the box. ○ The Lsystem node is a mathematical language for repetitive organic structure like trees, these rules define a trunk, a branch, which is a smaller and twisted version of the trunk, and a twig, etc. ○ Add a transform node if necessary https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 75/86 4/12/24, 1:15 PM Intro to Houdini ○ This node allows you to switch the visibility between the Lsystem and the box. ● To set up random rotations: In the copy node, go into the Stamp tab in the parameters. Intro to Houdini ○ Turn on Stamp Inputs ○ In Variable 1, set a name like treeRotation and in the value write the following expression rand($PT)*360 ○ rand means random and it picks a random number between 0 and 1. $PT selects a point number of the scatter (PT) and multiplies it by 360. ● Between the switch and the copy, add a Transform node ○ In Y rotate type the following expression: ○ stamp('../copy1', 'treeRotation', 0) ○ stamp recalls the stamp function, ../ goes up one level, so it goes out from the transform node into where all the other nodes are, and copy1 recalls that node. treeRotation recalls the variable inside copy 1. And the last 0 means that if it can’t find the variable then it should rotate the trees only 0, meaning nothing. Particles: Forming a teapot ● Create a sphere and a platonic solids node ○ Change the sphere from primitive to Polygons and the Platonic Solids into Utah Teapot ○ Make the teapot larger and move it up in Y ● Create a Pop Network and plug the sphere into input 1 and the teapot into 2 ○ Go inside the Pop Net and create a Source node and set the Geometry Source to Use First Context Geometry (thats where the sphere is plugged in) ○ Go to the Attributes tab and change the Inital Velocity to Add to inherited velocity and increase it to 3 on Y. If you want it to to move only upwards with absolutely no side movement, set the variance to 0 on X and Z. ● Add an Attractor node outputted from the Source ○ Set the Geometry Source to Use Second Context Geometry ● Go up one level and add a Scatter node to the Teapot ● Add a Point node after the scatter ○ Go into the Force tab and change Keep Radius to Add Radius and set it to 5. ○ The Radius defines when the particles will stop being calculated. So if it’s set in 5, the particles will only be calculated on a 5 unit radius around the source that is emitting. By using this, you can define which area you want the computer to calculate. In this case, the sphere has a radius of 1 and the teapot of 2, and they are 2-3 units away from each other, so the minimum radius would have to be 6, but if you want the particles to keep going you can increase it. ○ Change the Keep Radial Force to Add Radial Force It’s an attractor, how strong do you want to attract the particles to the teapot. Set it to 10 ○ Change Keep Force Scale to Add Force Scale. It’s like an ease in, ease out, how quickly are the forces attracting the particles. Set it to 0.2 ● Go inside the Pop Net and into the attractor and change the Attractor Use to Single Point per particle ● Create a Drag and connect it into the Attractor https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 76/86 4/12/24, 1:15 PM Intro to Houdini ● go into the Source and inside the Birth Tab and set the Constant Activation and constant Birth rate to 0 and set the Impulse Birth Rate to $NPT which means number of points. Set the Impulse Activation to $F<50 so it Intro to Houdini stops emitting after frame 50 Hard surface modeling ● Blast operator deletes the faces or primitives of an object. You can just select them and hit delete and the blast will be created automatically. ● Poly Extrude (You can access it from the Shelf) extrudes the selected polygons (hotkey A to select all). ○ Keep Points shared: No will extrude each face individually, average will average them, and normals will keep them all extruded the same amount. ○ Options tab, Output Back = 2 sided faces, turn it on. ● Group operator allows you yo group different primitives/faces of a geometry so you can work only on them. Select the faces you want and in the shelf go to Model - Group. ○ Change it’s name so you can know what it is when you select it later. ● Divide operator allows you to divide the geometry in any way you want. ○ To perform the divide only on the faces you want, you can select the group you created under Group. ○ Maximum edges: 3 is triangles, 4 are quads ○ Bricker Polygons allows you to control the amount of divisions you want. Dynamics · Rigid body collisions Wall fracture ● Isooffset – Creates a volume, made of different boxes. Increase to Uniform Sampling to 100. ● Scatter ● Before fracturing, reduce the number of points in scatter to 100. ● Connect fracture to Voronoi Fract ● Name the isooffset “density” ● Add a Volumevop inputted from the isooffset and plug it into the scatter and the scatter into the Voronoi fracture ● VolumeVop – Add a aaflownoise operator between VolumeVopGlobal1 and Volumevoputput. Make it go from P (position), not desntiy. Also, promote (middle click, promote) Frequency, Offset, Amplitude and Roughness. ● Volume Visualization – Plug it between VolumpeVop and Scatter if the volume isn’t appearing properly in the viewport and change the Density Scale. ● You don’t want the pieces to touch each other, there has to be a small space between them. ● Scale each piece individually – ● Add a connectivity from VoronoidFracture (set it to primitive and type chunk_id into attributes) and then plug it into a ForEach operator. With FOR Attribute Value (set it to Each attribute value and type chunk_id into attributes). Open the ForEach operator and add a transform operator outputted from the ForEach. Set the pivots to $CEX $CEY $CEZ. This will scale each object on it’s own center axis. Scale it so there’s a small space between them. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 77/86 4/12/24, 1:15 PM Intro to Houdini Rigid body solvers for rigid body objects and static solvers for everything else Intro to Houdini Never use the Xform (transform) operator for animation! It doesn’t translate the object, it translates all the geometry! Use the translate in the Object level. Geo cache – The animation is in the geometry, the software reads the movement of every single vertex. This is used to export the animation into any software. Creating dynamics with high poly models. When you have an already animated model, like a crane crashing into a wall, the animation is already done, probably in another software. You can’t just use the initial velocity, its a more complex animation. When that animation is imported, it’s imported as just geometry, and the way it works is that each vertex moves every frame. So Houdini doesn’t recognize the animation, there’s no movement for it, no velocity, it’s just vertices changing every frame. If you check on the Details, it will show no translation, because it’s not the object being moved, it’s the geometry. Also, calculating all the vertices for collisions in every frame will take forever, so the way you do it is creating a collision mesh, which will solve these 2 problems. Basically what it does is creates an object out of the high poly model, like a reference copy, and now it’s not the geometry which moves, it’s the object, so it has a velocity and the simulation can be calculated. One the simulation is working with the reference object, you can just take the data and copy it into the high poly models. Extract alembic geo ● You need to load in the alembic through the Alembic node and then create an Extract Geometry SOP. ● Inside the Geo node with the Alembic, add a Convert node and change it to Polys, and then an Null called Animation. From the Convert, output a Time Shift SOP (make sure Frame is set to $FSTART. Then output a Null called Rest. ○ Animation null will output the whole animation as polys, while the Time shift will only output the rest geometry, thats why its frozen on the Time Shift. ● You can add a new file node with the OBJ (not the alembic) and then input it to the Extract Geo node. Particles and Explosions Vopsop1 ● It creates a network that gives you more control over your particles ○ Create a Vector To Float (Inputted from Point Position). This unpacks an operator into 3 vectors (X,Y,Z) ○ Plug the Y axis into an Absolute operator. This will make all of the values positive and delete all of the negative ones. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 78/86 4/12/24, 1:15 PM Intro to Houdini ○ Add a Float to Vector (Output it to Point Position from the Output) operator to close it. Connect the X and Z from Vector to Float to Float to Vector and the Y from Absolute to Float to Vector. Intro to Houdini ○ Now only particles that are positive on Y will be displayed. ● Vector4 ○ Converts a vector into a vector with 4 components instead of 3. Dust and Smoke Fluid Source ● It creates a volume out of a geometry that will be used in a simulation. ○ The Division size should be kept low, or it will crash! If the sim is not important, it will have a small number, while a cloud will have a big one. ● New Fluid Source, named: Temperature. How smoke moves in the simulation ○ Merge both fluid source operators. Make sure they both have different Noise so it creates a nice effect. ● Turn on Curl Nosie in Velocity tab in the fluid source operators. ● You need Velocity, Density and temperature ● Also, it needs a bounding box which will tell it where to simulate. It simulates exactly the area you need. ● DOP Network - Smoke Object ● Pyro Solver - default solver ○ Turn off combustion ● Add a Source Volume and connect it to the last box od Pyro solver into the sourcer. ○ Turn off Normalize check box for Source volume, temperature and velocity ○ set Activation to $FF == 2 Fluids Fluid emitting source ● Create a Geometry object, inside, a sphere ● Add a transform node, and move it up in Y, then add a scatter node. ○ In the scatter node, you can change the number of points to whatever you want, and the Random Seed so it changes the position of the points. ○ A good technique is to use the expression $FF*2 (or just $FF) so the seed changes every frame. $FF means it gets the number of the current frame, and *2 just multiplies it. ● Create a Null operator outputted from the scatter and name it something like OUT_POINTS ○ Null objects are good for outputting, it allows you to give the null a name which you can use. ● Create a Dopnet node, this node doesn’t need to be plugged anywhere. ○ Inside the Dopnet create a Flip Object and a Flip Solver. The Flip Object determines the emitter and the Flip Solver solves it and outputs it. ○ Connect the Flip Object into the Flip Solver. ○ Inside the Flip Object you can change the particle separation. Also in Guides, set the Particles Visualization to Particles https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 79/86 4/12/24, 1:15 PM Intro to Houdini ○ In Initial Data set the Input type to Particle Field. ○ In the Flip Solver, there is a reseeding option. What it does is creates extra particles in some areas if Intro to Houdini they get too spread out. This is good for some simulations, like filling a container or in an ocean, but if not turn it off. ○ Create a Pop Solver node and plug it into the second input of the Flip Solver. Turn off “Use External POP” and under Collisions turn off “Handle Collisions”. In Solve Mode under Solver set it to Velocity Update. ○ Inside the Pop Solver, create a Source node. ○ In the Source Tab, set the SOP to ../../OUT_POINTS or whatever you named the Null object. Also, set the Emission type to Points (random) and in Geometry Source, “Use Parameter Values”. ○ In Birth you can control the options of the particles. ○ Impulse Activation: If set to 1, it uses the Impulse Birth Rate. It creates whatever number is on the Birth Rate every frame. ○ Impulse Birth Rate: How many particles are created every frame. You can set it to $NPT so it uses the same number from the number of points from the Scatter. ○ uConst. Activation: If set to 1, it will use the Const. Birth Rate. ○ Life Expectancy: How many frames the particle lives before disappearing. ● In the Dopnet, create a Gravity node and output it from the Flip Solver. ● Adding Viscosity/Density/Divergence ○ If you want to use any of those, go to the Flip Solver and they are under Volume Motion ○ You need to enable each of them. The Mix Method can be set to Copy to use the same number, or multiply to multiply it. ○ They each have an attribute name, viscosity, density and divergence. If you set them on, you need to create attributes with those exact names. ○ Once on, go back 1 level inside the geometry, and create a Vopsop node between the Scatter and the Null. ○ Inside the Vopsop, create a node called “Add Attribute”. In the Attribute field, name it either viscosity, density or divergence. You need an attribute for each one of them. Also set the Signature to Float Attribute. ○ Promote the Data Float field. If you open the promoted attribute, you can set the Label to the name to what the attribute does. ○ Now you can control those attributes from the Vopsop. ● Adding a Collision Object. ○ You can copy and paste the transform node from the sphere, and then add another Null and name it SPHERE_COLLIDE. ○ Inside the Dopnet, add a Static Object and a Static Solver. Connect the object into the solver, and then add a merge, and connect the Static Solver first and the Flip Solver second, then connect the merge into the Gravity node. ○ In the Static Object, set the SOP Path to ../../SPHERE_COLLIDE. ● Adding a Ground Plane ○ Inside the Dopnet, add a Ground Plane node, and a merge node. Plug the static object first and then the ground plane into the merge, and then the merge into the static solver. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 80/86 4/12/24, 1:15 PM Intro to Houdini Rigging objects for DOPs Intro to Houdini ● Create a geo node and import your OBJ file. ○ You can add an edit node and select polygons to delete. You can use blast or just delete them on the viewport and it will happen automatically. ● The vertex node is great to fix the normals of an object, just set the Normals to Cusp Normals ○ Turn off Recompute Point Normals if you have a Transform Node! ● Create a null to output the model ● Create a new Geo node where the rig of the model will be. ○ Add an Object Merge node and bring in the model. ○ Create a Voronoi fracture to break the object into pieces. ○ Instead of using a scatter node, which makes random pieces, you can create a box node, output it to the object merge (so the box will be the size of the object, like a bounding box) and if you change it to Polygon Mesh. you can change the subdivs. Then add an Add node and delete everything except points, so now you will have organized points to plug into the Voronoi. ● The vertex node can fix the normals, because Voronoi always changes the normals on the edges for the sake of display, but it can bring problems in rendering. ● Add an assemble node and create a packed geometry. Add a Null for output. Packed Primitives ● The difference between using packed geo and unpacked geo is that if you have a fractured object, you will have a lot of points inside each piece. So if you have like 300 pieces, you can end with thousands of points. By packing it, you make each piece be a point, so you will end up with as many points as fractured pieces. This reduces the time of calculation. ● Packed primitives are low on memory ○ The long way of using the assemble node and doing what it does manually, is creating a Connectivity node from the voronoi, and then setting it to primitive. What this does is it creates an attribute called “class” for every piece that is connected. Then you can add a For Each node, and set it to Attribute Value, and type Class. Inside the Foreach, just add a Pack node. ● If you extrude an object and then you want to pack it, you will notice that the extruded parts aren’t part of the same primitive. So if you extrude 2 planes, the new faces won’t be part of the object. So on the Extrude SOP, check Consolidate Faces to Mesh. If you add a connectivity sop, then it should display the correct number. Contd. ● Make a DOP Network and create a RBD Packed Object and select the rigged object. ● Add a bullet solver and a gravity node. ● Add a ground plane with a static solver and merge it into the bullet solver. ● Create an output node ● Create a new Geo node and call it Cache_sim. Inside make a Dop Import node and select the Dop Network node. Set the import style to Fetch Packed Geo from DOP Net. ○ You can use an object mask by typing what is the object you want to see https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 81/86 4/12/24, 1:15 PM Intro to Houdini ● Add an Attribute node to clean up all the extra attributes that were created. In the Point tab, type * into the Delete Attributes (* means all). On Primitives, delete Dopobject and on Detail DopPath. Intro to Houdini ● Create a ROP Geometry node and set the sim path use the $F.bgeo. Copy the parameter of the path and create a file node and paste it as a relative reference. Now you can cache the sim and see it on the file node. Constraints (Spring) ● To make constraints, you need the full primitives, you can’t pack them. After the assemble node (with packing turned off), create a Connect Adjacent Pieces node and set the type to adjacent pieces. You want everything to be connected in the object, so increase the radius until everything is attached with the line. ○ To see the object while increasing the search radius, set the assemble node to template. ● Add a Create Attribute node and set the class to Primitive and type to string and call it constraint_type ○ The name HAS to be constraint_type (thats the way it’s in DOPs) ○ Under String type position. ● Create on the plus symbol to add another attribute, and call the second one constraint_name and set the class to primitive and type string. ○ Set the string to Spring. ● Add a null to output it. ● Add a null to output the geo from the assemble, but first copy and paste the assemble node and pack the primitives! ● Add a DOP network and inside and rbd packed object with the out_geo, and then a bullet solver with gravity and a ground plane with a static solver. ● After the merge node, add a Constraint Network node. ○ It will give you an error. So pick the constraint network on the parameters and it will still give you an error. ○ You need an input, so create a Spring Constraint Relationship and plug it into the second input. ○ It won’t work, so you need to set the Data Name of the spring constraint to Spring. ○ You can play with the strength of the string. ○ Since the rest length is set to 1 by default, the string will try to get that size if that’s not it’s size. That’s why it will look weird. ● To solve the length of the string issue, go back to the connect adjacent pieces node, and turn on Length Attribute, which will calculate the length between each point. ● Add a point SOP before the null from the output geo, and change the velicity to Add Velocity and delete the channels and then set the speed you want. ○ To only apply it to once piece, on Group, type the number of the piece you want it applied on. ○ On the DOP net, make sure Inherit velocity is checked on the RBD packed object. Glue Constraint ● Make a Connect Adjacent Pieces node and set everything as before and create attributes, but change the String to glue. Make the second attribute the same but make the String Glue. ● When going into DOPs, instead of the Spring Constraint, use a Glue Constraint plugged into the Constraint Network and set the Data Name to Glue. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 82/86 4/12/24, 1:15 PM Intro to Houdini ● You can add a strength attribute on the car rig by adding a create attribute node after the last one, and set the name to strength, class to primitive and type to float and value to whatever you want the strength to be. Intro to Houdini ○ Now when you go back to DOPs, the strength of the glue will be a multiplier, so it will be multiplied by the number you set on the strength. ● To make the strength random, you can go to the attribute create of the strength, and on the Value, type this expression: ○ rand($PR)*20000 ○ where rand means random, $PR means primitive and then you multiply it by a number. ● Pin Constraint Keep a box on the floor: ch("sizey")/2 .rat files ● Rat image files are optimized for rendering in Houdini. If you have a lot of textures that you have to render in Mantra, convert them to .rat so it’s faster. ● To convert a file to .rat open the textport and type: icp <file path> <file path with .rat extension> ○ So just type icp and then drag the picture into the textport and the path will be automatically created, and then drag it again but change the extension to Rat. ○ Press enter and the new rat file will be created. HDR’s in Houdini ● In the help window look for stand alone utilities and you can see a lot of the tools that come with Houdini such as icp. Another one is called isixpack which converts HDR files into Houdini’s native HDR extension. Cloth Simulation ● Different topology will give different results. Try between quads and tris. Try to make the mesh as even as possible. ● You need polygons for this, so use a convert SOP if you need to. ● Stiffness ○ How stiff a material is, the higher the value, the more rigid it will be. ○ Cloth has 3 parameters: stretch, shear and bend. ○ There are 2 type of bend models, weak bend and strong bend. ■ Weak bend is used for cloth objects like silk. ■ Strong bend is used for heavy objects like metal. When using the strong bend model, make sure you use the Float 64 bit instead of 32 in the Float Precision of the Cloth Solver https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 83/86 4/12/24, 1:15 PM Intro to Houdini ● Damping ○ How quickly the cloth loses energy. The higher the value, the quicker the cloth will come back to its original shape. Low values will have a more bouncy effect and it will not regain its shape. ○ Damping should not exceed 1% of the stiffness value. Intro to Houdini ● Cloth Solver ○ Max collision iterations is the resolution for collisions, increase it if there is intersecting geometry. ○ You can disable self collisions for faster results. ○ The friction of an object is multiplied by the friction of the surface! ● Speed vs quality ○ Dont change the solver settings that much. ○ Adaptive substepping should always be on. ○ Substep tolerance: 1-2 = low quality but very fast. 0.1/0.05 high quality but very slow. ○ Only change minimum substeps (increase to 10), but never the max substeps. ○ Float Precision: use 64 bit for more accuracy and for strong bend deformations. ○ Never simulate far away from origin! ● Plastic Deformation ○ It means that cloth won't regain its shape. ○ The Threshold is how much of a deformation needs to happen before it becomes permanent. ● Paint SOP to control cloth attributes ○ There is a way to paint the values of the polygons which you want to be more or less influenced by the cloth. ○ Basically, you create a new attribute (lets call it mult) and with a paint SOP, you paint the values in. High values will be more resistant while small values will be very deformed. This mult attribute will be used as a multiplier for each polygons weight. ○ To create this, create a Create Attribute node and call it mult (point, float, 32). ○ Add a Paint SOP and turn on override color and type mult. Set thee FG color to 0 and BG to 1, 2, 3 or whatever you want the multiplier to be. ○ Paint the weak areas that you want to have more deformation. Sometimes using a wacom tablet wont let you apply paint to erase! So paint with the mouse.stre ■ To visualize paint you can make a point SOP, add color and type a point expression: point(“../paint”, $PT, “mult”, 0) * 0.9 ○ Create a Null and name it Cloth Control or something like that. Here will be all the cloth attributes. All these attributes act as multipliers for the Cloth Objects attributes, so make sure you are aware of it or set the Cloth Objects attributes to 1. ○ In the Null, go to Edit Parameter Interface and create a Stiffness folder. Inside, make a float called Stretch Stiffness, and then Shear Stiffness, Weak bend, strong bend, etc. and the same with a new folder but for Damping. Make sure you name each one in a way that makes sense, so for Stretch Stiffness, use stretchstiffness. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 84/86 4/12/24, 1:15 PM Intro to Houdini Intro to Houdini ○ Create Attribute and inside Houdini Help, go into Cloth Object to see what every attribute is called. For the Stretch Stiffness the attribute is shellstretchstiffness. Set the appropiate name for each. For plasticity it is enablePlasticity. In the value, write the following point expression: ○ point(“../paint”, $PT, “mult”, 0) * ch(“../clothcontrol”) ○ What this is doing is getting the mult value (which depending on the color goes from 0 to 1, so the value is driven by the color) and multiplying it by the Stretch Stiffness value of the null node. This way, the hard parts, which have a value of 1, will have 1000 value in stretch stiffness if the stretch is set to 1000. But values that were painted and have 0.5 value, will only have a 500 stretch stiffness value. Remember that these values are being multiplied by the Cloth Objects values! ○ Create an Attribute SOP and delete the Cd. Then add an out null and now you can make it a Cloth object! ● Cache simulation ○ Create a Geo node, inside a Null called simulation and then add a Rop Output. Set it to only cache 1 frame and select the frame where the object is deformed that you want to cache. Common Expressions ● ch(“path”) - gets the current value of the parameter ● chf(“path”, Frame) - gets the current value of the parameter on a determined frame ● stamp(“copySOP path”, point number, “attribute name”, index) - Retrieves the current value of the specified stamp variable. ● point(“path”, point number, “attribute name”, index) - Retrieves a point attribute value. If vector, index specifies vector component (0=x 1=y 2=z). For color, 0=red, 1=green, 2=blue ● prim(“path”, point number, “attribute name”, index) - Same as point but for primitives. ● clamp(value, min, max) - keeps the value within the minimum and the maximum values. ● fit(value, min, max, newmin, newmax) - Remaps the value from the old range to the new range and clamps it. ● fit01(value, newmin, newmax) - Same as above, but assumes the value is already between 0 to 1. ● smooth(value, min, max) - Outputs a smoothed value between 0 and 1. ● noise(x,y,z) - Returns a noise value for a given position in space. ● rand(seed) - Gives a random number based on the seed value. The value will always be the same for a particular seed. ● length (x,y,z) - Returns the length of the vector. ● distance (x1, y1, z1, x2, y2, z2) - Returns the distance between 2 points. ● if(expression, value if true, value if false) - Gives a choice of two values depending on the expression evaluating to true or false. ● bbox(“path”, dimension type) - Returns the required measurement of the bounding box of some geometry. dimension type can be: D_XMIN, D_YMIN, D_ZMIN, D_XMAX, D_YMAX, D_ZMAX, D_XSIZE, D_YSIZE, D_ZSIZE. ● centroid(“path”, dimension type) - Returns the X, Y or Z position of the center of the bounding box. Dimension Type can only be: D_X, D_Y, D_Z. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 85/86 4/12/24, 1:15 PM Intro to Houdini Houdini expressions can also have mathematical functions like: ● sin, cos, tan, asin, acos, atan, atan2, abs, pow, sqrt, ceil, floor, atof, dot, cross, deg, rad, exp, frac, hsv, rgb, Intro to Houdini min, max, log, log10, round, substr, strreplace. The modulus operation is achieved using the % and boolean logic using <, >, <=, >=, == !=, !. Expression variables ● $PT - Point number ● $PR - Primitive number ● $ID - Unique particle ID (points get reused once a particle dies) ● $TX, $TY, $TZ - Position of a point ● $NX, $NY, $NZ - Normal of a point/primitive ● $CR, $CG, $CB, $CA - Color of a point/primitive ● $VX, $VY, $VZ - Velocity of a point ● $BBX, $BBY, $BBZ - The normalised (0 to 1) position of the point in the bounding box ● $CEX, $CEY, $CEZ - Centroid of the geometry ● $AGE - Number of seconds a particle has been alive ● $LIFE - Normalised (0 to 1) age of a particle ● $XMIN, $YMIN, $ZMIN, $XMAX, $YMAX, $ZMAX - Extents of the bounding box ● $SIZEX, $SIZEY, $SIZEZ - Size of the bounding box ● $TX2, $TY2, $TZ2 - Usted to identify the position of a point coming from the second input of a Point SOP. https://docs.google.com/document/u/0/d/1HjKSSREu1QjosmJ5PRcDj8bRX2Nxo_DVvqJqwawuRU0/mobilebasic#h.hbjlle6xh5co 86/86