Boat hull displacement

Started by sboerner, January 10, 2023, 11:35:57 PM

Previous topic - Next topic

sboerner

A lot of my scenes include open, shallow-draft boats and I've long been frustrated by the lack of a simple way to create accurate displacements for the hulls. I've tried painted shaders or displacement masks made by hand in Photoshop with mixed success (and it's  not much fun).

Here's a technique that (I think) solves the problem. I've tested it a bit and so far it works pretty well. The displacements it creates are precise so there's no manual painting or guesswork. It takes a little advance work but once that's done the same setup can be used for future projects.

First, create a scene with *no* displacement or surface details, just a perfectly level planet surface.

Place the finished boat model at the scene origin and invert it vertically by changing the Y scale to -1. Assuming the model was saved with its origin at the waterline (which of course it was, wasn't it?), the part of the hull that was below the waterline will now protrude above the planet surface and (very important) will be a mirror image of the original.

Set up an orthogonal camera with its XZ coordinates set to the scene origin, facing down directly above the hull. Set up the camera and renderer to create a square image large enough to include the exposed hull. Use round numbers for the dimensions. Add a render layer to output a surface position layer.

Render the layer.

Now, in the actual scene, use an image map shader to place the surface position image at the boat's position and orientation. Set the dimensions to match those used to create the rendering.

Under the Colour tab, select linear data. We only want the Y (green) component of the image, so enable Multiply RGB and set red and blue to zero.

Feed the image into the function slot of a displacement shader downstream (pun intended!) of the water shader. Set the displacement to -1. If the water is reasonably still (low wave roughness) this should make a perfect cast of the hull in the surface.

In the examples here, I included a surface shader to the network with smoothness set to 1 to flatten the water surface before the displacement. The surface position image masks this shader, with a bias scalar node inserted to adjust contrast. Displacement is set to -1.1 to provide a little wriggle room.

The displacement will need to be tweaked -- scale, position, magnitude -- as the the water roughness increases. It seems to work best when the displaced surface falls inside the mesh of the vessel's sides (inside the planking, so to speak). That mitigates the odd reflection and other artifacts that might show up depending on the light angle.

In *very* rough seas this probably won't work at all. But then, you shouldn't be out in that kind of weather in an open boat anyway, should you? :)

Once the surface position maps are made they can be stored with the models for later use. I didn't do it here, but it's a good idea to include the dimensions of the map in the filename ("bateau111_surfacePos_12x12.exr") so you don't have to remember them. And the basic scene used to create the render layer can be saved and used for future models.




Hannes

Cool and clever technique, Steve! Thanks for sharing.

Dune

That is indeed an improved technique over the one I used, so thanks for the idea, Steve. I used to do a screenshot in Lightwave of the hull at waterlevel and make a flat map for every boat, this is way better. I guess you can also make a greyscale of just the Y and save as tiff instead of the exr.

Speaking of negated X (orZ) of a model; I often use that technique to get 'another object' for pops or single objects, whatever it may be, people, trees, etc. It's flipped and looks different. The only thing to think of is to set 'flip normals'.

sboerner

Thanks. It seemed like it might be worth sharing. If you extract the green channel it probably should be saved out at 16-bit . . . I was looking for an "all-Terragen" solution that didn't involve a round-trip through Photoshop. One nice feature of using .exr is that the floating-point pixel values, I think, are equivalent to TG units -- a green value of 0.364 is 36.4 cm vertical displacement.

Flipping models on the XZ axes is a great idea, too.

mhaze


WAS

Awesome job! I'd say the only problem is TG itself. It reads that tiny little space between the boat as open space, so you get pure light casting from the hull of the boat, which should be inverted and much darker due to the object actually blocking the sun.

Dune

I doubt if you would really notice that, but technically that seems to be true. I would therefore make it so that it's as far on the inner side of the boat as possible. You could even make the area displaced downward pure black, which might help.

Quote from: sboerner on January 11, 2023, 09:52:14 AMan "all-Terragen" solution
would be great, as that would imply collision control. Good for trees as well. But rather (extremely) complicated to achieve technically, I imagine.

sboerner

QuoteAwesome job! I'd say the only problem is TG itself. It reads that tiny little space between the boat as open space, so you get pure light casting from the hull of the boat, which should be inverted and much darker due to the object actually blocking the sun.
This is why it's a good idea to insert the displacement into the walls of the mesh. That seems to fix some of these issues, anyway. Practically speaking that means scaling the displacement map slightly in X (so instead of 12 x 12, use 11.8 x 12 or similar, or scale it in the transform input shader used for positioning) and Z as well if you want to tighten it at the bow and stern.

And of course there are always cheats . . . depending on the angle you could have some water intruding into the open interior of the boat, so long as it's hidden by the mesh, i.e. the near hull wall and gunwale.