We are currently trying to export our scene to the USD format.
For normal textures, if we already have a tangent-space normal map with values in the 0,1 range, why do we need to remap it to the -1,1 range? What is the purpose of this transformation? I came across the following documentation mentioning this step, but it doesn’t really explain the reasoning behind it.
“Expects normal in tangent space [(-1,-1,-1), (1,1,1)]. This means your texture
reader implementation should provide data to this node that is properly scaled
and ready to be consumed as a tangent space normal.
If the texture has 8 bits per component, then scale and bias must be adjusted
to be (2.0, 2.0, 2.0, 1.0) and (-1, -1, -1, 0) respectively in order to
satisfy tangent space requirements. Normal map data is commonly expected to be
linearly encoded. However, many image-writing tools automatically set the
profile of three-channel, 8-bit images to SRGB. To prevent an unwanted
transformation, the sourceColorSpace must also be set to “raw”.”
The constraint/expectation is specifically attached to the specification for UsdPreviewSurface, from which you are quoting. It’s not a declaration about “the cosmically right way to do normal mapping” , it was the decision our graphics folks made to keep the PreviewSurface code simpler, pushing the transformation it would otherwise have to do itself out into the UsdUVTexture node/implementation, since we needed to provide a basic value scale/offset ability for that node anyways.
So, to have the correct rendering result, should I set these two factors in UsdShadeShader in general? I did some round-trip tests for importing the USD file into our system first, and then I exported the file by setting this transformation. It seems that I can get the correct result.