Boolean experiments in Substance Designer
This is the first blog entry I wrote on my Artstation blog about a year ago. I though it would make a good first post here just to start things off and have everything in one place. Let's hope I'll have more stamina with with blog (haha!)
A few weeks ago I read through Luc Chamerlat's very interesting Artstation blog post in which he used Substance Designer's 3D Cube GBuffers node to create a fully rotatable dice that always shows the correct amount of eyes (you can find it here)
That got me thinking: how far could one actually push Substance Designer's 3D modeling capabilities? As a first little experiment (that turned out to be way bigger than I expected *cough*), I tried to create nodes for Boolean operations on 3D cubes: union, subtract, and intersect. Technically there is also difference, which removes two objects' cross-section from their union, but that operation is pretty rarely used, so I focused on the other three. The 3D Cube GBuffers node also provides a variety of different output: position, normal, depth, and UVs. As depth is most important in my view, I gave it most of my attention. However, normal information was needed for internal calculations, so my nodes ended up outputting it as well.
But first of all, I would need a way of moving cubes in three dimensions. After all, the classical Transform node only concerns itself with 2D displacements. I pimped it's offset parameter with a function that takes a 3D offset and orientation and figures out the correct 2D displacement, so objects would seem to move in 3D. This orientation has to match the one fed into the 3D Cube node, otherwise the illusion breaks. The simplest way I found was to create a graph parameter to drive both the orientation in the 3D Cube and the 3D Offset node.
The 3D Offset node can displace a texture 3-dimensionally. So so it looks at least.
As
the view is orthographic, we thankfully don't have to care about
perspective distortion or objects getting smaller as they travel into
the distance. But what we do have to care about in the case of depth
textures is the change in pixel value representing the distance to the
camera. For this I wrote a Pixel Processor node that calculates the
object's displacement along the z-axis (the depth) and adds/subtracts
the same corresponding value from every pixel. Except for perfectly
black ones, as they are considered to lie at infinity. The amount of
pixel value adjustment can be controlled via the depth adjustment parameter, so the node can also be used to offset other textures than depth-maps.
The
only thing missing now to create a union operation is a second Cube 3D
node provided with the same orientation and a blend node set to Max (Lighten).
Voila! One can, of course, add even more objects to this, offset the
orientation of one of them or use other objects than cubes entirely!
Node setup for a Union operation.
Sadly,
the equally useful subtraction operation wasn't nearly as easy to
implement. Because of that, it has some considerable limitations: it
only supports two axis-aligned cubes. But hey, at least you can make
some cuboid pipe, vase or whatever. Some of these things the Shape Extrude
node can't do. The cross-section node faces the same limitations and is
even less useful. Apart from minor details, it can basically only
create shapes that a simple Cube 3D node can achieve.
The output of the subtractive Boolean node
But
why these limitations? As the transformation formulas involved can be
pretty tricky, visual feedback was very important for me to wrap my head
around this. So I started by piping outputs of the GBuffers node
through others, hoping that at some point something like a subtraction
would emerge. But after seeing what is possible with this approach, it
seems to me that you have to do all the calculations in Pixel
Processors. Maybe someday I'll come back and try different approaches,
but in my view, the current possibilities of the function graph make
working with it too much of a hassle for a reasonable payoff. In the
meantime, I will publish all the nodes I produced during this
experiment, in the hope that someone gets inspired to tackle the problem
himself. Just think about it, how awesome would it be if we someday
have some simple ray marching implementation in Substance Designer that
allows us to create all sorts of different 3D shapes!? These are the
things that keep me awake at night.
PS: You can grab the nodes for free in my Artstation store.
~David
Comments
Post a Comment