4
$\begingroup$

I have a handful of these strange normal maps I need to use in my scene that store X in the Alpha channel, Y in the green channel, and require you to calculate Z with the following formula:

Z = sqrt(1 - (X * X + Y * Y))

Red is always 100% and Blue is 0%, but these channels are not used.

Despite figuring this much out, I haven't been able to produce a node setup that can correctly convert this into the desired purpley tangent space normal map.

Any ideas?enter image description here

$\endgroup$
  • $\begingroup$ Do you want to keep them in this format? $\endgroup$ – StarWeaver Mar 27 '18 at 8:11
5
$\begingroup$

Ok, first thing is to split out the channels with the separate RGB node. We'll put down a few re-routes too so we don't go nuts and mix channels up:

putting down the separate RGB

Next, put in a Combine XYZ node to recompile the channels together. (note that you can use a Combine RGB node here instead of you like, they are identical aside from labels and the color of the output socket. Color and Vector and both a generic vector3 format inside Cycles, they are only differentiated for UI clarity reasons).

combine XYZ added

Now, currently we have Z=0. That's not going to work. As you noted in the OP, we need to derive Z from X and Y. The reason for this is that X and Y have already been normalized so the full XYZ vector is in a 0-1 range. Thus we can't just shove a 1.0 in there, we need to actually compute Z using the forumla you have above. (note that this setup is exactly what the Unreal 4 engine DeriveNormalZ does under the hood).

First the multiplications within the parentheses, X * X and Y * Y: multiply node

Then sum the result: add node

Subtract that from 1: subtract node

Now we need the square root of that result. That's the same as raising to the power of 0.5, so one more math node: power node

Finally, the particular normal map you provided appears to be DirectX formatted, so we need to flip the G(Y) channel too: complete shader

And it works! final rendered result

$\endgroup$
  • $\begingroup$ Thank you! I was doing something somewhat similar, but I ended up swizzling the channels from 0 to 1 to -1 to 1 and doing a couple of other things differently $\endgroup$ – DejaVu_Loop Mar 27 '18 at 13:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.