Given a checker pattern consisting of completely random colors, what is the best method of converting these colors into normal information creating a slanted surface in two dimensions wrt the surface normal? Using a slider to increase the effect, tiles would be tilted in random directions and not produce any black artifacts. In this post you can see how I normally do it, but it will always slant in some fixed direction (although in a random amount) and always produce black artifacts way too early (meaning using proper geometry I can get much more pronounced effect). Obviously the (nonexisting) maths is wrong, so I’m wondering what would be the proper math?
Think of it as tiles which are not lay’ed correctly and deviates in tilt and bank angle, which would be easy to spot in reflections.
Subtract a [0.5, 0.5, 0.5] gray to the random color you have, scale it by multiplying with some float, add it to the normal vector and normalize the output.
The explanation: a random color is a group of 3 random values in the interval [0, 1] (the RGB channels). If we think of them as components of a vector, the color will be represented by a vector in the 1st quadrant, where X, Y and Z are positive. If we subtract 0.5 to each component, then we raise the probability of a random color to become a vector in any quadrant. The size of this vector will be less than 1, which is (most of the times) still too big, so we scale it to an even smaller size. We could imagine this operation as a small box with center at the origin, where the vectors are limited to.
If we add this result to the normal itself, we will get another vector. If we scale the random color to allmost 0, the result will be very similar to the original normal. Bigger values will increment the difference of the normal and the final vector, and values above 2 can even result in vectors pointing to bellow the surface, so one must be carefull.
Because the resulted vector is not normalized, we perform that last step and use the final vector as the new normal.
If both color and normal are uniform inside the tile, then each tile will end with it’s own new random normal… Ideal for all those hand made imperfections when placing perfect flat tiles in place!
See link in original post for the generator setup. Basic idea is plank lay within tile are less inaccurate than the full tiles. Color outputs also controls reflection color (for illustration). I’ve tried subtracting grey prior to separating (blue channel is replaced with a one) which only made the problem worse. Also normalizing the mix node (prior to mixing with bump mapping node) also didn’t help much. Influencing blue seems to push the reflections in or out (could be used for “height mapping” or something maybe?), and the bad effect is decreased if the blue is fixed at a higher number (say 4), but I don’t want that because of the push/pull effect.
Note how the tiles around the red ball goes black from “bad normals”.
From what I can gather, I need to do some trickery based on which direction I’m viewing from. I’ve tried looking at Ace’s bumpmap fix node, but I can’t really grasp what is going on.
try to keep the final normal close to the original one. In terms of realism, very small tilting values give better results, and won’t produce the typical artifacts on glossy surfaces (which are caused by normals being too much different then the surface being rendered, and reflecting the inside of the mesh).
Normally, when doing real parquet floors, rulers are used to level things up; the floor is sanded after; and the final surface is almost flat (thought not so quite as the geometrical surface we use in blender!). So just a small amount gives the best result
They’re not caused by being “too much” (I think), but rather that they are causing the reflected ray to point into the geometry. I can exaggerate the above to have some massive distortions, but it will increase the frequency of “bad normals”. So basically, is there a way to identify normals that would cause a black reflection and then “flip it” (one or both of the x and y components, the z component seem to be very close to 1, forcing it to 1 doesn’t seem to cause much of a difference although I suspect its a “distance modifier” or something)?
Basically something like this:
Some calculation involving surface normal (original) and incoming.
Check if modified surface normal x exceeds some value based on point 1.
If it does, then flip/negate x such that reflected ray would not point back into geometry.
Check if modified surface normal y exceeds some value based on point 1.
If it does, then flip/negate y such that reflected ray would not point back into geometry.
Considering x:
Angle between camera ray and unmodified surface normal is 2° (close to gracing).
Angle between camera ray and modified surface normal is -3°, resulting in -1° which is then flipped to +1° causing a nonproblematic reflection ray.
For simulating random lay, I believe this would work very well at least for stills.
The “bad reflection” stems from a relatively extreme angle of incidence i.e. what secrop said about bump strength still applies.
If you really want to use extreme camera angle from camera that is close to the floor you are likely better off with some form of displacement or even using an array modifier on a low poly mesh of a tile to build that floor from. In theory some form of parallax occlusion mapping could also help a little though, the thing is there’s no built in node for that. Then again, why not just plug your tile height into displacement?
But the problem is view (direction, not grazing angle) dependent, why? Random tile color output (replacing blue with one) has no problems with camera at northeast corner, and massive problems with camera at southwest corner (looking at the center of the scene). That is with plugging the raw random color (blue 1 though) directly into normal, not via normal mapping node. In my mind that would tilt face forward and backward of up, and bank left and right of up, equally distributed with half of them becoming bad always. But that’s not what I’m observing, instead bad or good normals are dependent on viewing direction. Which is why I think there is a way to counter the effect (at least for flat floors and stills).
The counter for the effect would be a huge ass hack and would only look “better/right” precisely because it would be wrong.
And yes, the problem is view dependant since the raytraced result of normal mapping is. If your normal map strength is strong enough on a flat plane the resulting ray would be shot from the sampled point on the surface away from the camera. Now if you were using say micro displacement you wouldn’t even see that point since there would be geometry rendered in front of that point, get it?
Ray’s that don’t reach the camera aren’t and shouldn’t be rendered, right?
So try normalizing your data before you plug it into your shaders normal/vector input.
(vector math node offers the function I believe)
To avoid the glossy artifacts, you can use this nodegroup instead of AceDragon’s setup. This just because Ace’s setup just works with grayscaled textures to be used with the bump node; but as soon as you start manipulating vectors, you’ll need my setup (as it works on vectors and correctly calculates theparts where the artifacts occur.
I can get the top post one to equalize the amount of good and bad normals so that “half of them” (depending on grazing angle) will always be bad no matter the viewing direction, and utilize the fix. However, that obviously only completely flattens the bad normals (due end selection mixer mixes with Geometry Normal). I can also modulate the “small float” to vary with grazing angle. I would probably do something like this for animation, since at least the normal quadrant orientation is static.
But, ideally I would like to mix in with something else than surface normal when the dot product goes bad. I tried something like "if dot product bad, then replace a component with negated component. Add together the components and use the result as a “fixed” normal. But I wasn’t able to succeed.
For a floor (ignore z), would I have to do this check three times?
Check bad dot.
Negate x. (x=x*-1, y=y).
Reassemble and check bad dot.
Negate x and y. (x=x, y=y*-1).
Reassemble and check bad dot.
Negate x. (x=x*-1, y=y*-1).
Reassemble and check bad dot.
In my head, one of those dot checks should turn out good. Maybe rotating the incoming angle based on quadrant checks would help? This probably wouldn’t work for animations, as normals would flip to produce a good dot.
“would only look “better/right” precisely because it would be wrong”.
To me, looking good for everyone is better than being correct known only to me.
Why would we even bother with normals if microdisplacement is a solution? Floortiles and planks could also be properly modeled to have this slanted lay inaccuracy, easily even. But modifying normals is cheap, and I’m a big fan of cheap (by force). Just takes a hell of a lot more effort to learn to do it correctly
The ‘bad normals’ are always bellow 0, so they are fixed anyway. But now the mix is driven by an exponential curve that makes a transition between both normals near the problematic ones (a bigger value in the Value node let’s more textured normal into the surface, and smaller values reduces the overall bumpiness).
For displacement, a gradient with a random rotation for each tile may be sufficient.
Thanks, I’ll be trying it out. Although I’m pretty satisfied with the end result I’m getting now. Significant lay inaccuracy (equal distribution of bad normals with “small float” influenced by grazing angle, combined with (large) profile bumps using Ace’s setup. I’ll post an update when I get time to clean in up. Here is a test render: