> For the complete documentation index, see [llms.txt](https://docs.nosleepcreative.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.nosleepcreative.com/dev/archive/houdini.md).

# Houdini

Houdini is a 3D software known for its procedural generation tools. In short, procedural means:

* Non-destructive setup
* Flexibility and adaptability
* The software does most of the work; you just create the tools

It has a steep learning curve, especially if you have not used a node-based software such as Nuke. It is natural not to comprehend what you are doing when you start out; keep watching tutorials and one day it clicks. To get started, think in "points": if you can manipulate points any way you want, you will have no problem with the software.

## Resources

**Documentation / tutorials**

* [VEX reference](https://www.sidefx.com/docs/houdini/vex/index.html), [VEX language](https://www.sidefx.com/docs/houdini/vex/lang.html), [VEX functions](https://www.sidefx.com/docs/houdini/vex/functions)
* [SideFX getting started](https://www.sidefx.com/learn/getting_started/), [Houdini docs](https://www.sidefx.com/docs/houdini/), [SideFX forum](https://www.sidefx.com/forum/), [HipFlask](https://www.hipflask.how/)
* [Expression cookbook](https://www.sidefx.com/docs/houdini/ref/expression_cookbook.html) and [parameter expressions](https://www.sidefx.com/docs/houdini/network/expressions.html) (hscript)
* Entagma, Rohan Dalvi, [Junichiro Horikawa](https://www.youtube.com/c/JunichiroHorikawa/videos)

**Wikis and repositories**

* [Deborah Fowler](http://www.deborahrfowler.com/HoudiniResources/HOUDINI-RESOURCES.html)
* [Tokeru](http://www.tokeru.com/cgwiki/?title=Houdini), including [Joy of VEX](http://www.tokeru.com/cgwiki/index.php?title=JoyOfVex)
* [Tosin Akinwoye](https://tosinakinwoye.com/2017/01/23/houdini-vex-snippets/), [Kiryha](https://github.com/kiryha/Houdini), [jtomori](https://github.com/jtomori/vex_tutorial/blob/master/README.md), [John Kunz](http://mrkunz.com/blog/08_22_2018_VEX_Wrangle_Cheat_Sheet.html)

**Math**

* Khan Academy, [3Blue1Brown](https://www.youtube.com/channel/UCYO_jab_esuFRV4b17AJtAw)
* [Procedural noise](https://www.scratchapixel.com/lessons/procedural-generation-virtual-worlds/perlin-noise-part-2)
* [Cross product and dot product: visual explanation](https://www.youtube.com/watch?v=h0NJK4mEIJU)

## Shortcuts (Mac)

| Function                    | Shortcut                              |
| --------------------------- | ------------------------------------- |
| View properties             | MMB                                   |
| Reveal properties panel     | P                                     |
| Align nodes / layout nodes  | Hold A + drag (down/right) / L        |
| Move in / out of nodes      | U & I                                 |
| Cut node connection         | Y                                     |
| Radial menu                 | V                                     |
| Network box                 | Shift + O                             |
| Camera views                | Cmd 1/2/3/4                           |
| Delete channel              | Ctrl + Shift + LMB                    |
| Save / load quickview       | Cmd + numpad 6-9 / Space + numpad 6-9 |
| Go to next / previous level | Alt + left / right arrow              |

## Terminology

| Item       | Description                                                                                       |
| ---------- | ------------------------------------------------------------------------------------------------- |
| Object     | Object-type nodes that build transform and constraint hierarchies. Geometry objects contain SOPs. |
| SOPs       | Surface Operators: geometry nodes that construct and modify geometry (polygons to volumes).       |
| DOPs       | Dynamic Operators: simulation and solver nodes. They read geometry from SOPs.                     |
| SHOP       | Shading Operators: materials. Some are hard-coded VEX, others are folders of VOPs.                |
| VOPs       | Vector Operators: node wrappers around VEX, used for shaders, geometry, volumes, pixels.          |
| VEX / CVEX | Vector Expression Language. CVEX is the context-agnostic version used throughout Houdini.         |
| COPs       | Composite Operators for image compositing.                                                        |
| ROPs       | Render Operators: dependency graphs for outputting geometry, sims and renders.                    |
| CHOPs      | Channel Operators for raw channel data (motion, audio). Safe to ignore at first.                  |

## Tips

* After `copytopoint` onto a grid, an `add` node after the grid deletes unused geometry and leaves only the points.
* With more than one node selected, hold alt/option and drag a new connection to create a `merge` node.
* In the TAB menu, type node initials to find it (point wrangle: PW, attribute from map: AFM).

## VEX cheatsheet

```c
// Data types
int x = 18;
float y = 3.142;
string name = "John";
vector v = {1,1,1};
matrix3 m = ident();      // identity matrix
float my_array[];         // arrays: member_type var_name[]

// Attributes
@P  @P.x  @N  @Cd  @Alpha  @pscale  @ptnum
v@myVector = set(-1,-1,-1);
i@var = 1;
@scale = set(1,1,1);

// Loops and conditionals
for (int i = 1; i < 10; i++) { }
if (x == 1) { } else { }
while (condition) { }

// Functions
fit01(attribute, minVal, maxVal);
fit(attribute, ominVal, omaxVal, minVal, maxVal);
rand(value);
normalize(v);
noise  anoise  snoise  pnoise
```

```c
// hscript / expressions
$T  @Time           // time
$F  $FF             // frame (int / float)
$CY                 // copy number (copy stamp)
$CEX $CEY $CEZ      // centroid
$HIP  $HIPNAME      // project path / name
stamp("../copy1", "variable", 0)
name.$F4.jpg        // 0008 padding

// Creating controls
ch('threshold')  chf('threshold')  chi('threshold')  chv('vector')
chramp('channel', ramppos)
```

## Techniques

**Transferring attributes**

* `attribtransfer` for e.g. P, Cd.
* In a point wrangle, read from the second input:

```c
@Cd = point(1, 'Cd', 123456);   // specific point on input 2
@Cd = v@opinput1_Cd;            // same point number on input 2
i@n = npoints(1);               // points on input 2
```

**Copying points**

1. `Copy Stamp` with expressions: good for quick prototyping
2. `Copy to Points` with a SOP, e.g. `circle`
3. `Copy to Points` with `pointwrangle` and VEX

**Instancing random geometry**

* Create several objects (demo1, demo2, demo3) and an `attribcreate` string attribute `instance` set to `/obj/demo`round(fit01(rand(@ptnum),1,2))\`\`.
* With `copytopoints`, give each geometry `i@variant = 1;`, then on the points `i@variant = int(fit01(rand(@ptnum),0,2));` and list `variant` in the Piece Attribute.
* Arnold does not accept packed geometry: add `unpack`.
* For lights, use full point instancing; you cannot see instances until you render.

**Random colour**

```c
rand(@ptnum), rand(@ptnum), rand(@ptnum)                // random grey
rand(@ptnum), rand(@ptnum+25), rand(@ptnum+10)          // random RGB
```

**Random image per copy** (material SOP, `basecolor_texture`, image sequence named `image_04.jpg`)

```c
$HIP/textures/image_$F2.png                                           // by frame
$HIP/textures/image_`padzero(2,ceil(fit01(rand(@ptnum),0,7)))`.png    // random image
```

## Cookbook

Run point wrangles over Detail when generating points.

**Circle of points**

```c
int pt = 18;
float angle = 360/pt;
float radius = 20;

for (int i = 0; i < pt; i++) {
    float x = radius * cos(radians(angle * i));
    float y = radius * sin(radians(angle * i));
    addpoint(0, set(x, y, 0));
}
// copy stamp: 10 * cos(10 * $CY) and 10 * sin(10 * $CY)
```

**Phyllotaxis** (Vogel's formula: r = c√n, θ = n × 137.508°)

```c
int total = chi("total");
float cval = ch("cval");
float zdepth = ch("zdepth");
float angle = 137.508;

for (int i = 0; i < total; i++) {
    float x = cval * sqrt(i) * cos(radians(angle * i));
    float y = cval * sqrt(i) * sin(radians(angle * i));
    float z = i * zdepth;
    addpoint(0, set(x, y, z));
}
// source: deborahrfowler.com, which also has an orient-attribute version.
// Copy stamp: c * sqrt($CY) * cos($CY * angle)
```

**Random pscale, delete, push along normal**

```c
@pscale = fit01(rand(@ptnum), ch('min'), ch('max'));

if (rand(@ptnum) > ch('threshold')) { removepoint(0, @ptnum); }

float factor = fit01(rand(@ptnum), chf('min'), chf('max'));
@N *= ch('scale') * factor;
@P = @N;
```

**Rotation with orient**

```c
vector r = set(ch('rot_x'), ch('rot_y'), ch('rot_z'));
p@orient = eulertoquaternion(radians(r), XFORM_XYZ);
```

**Bands of colour moving across geometry (one axis)**

```c
@dir = @P.y;
@Cd = sin(chf('offset') + chf('width') * @dir - @Time * chf('vel'));
@pscale = @Cd;
```

**Connecting lines: plexus (Entagma)**

```c
int npts[] = nearpoints(0, v@P, chf('max_dist'));
removeindex(npts, 0);
foreach (int npt; npts) { addprim(0, "polyline", @ptnum, npt); }
```

## Rendering (Mantra)

* Use separate Mantra nodes for test and final renders. Output padding: `$F4.jpg` gives `0001.jpg`.
* PBR engine. Raise pixel samples to reduce noise; keep an eye on min/max ray samples.
* Depth of field in compositing, motion blur in the renderer. Always render EXR.
* Reflect limit 10-15 for glass; turn it down if reflections are not needed.
* Tiled renders (reduce the tile count to 2 for a quick render) speed up tests.
* Preview with flipbook / MPlay, export via ffmpeg to mp4.

**Jason Iversen's PBR settings** ([source](https://www.sidefx.com/forum/topic/21548/))

* Pixel samples 7x7 (up to 10x10 if needed); min/max ray samples 1/9 (sometimes 2/9)
* Noise level 0.08; reflect/diffuse limits 2, 2; gamma 2.2; colour limit 4

**Lighting**

* Distant light is cheap and good for blocking; sun gives blurred shadows. Point lights suit bulbs; disk lights for highlights.
* Warm and cool lights add dimension. Use a light bank (Data tree) to edit many lights at once.
* Instanced lights: pack geometry, `attribcreate`, full point instancing.

## Pyro and smoke

1. Advect particles or points (garbage in, garbage out).
2. Convert to **VDB**.
3. Add `smokeobject` and `pyrosolver` in DOPs.
4. Add detail with microsolvers (`gasdissipate`, `gasdisturb`, `turbulence`).
5. Optimize with `gasresizefluiddynamic`.
6. Cache the simulation.
7. Texture and render.

Division sizes: 150 (sketch), 300 (detailed), 600 (high quality); use Takes to toggle. Override divisions to about 50 for visualizing guides. Use OpenCL if you have a good GPU. Temperature creates velocity. Shadows missing in the viewport? Enable HDR rendering in viewport preferences, Effects tab.

Docs: [Pyro solver](https://www.sidefx.com/docs/houdini/nodes/dop/pyrosolver.html), [Tokeru: Smoke and Pyro](http://www.tokeru.com/cgwiki/index.php?title=Smoke_and_Pyro), [Pyro Tips & Tricks, Jeff Wagner](https://vimeo.com/225159293).
