Photoindra

Cleaning up AI slop. A manual retopo workflow in Houdini and Marmoset.

We’re heading toward an AI collapse, where everyone and their grandmother can generate videos, images, and complex 3D scenes. But for now, the quality of the low-resolution meshes AI generates is surprisingly poor. In the examples that major services show in their paid Instagram ads, the low-res geometry looks more like ZRemesher output from ZBrush. Same story with the UVs.

And while I’m sure this will keep getting better over time, for now the solution is manual retopology of the AI slop. With Modeler inside Houdini and auto-baking in Marmoset, the process isn’t that complicated.

  1. The reference image was pretty small, so I generated 4K images from different view angles, plus some extra textures of acacia wood.
  1. I generated the high-res AI-slop geometry for the main frog with the paid version of Tripo3D. You can use other free services, but in my tests Tripo produced cleaner results and allowed multi-angle references. Then I generated a separate mesh for the stick, just to try a multi-object workflow later on.
  1. Imported both into Houdini, aligned the axes, and scaled to 1 meter. Retopo done with the Modeler plugin. I compared it directly against TopoGun 3 on several projects, and while I love TopoGun, I probably won’t use it anymore. Direct retopo in Houdini feels much more fluid, and on more complex AI slop it lets me hide parts of the geometry faster.
  1. UVs done in RizomUV. I still think nothing comes even close to it.
  1. Then I imported the UV’d low-res geo back into Houdini. Hardened the UV seams with the “Labs Soften Normals” node and merged the geo back with the high-res. I used groups as the name attribute so Marmoset would later understand it needs to bake from GRP_frog_stick_HIGH to GRP_frog_stick_LOW, and GRP_frog_body_HIGH to GRP_frog_body_LOW. This way I can have two AI-slop materials on the high-res geo with bad UVs, all baked down to one clean 2K UV set. When exporting the FBX from Houdini, just remember to tick the “Build Hierarchy from Path Attribute” checkbox and change “Path Attribute” to name. If you just assign the material inside Houdini, Marmoset won’t like it much – it’s easier to create a string attribute named shop_materialpath on the primitives and give it the name you want to see in Marmoset.

Also, if you assign different colors to different parts of the geometry in Houdini, Marmoset can use them as an ID map for baking. I used this to mask the stick later. You can preview it by switching albedo to vertex color in the material settings.

Then in Marmoset, with “auto-reload” and interactive mode in the Bake Project, it automatically picks up every change I make to the retopo in Houdini. I absolutely love this feature for iterating and making corrections – it’s probably the main reason I don’t bake in Substance Painter.

  1. In Marmoset I created a New Texture Project and linked the low-res frog’s material to it, so I can fix all the strange AI texture artifacts by hand. In general, material editing looks very similar to Substance Painter. I think Substance is still missing a rounded-edge baker, but that’s a topic for another post. In a separate folder I exported the low-res geo for Sketchfab, and used the same folder to export the corrected textures from Marmoset.
  1. This was the first time I rendered videos from Marmoset, and I was surprised by how fast it was. One real downside: you can’t link the render resolution to the camera, so if I want both vertical and horizontal shots, I have to change the resolution manually in the render tab.

You can grab the model for free on Sketchfab.

Will any of this matter in a year, when the meshes come out clean and the UVs aren’t garbage? Maybe not. But until then, manual retopo instead of AI is the way to go. The AI does the boring artsy stuff. I get to do the actual modeling. Yay!

Real directors vs AI Slop – Human Pacing Still Wins

There’s “this will change everything” coming from AI news every day. Tons of influencers claiming that “this will end Hollywood”. And sometimes generated videos even look ok on small phone screens. What’s always lacking is pacing, consistency, and a non-AI-generic look on 4K TV screens.

Higgsfield is an AI services aggregator. I don’t use it because of lots of negative reviews online. They sell you the idea of “unlimited” access but then people find out that it becomes “limited” very fast.
But their promo materials are quite fun to watch. Recently they came up with Arena Zero. A 10 minutes video generated with new Chinese model Seedance 2.0 (Yes, the one facing backlash in the USA for allegedly being trained on copyrighted Hollywood movies). The video was generated by 4 directors (from Kazakhstan and Russia) in 4 days. 2 for pre-production and 2 for color-grading, sound and editing. I’m pretty sure there were other designers involved helping generate scenes.

Important part left behind during breakdown:
How many credits did they use? They talk about “5000 decisions”.
Did they have some sort of “unlimited” access without waiting in line?
Is it limited to 720p only? They didn’t talk about upscaling during interviews.
Also from what I see access to Seedance 2.0 right now is only for “business” accounts and “quick business verification required for access” whatever that means. I guess it is to make sure that the company is registered outside of USA to avoid possible future copyright claims.

But it’s the first time I’ve watched 10 minutes of so-called AI slop and didn’t feel bored.

Links to original videos:
Arena Zero from Higgsfield AI

Arena Zero Full Breakdown: Seedance 2.0

If you want to compare and look at influencer generic AI-slop:

Plasticity to Houdini 21 recipe

I’ve been using a lot Plasticity lately. It’s a simple CAD tool for surface modeling – much easier than Fusion 360 or MOI. I can do modeling with booleans and curves there much faster.
Then I import the geometry into Houdini, and usually my import process looks like this:

  1. Align the axis to the only correct way: Y is up, Z points forward to the viewer, and X points right.
  2. Scale to meters.
  3. Use a Match Size node in case I modeled without real-world dimensions.
  4. If you name your layers in Plasticity they will come into Houdini as a “path” attribute, so you can easily convert them to groups with the Groups from Name node.

To make this transition as easy as possible I use the new Recipes system (added in Houdini 20.5). To share those recipes between my different workstations, I created a recipes.json file inside the Houdini packages folder with this content:

{
  "hpath": "path_to_your_cloud_folder/Documents/Houdini/recipes_folder",
  "env": [
    { "HOUDINI_CUSTOM_RECIPE_DIR": "path_to_your_cloud_folder/Documents/Houdini/recipes_folder" },
    { "HOUDINI_CUSTOM_RECIPE_LIBRARY": "custom_recipes" }
  ]
}

In this setup, when you save a new tool as a recipe, Houdini automatically locks the Save To field to Custom File Path, pointing to:
path_to_your_cloud_folder/Documents/Houdini/recipes_folder/olts/custom_recipes.hda

Here’s example of another recipe that helps process low- and high-poly meshes for baking in Marmoset:

I’ll post more details about this project later, but the main idea is to use crude low-res geo from Plasticity, clean it up in Houdini, and at the same time import mid-poly. Then, use it in combination with Marmoset’s rounded edge baking.
No more micro-beveling inside Plasticity or ZBrush.

Houdini to Redshift: Keeping Colors Sharp

In Houdini, I usually assign color to primitives (though Houdini defaults to assigning it to “points”). However, if you want Redshift to recognize color attributes (using RSUserDataColor), you need to promote the Cd attribute to points or vertices, as Redshift doesn’t interpret it directly on polygons.

Promoting Cd to points will result in color blending when you subdivide the model, which can create blurred colors. To maintain sharp color boundaries, promote Cd to vertices instead, as Redshift can understand vertex-level color attributes clearly.

Pony Halloween in Star5

While everyone is arguing what AI is best to keep people lying on the grass (Stable 3.5 or Flux), I’m using Pony Diffusion to grab some souls for this Halloween and form a “Cult of Ai”.

Was made with AI in ComfyUI on Windows. But you can build similar graph in Colab. Just need to customize the input and output folder paths.

Baking textures with Redshift inside Houdini

I had to bake some texture maps in Redshift inside Houdini. Haven’t seen any clear tutorials on how to do that. So here is short guide.
Let say I created complex material mixing different texures, adjusting them with color corrections and gradients, noises. I’m happy how it looks in the Redshift renderer. And want to pass geometry to 3ds Max and setup materials with Corona.
General ideas is that you need to create custom AOVs to bake all those textures. Link to documentation about custom AOVs:
https://help.maxon.net/r3d/houdini/en-us/#html/Custom+AOVs.html

Here is how a test material network looks like:

Just for visual reference I’m adding black nulls to know what maps I want to bake. And connecting here those nulls to red nodes (StoreColorToAOV or StoreIntegerToAOV). Sadly you can’t use `opinput(“.”,0)` to get the name of connected node in MAT context like you can in SOP. So you’ll need to copy paste names from nulls.

Create separate Redshift render node. In RenderMaps tab set Renders Maps Baking Enable.
If during testing you want to switch fast between textures resolution (from 512x512px to 1024, 2048, 4096) add an integer slider (with range from 0 to 3) to the inteface of RenderMaps tab (I called it indra_res_mult) and in the Output resolution add:

512*pow(2, ch("indra_res_mult"))

If it is black and white texture like roughness or mask use data type scalar. And it will be saved as 8 bit greyscale image in this case. They need to be with gamma 1. But if you render them in Redshift in png it will save in gamma 2.2. So if you want gamma 1 you need to save in tif. And for channels like base color use png.

Things to remember:

  1. No tessellation on obj level. It took me more than 1 hour to figure out why my maps were looking strange and it was just this one checkbox.
  2. No overlapping uvs.
  3. Faces has to be coplanar. I personally didn’t have a problem with this. But in this video for C4D it is recommended to triangulate.

Tips:

  1. If you have assigned groups to geometry and want to use it inside redshift materials: you need to promote it to vertices on SOP level and switch on “Output as Integer Attribute”. You don’t need to create node for each group. Just use GRP_* in group name field. (I usually start names of all groups that I want to keep with GRP_ in the beginning). Then read it inside materaials with “RS Integer User Data” node. Just writing “GRP_group_name” or “group:GRP_group_name” will not work. That’s why we need convert group to integer attribute.
  2. To write those masks you need to use “RS Store Integer to AOV”. StoreColorToAOV will not work.

Flexible Color Assignment in Houdini and Redshift

How do you assign random colors from a specific set to objects and keep the setup flexible for changes with Houdini and Redshift?
Let’s say we have several plastic cups in a scene and 4 specific colors from a client.

  1. Create a class attribute with a connectivity node (you can name it whatever you like).
  2. Promote it to the vertex level with an attribute promote.
  3. In the shader tree, use an RS Integer User Data node to bring in the attribute named “class” (or any other name that you gave it earlier).
  4. Connect it to an RS Jitter node (name it “max_variations_01”) and select “User Data ID” in Input ID Mode. In “integer jitter,” set the min to 0 and the max to 3, so we will have 4 variations. With this node, we only control the number of variations.
  5. Create another RS Jitter node (name it “lightness_range_01”). We will use it to create lightness variations. Keep the color to black and set Saturation Variation Max to 0. Now, with the Value Seed, you can control the randomness.
  6. Create an RS Color Ramp (name it “recolor_01”) with 4 colors from your client and set the interpolation to constant.
  7. After adjusting the seed on the “lightness_range_01” node, you will need to move the colors a little bit on “recolor_01” so each of them will end up in a range generated by “lightness_range_01.”

Another thing that you can do is to offset UVs for each object. So when you add textures for roughness, they will not repeat obviously. To do this, after the connectivity node, add an attribute wrangle node (Run over Vertices) with this:

@uv.x+=rand(@class);

Before:

After:

Modeling low poly pirate ship in 3D

Timelapse of modeling low poly pirate ship in 3d using Houdini, Zbrush, Substance Painter, RizomUV and Redshift:

If you prefer video on youtube with chapters you can watch it here.

Small concept drawing that you see in timelaps I found on pinterest quite a while ago. Sadly I don’t know the author.
You can rotate model in your browser here:

I also passed geometry to Meta Spark Studio to make an IG filter.
Here is link to open filter in Instagram:

If you want to do that there are couple of things to remember:

Search and replace paths in Houdini

If you want to search and replace paths in multiple locations use Windows -> Hscript Textport window

and write:

opchange \$DOWNLOADS"/wetransfer" \$JOB"/geo"

Backslash before variables will allow you to keep variables ($JOB and $DOWNLOADS in this case) and not expand them to full path.

Another case: you imported FBX with materials. You can move them to mat context and change path with this:

opchange ../../materials /mat

Another example: on windows machine for some reason textures are using absolute paths and I want to change them all to the root of the job project:

opchange "C:/Users/user_name/Dropbox/Work/project_name" \$JOB

Documentation:
https://www.sidefx.com/docs/houdini/commands/opchange.html

Zbrush lowpoly modeling and polygroups.

If you ever wondered why during polymodeling in zbrush you keep selecting several polygroups by CTRL+Shift clicking on only one:
Zbrush for most of brushes and selections uses vertices. And if your polygon doesn’t have any other polygon in same polygroup next to vertex that you clicked – it just selects also next polygoup.

So in this case you can use Select Lasso tool and click on one edge to hide full polygon loop. And then invert the visibility by CTRL+Shift dragging outside of mesh:

Earlier Ctrl + ↓