Thursday, June 15, 2006

Rib attributes in a Slim Template

Listening to : Blue Jam

Here's the syntax for adding a Rib attribute to your Slim Template, so that it appears as a built in control.



collection void RIB {
state closed
ribattribute string "shade:transmissionhitmode" {
label "shadeTransmissionHitMode"
default "primitive"
subtype selector
range { "primitive" "primitive"
"shader" "shader"
}
}
}

Wednesday, May 31, 2006

Rotation Matrix from Axis Vectors

Listening to : The Decemberists (various)

This is an oldie but a goodie, and I haven't posted it anywhere else, so here it is before I forget.

If you want to make a rotation matrix ( 4x4 ) so that you can make objects orient the same way as, say for example a normal and a tangent on a surface, so long as you have 2 of 3 of the desitnation "axes" then you can build a matrix directly from copying the values of those vectors. (if you do only have two, you get the third from doing a cross product).

I'm using row major notation here - so anyone who needs this column major, just transpose it.
I'm also assuming that the space of the sought rotation matrix is the same space that the vectors are in. (e.g. world space)
Lastly we're assuming that the normal and tangent and binormal are all normalized.

So, you have a normal and a tangent in (say) world space and you want a rotation matrix so you can apply the same orientation to other objects. This is the same as making a new coordinate system and transforming them into it without any rotation at all in that new coordinate space.

It helps to think of normal and tangent, and the 3rd vector called the 'binormal' (which is the cross product of the other two) as the axes of a space into which we're transforming.
It can be any order really, so lets pick :-
Normal = +Y axis
Tangent = +X axis
Binormal = +Z axis

So we have (for example)
+X vector is ( 0.670014, 0.541446, 0.507856 )
+Y vector is ( -0.609193 0.791979 -0.0406534 )
+Z vector is ( -0.424223 -0.282144 0.860482 )

So our 4x4 matrix will be
| Xx Xy Xz 0 |
| Yx Yy Yz 0 |
| Zx Zy Zz 0 |
| 0 0 0 1 |

which in our example gives us the following 4x4 rotation matrix !
| 0.670014 0.541446 0.507856 0 |
| -0.609193 0.791979 -0.0406534 0 |
| -0.424223 -0.282144 0.860482 0 |
| 0 0 0 1 |

So all that any rotation matrix consists of, is the three axes vectors that define it as a coordinate system.

To rotate a plane by -45 degress about X in MEL, you'd do this
// -45 degrees in X
xform -m 1.0 0.0 0.0 0.0 0 0.707107 -0.707107 0.0 0 0.707107 0.707107 0.0 0.0 0.0 0.0 1.0 pPlane1;

Where 0.707107 is of course 1/sqrt(2)

Tuesday, April 18, 2006

Accented Characters on Linux

Alt Gr + ;
e
= é

Alt Gr + ;
a
= á

Alt Gr + '
e
= ê

Alt Gr + '
a
= â

Alt Gr + #
e
= è

etc.

Friday, February 24, 2006

Faking depth in a cyc arena


Listening To : Prince, Raspberry Beret

A problem that came up during Flyboys was that we had a tiled arena floor that was 10kms square, but beyond that we had a matte painting 'cyc' aka cylindrically projected onto a bowl shaped geometry with vertical sides.
When rendering a Depth pass or secondary output, when a camera following the action got close to the bowl, then the colour information in the matte tells you there are things far away in the distance, but the depth (as in length(I) ) doesn't. The depth values decrease rapidly as you approach the sides of the cyc.

Not what we want at all.

So if its safe to assume the ground continues in a near-planar fashion in all directions out to the horizon, we can do a very simple, quite elegant cheat to work out what the depth would be, if the cyc wasn't there.


Breifly (see diagram also):

float S = 1;
point P = transform("world", P);
point E = transform("world", E);
vector I = vtransform("world", I);

if ( ycomp(I) < 0 ) // I.e. point being shaded is closer to ground than the camera
{
// S is some scale value we need to solve to scale I upto;
// I' = P'-E
// ycomp(P') we know is always zero
// therefore we can solve the scale for ycomp and use it to scale I (similar triangles)
// P' = E + I*S;
// so;
// ycomp(E) + ( ycomp(I) * S ) = 0;

S = ( -ycomp(E) / ycomp(I) );

I = vtransform("world", "current", I*S);

// Voila, our new fake (clamped) depth is;
depth = min( length(I), 65535 );
}
else
{
// E.g. plane is upside down, etc.
// Just Set depth to Max ( 65535, which is the largest value our EXR's can store )
depth = 65535;
}

Friday, January 20, 2006

occlusion, subset and the minus sign

Listening To : 'The Now Show', Radio4.

I didn't know that you could negate subsets the same way as you can for light categories, but it totally works. You need to assign the group via rib attributes, to the geometry.
e.g.
Attribute "grouping" "string membership" ["noRflOccl"]

Cool.

Monday, January 16, 2006

Current Project Path via MEL

Listening To : "Its Art, Dad!", The Clientele

Here's a handy tip. How do you get the current project path from MEL ?


string $ws = `workspace -q -rd`;


Voila!