The spaceChange
Utility Node
(plugin, sample shaders and tutorial)
As you certainly know the
position of a point, or a vector can expressed in Maya (actually in all
rendering systems) in different coordinates systems. Most of the rendering
process takes place in the Eye or camera coordinate system, however many
times you'll have to use coordinates for points or vector in shading networks
that you can only retrieve in the World coordinate system or in a
specific transform's Object coordinate system.
If you need basic
information on the concept of coordinate systems, you can get more precisions
in Maya online documentation or any (technical) book about rendering.
Actually all you need to do
conversions beetween these coordinates systems can be found in the « rendering
attributes ». These are described in Maya API documentation in the
section Maya Developer's Tool Kit – Appendices – Appendix C: Rendering
attributes. The shading process will provide them to any shading node that
« asks » for them (that has got an input attribute of the same name).
If you check some Maya shading node in the connection editor you'll see it has
several input attributes, that though are not connected to anything will be
« fed » with the relevent data during the render process. I think Duncan
Brinsmead from Alias|Wavefront did a nice explanation on this some
time ago on Highend3d maya list.
A very useful node in
creating shading networks, the samplerInfo node will provide some of
these rendering attribute as output attributes. However we must have not been
deemed worthy of accessing all these attributes, as indeed only a subset of
them are provided through the samplerInfo node.
So I wrote a small utility
node that will make conversions easier. Converting from one coordinate system
to another is as simple as multiplying a point or a vector by a matrix. So it's
just what this node does, it operates in a similar way to a vectorProduct
node, set to either « Vector Matrix Product » or « Point Matrix
Product » mode. The nice thing is you will only have to indicate what you
are converting (a point or a vector), and from what space (coordinate system)
to what space you want to do the conversion and the node will use the above
mentioned rendering attributes to create the conversion matrix and handle the
conversion for you.
Update! : the 7.0 version that has
been last added
The Maya 4.0 version
: spaceChange40.zip
The Maya 4.5 version
: spaceChange45.zip
The 4.51 version and later
versions now includes « normal » mode in addition to point and
vector mode. Imagine transforming an object, in the case where the
transformation includes non-uniform scaling. Then transformed normals are not
the same thing as the transformed object normals. If what you are after are the
transformed object normals, then use that new « normal » mode instead
of vector.
Version 4.51 for Maya 4.5 : spaceChange451.zip
Version 5.0 for Maya 5.0 : spaceChange50.zip
Version 7.0 for Maya 7.0 : spaceChange70.zip
Also source files are
available here : spaceChangeSources
|
Exemple : the way I handled conversion of
normals from Camera to World space without spaceChange (with a vectorProduct
node). I'm getting the EyeToWorld matrix directly from the camera
because of some issues with the one provided by samplerInfo. Drawback
is, if you want to use another camera to render you'll have to change the
connection manually. |
|
|
The
same conversion using a spaceChange node. Note I also replaced the
clumsy « normalAdd » / « normalScale » part by a setRange
doing the same thing (converting from XYZ range (-1 -1 -1 to 1 1 1) to RGB
range (0 0 0 to 1 1 1). The spaceChange is set to convert from camera
to world space and will receive the correct matrixEyeToWorld
information from the render process whatever camera is being used at that
time. |
|
|
And
the way the spaceChange attributes are set for this conversion here. Note
that the conversion matrix that will have been built and used by the
node is also directly accessible from outMatrix. |
|
So you see there is not
much in it and it's really easy to use. There are two particular
« space » that need a specific explanation though, they are « point
space » (sometimes called tangent space, I'm not sure which
denomination is the more correct/most used, tell me and I'll change it if it
turns to be the other one) and « facet space ».
Point Space describes a coordinates system
where the origin is the point currently being shaded (P as called by
Renderman or pointCamera/ pointWorld/ pointObj in Maya depending in what
coordinates system it is itself expressed) and the 3 axis are TangentU,
TangentV and N (the normal) at this point. In many cases (deforming
objects, and or objects that will be exported to an external rendering engine)
it is the best space coordinate to express normal maps.
Facet Space is the same as point space, except
the geometric (non interpolated) normal is used. It's not to be confused with
barycentric coordinates (that I could add if there is a need for it?), there
again tell me if I'm wrong in the choice of the name, I'm not very sure what
« proper » name should be.
In orthogonal coordinates
systems, axis vectors are expected to be... orthogonal. Depending on how the UV
are set up on your objects, there are fair change it won't always be the case. Rebuild
UVN will take care of just that, by rebuilding V from U and N if you set it
to « keep U » and by rebuilding U from V and N if set to
« keep V ». If left to simply « keep » then
it will use the provided U,V,N triad, wether they are orthogonal or not.
Notes and limitations : I have tested spaceChange in all
conversion combinations and it works as expected when rendering, however I
often use it in shading networks I need to convert to file textures. Then in
the baking process you'll notice some of the render data attributes are
incorrectly provided by Maya (or incorrectly recovered by the « convert
to file texture » process. These are :
·
TangentUCamera
and TangentVCamera
on polygons. Very annoying as they're essential to convert to and from
point/facet space!
·
The
matrixWorldToObject and matrixObjectToWorld : seems identity matrix is provided when
querying these during a « convert to file texture »
Also the samplerInfo
node's output attribute matrixEyeToWorld will not always update
correctly (its Duncan Brinsmead again who helped a lot and shed some
light on the problem on the Highend3d maya list server), and besides, Maya's
own « convert to file texture », as well as rayDiffuse's rayBake
and Mental Ray « convert to file texture » fail to get the
correct value for several parameters. Luckily there ARE workarounds! To read
more about these check : baking process issues and
workarounds
Olivier Renouard
olivier AT drone DOT org