Archive for CG Tutorials

The Importance of Technical Knowledge

CG production is an exciting career. Just look back at the changes that have taken place over the last 10 years and im sure you will realize how fast this industry moves. This industry of ours, so new, so fresh, so desired. Every year at Siggraph I see a large river of young new comers, eagerly applying for the scarce few openings that are available here in the USA.

Amazing how things have changed. I have met plenty of seasoned artists who have shared their stories. They remember how back in the old days (the 90s), big studios would snatch up anyone who had just a little bit of CG training. The demand for CG was so hi and the available talent pool was so small, that studios would pretty much open their doors to anyone who was willing to learn.

I became obsessed with the industry in 1999, effectively missing that sweet window of opportunity by about 4 years. By the time I had reached a level of mild competence, the industry had exploded! Nemo, Monsters, Shrek, Lord of the Rings, The Matrix had all been released and people where flocking in mass quantities to Siggraph. The lines to drop off demo reels at the ILM, Pixar, Imageworks, Digital Domain and Dreamworks booths where huge!

It was Siggraph 2001 and I managed to get acquainted with some industry heavy hitters. Being the young, eager beaver that I was, I kept trying to get information on what would be the best way to break into the industry. One of the industry veterans from Digital Domain, told me; “Learn RenderMan and scripting, for one animator opening, we get 20 to 30 reels, but for 10 technical openings we get 2 reels”. That conversation pretty much changed my life, as I went back home and completely changed the focus of my CG training. Instead of studying how to become an animator, I would learn RenderMan and scripting. Such career change eventually paid its dividends and I am glad to have the technical knowledge that I have. It has opened so many opportunities as a TD with good technical knowledge is always sought after by employers. Granted, I still have so much to learn, but that goes with the territory, as being a TD is a never ending learning journey.

Fast forward 8 years. The industry is very mature by now, the amounts of work being done is huge, with a talent pool that is even bigger. There are hundreds of extremely talented CG artists out there, all competing for a limited number of jobs available. This has made getting into the industry extremely hard. The amount and level of competition, for even the simplest entry level jobs is way higher of what it used to be. With such an environment, it is essential that new comers find a way to differentiate themselves from the rest.

While running TD College, I was lucky enough to meet may young talented artists. There was one in particular that caught my attention. This young artist had sinked a small fortune (around 90 thousand US dollars) into his education. He had received an internship at Pixar and graduated with very good grades. However, a year after graduation, he had still not landed “the” job that would place him in the industry. This artist enrolled in our “Python Programming” course. A course that lasted only 6 weeks but it covered a lot of very important programming concepts. The course was all taught in python, a language that has become the most popular for scripting in the CG industry. With 6 weeks of training, he was able to walk into interviews with new found confidence, applying for positions that he was not even considering before. Well, very soon he landed a job at IMD, then ILM and at the moment is at Dreamworks Animation. How much did he learn in those 6 weeks? Not much im sure, but he did learn enough to get him into the industry. These days this young artist is learning and growing by leaps and bounds, constantly improving his CG skills.

Our industry is a weird mix of talents. So unless you are a complete bad ass on your art, be it modeling, animation, lighting, texturing or else, your chances of breaking into the industry will be a lot higher if you are able to bring some technical knowledge to the table. What kind of knowledge? Here is a list of things that I believe will help anyone trying to enter the industry:

  1. Python: The most used language for scripting. Easy to use, easy to learn but soooo powerful. Python will allow you to script for pretty much every major CG application in the market, as well as develop quick pipeline tools.
  2. C/C++: The most used language in the industry. The APIs for most CG programs is usually in C++. If you want to develop plugins for Maya, Nuke, XSI or Houdini you will need to learn C++. If you want to write shaders for MetalRay, Arnold or VRay, you will also need to use C++
  3. Linear Algebra: Learn how to use vectors,points and matrices. Give special attention to vector operations such as cross and dot products. Learn the properties of vectors as well as the operations when you mix types (point + vector). Learn the properties of matrices.

So dont be afraid of programming or math, they are after all, the backbone of our industry and the stronger your understanding the more productive you will be able to become.

“Take the Red Pill …

..and ill show you how deep the rabbit hole goes” – Morpheus.

One of the coolest lines from one of my favorite movies, The Matrix. So why do I bring this up? Well In the process of writing Equinox I had to implement transformations, which of course means dealing with matrices and linear algebra.

I have used matrices in the past as they are one of those things that you will have to deal with as a TD, specially a shader TD. If like me, you did not have the luxury (or the debt) of a university education on computer science or engineering, then matrices might be intimidating and it might be one of those things that you avoid constantly until you are cornered and you can not dodge them any more.

As I stated earlier, matrices are a necessity in the TD world, but do not dispair, you can use them without really understanding the math theory behind them.  To use matrices all you need to do is understand the output and uses of the most common matrix operations. Lets examine matrices a little closer.

What is a Matrix?

From wikipedia: “In mathematics, a matrix (plural matrices, or less commonly matrixes) is a rectangular array of numbers, symbols, or expressions. The individual items in a matrix are called its elements or entries. The horizontal and vertical lines in a matrix are called rows and columns, respectively”. The following is a picture of a generic definition of a matrix.

A Generic Matrix

Matrices are used a lot in day to day activities. Perhaps one of the most unseen use of matrices are spreadsheets, where if you select a large range of cells and perform an operation on them, the application is performing matrix operations.

How Are they Used in CG?

One of the most common uses of matrices in CG are transformations. Matrices, specially homogeneous  matrices, are elegant data types for these kinds of operations. They are used extensively because a 4×4 matrix (homogeneous) can represent any of the most used afine transformations such as translation, rotation, scale, skew and reflection. This means that software developers have to deal with a single “entity” to handle all their transformation needs instead of having to use vectors for translation, scalars (floats) for scales and 3×3 matrices for rotations.

I.D. Please!

We will not get into much of the math behind matrices on this tutorial, and we will not look at the different matrices used in CG transformations. There is however one matrix that we must cover as it is extremely important for the current tutorial to make sense. This matrix is also essential in many transformation manipulations.

Give this matrix a good look:

Identity Matrix

You see it has 0 on every spot of the matrix except for the numbers that make up the diagonal from top left to bottom right. This matrix is known as the identity matrix and it is special because it represents a transformation set to Translate(0,0,0), Rotate(0,0,0), Scale(1,1,1). So when you create an object at the origin of the world, its transformation matrix is the identity. If an object is parented to another, and its transformation is the exact same as the transformation of the parent, then the child’s local matrix is also the identity.

Multiplying a matrix by its inverse will always result in the identity matrix, so to move an object to the origin you would multiply the objects world matrix by the inverse of the object’s world matrix.

We will not go into the details of how matrices are calculated as I usually like to go over how something “can be used” before I go into “how something works”. Lets take a look into some of the uses for matrices.

Note: All code examples are done in Blender, but the concepts should be applicable to any CG software.

Apply the transformation of an object to another

This is probably one of the simplest uses of transformation matrices. Just store the value of the source in world space and apply it to the destination object.

#
#
dst.matrix_world = src.matrix_world
#
#

Find the position of an object in relation to another

Need to find an object’s position in relation to , lets say the renderig camera? Then just invert the world matrix of the camera and multiply it by the world of the object.

#
# Make sure to perform this operations in this order as
# A*B != B*A
#
camera.matrix_world.inverted() * object.matrix_world
#
#

Convert Z-up to Y-up Coordinate Systems.

This is something I had to deal with when writing a RenderMan exporter for 3DS Max. Back on those days I did a lot of “juggling” to make things work. For instance when I got the transformation of an object in the form [x,z,y], I would shift the elements to [x,y,z]. This might seem easy but once rotations, and position of vertices had to be exported, the code got a lot uglier.

I ran into the exact same issue lately when writing BtoA. I am pretty certain that the previous versions of Blender used to use Y-up, but on the latest (2.5.x) it is using Z-up. Arnold on the other hand allows you to specify left or right handed worlds, but they are both Y-up. If you analyze the problem, you will realize that rotating the object 90 degrees on the X axis will make Y point up. Depending if you are converting to a left or right handed coordsys, you might need to rotate by -90 degrees. With a simple matrix multiplication we can solve the issue.

#
# Create a new matrix that is rotated -90 degrees
# on the X axis
#
mrot90 = Matrix.Rotation(math.radians(-90),4,'X')
# multiply the rotated matrix by the world matrix of
# object to be exported
#
newMatrix =  mrot90 * object.matrix_world
#

Freeze Transformations

Maya and several other 3D apps provide a way to freeze or reset the transformations of an object. Sometimes this is very useful, specially if you want to make sure that your object has a “starting point” in the scene that is an identity transform matrix and not some random numbers. A freeze transform on a mesh can be applied by:

  1. Multiplying the object’s world matrix to each point in the mesh. This will give the appearance that the object has moved, but its pivot point is still in the same location, because we actually moved the points, not the coordinate system of the object.
  2. We then multiply the objects matrix by its inverse matrix to get rid of the double transformation and move the points back to their original location. Now you will see that the transformations are back to the identity.
# Capture object to an easier variable
p = bpy.data.objects['Plane']
# Get the matrix and the inverse matrix
m = p.matrix_world
mi = m.inverted()
# Apply the matrix to every point in the mesh.
# This will apply a "double" transformation
# to the whole mesh
for i in p.data.vertices:
    i.co = m * i.co
# Multiply the object matrix by the inverse,
# officially setting the xform of the object
# to the identity and getting rid of the
# double transformation
p.matrix_world *= mi
#

 but wait a minute, the pivot point of the object is no longer where it was, lets take a look at how we can change the pivot point.

Center Pivot

To center the pivot point to an object we need to follow the following steps:

  1. Get the center of the object’s bounding box in world space (cworld)
  2. Find the position cworld in relation to the pivot point of the object (cwToPiv)
  3. Multiply every point in the mesh by the inverse of cwToPiv. This will center the mesh points to the pivot point.
  4. Apply cworld as the matrix of the object to move it back to its original location
# quick access variable
c = bpy.data.objects['Cube']
# get the bounding box. Blender calculates it
# in object space
b = c.bound_box
# get the min and max of the bounding box.
# through exploration I see that the min is
# at b[0] and the max is at b[6]
vmin = Vector([b[0][0],b[0][1],b[0][2]])
vmax = Vector([b[6][0],b[6][1],b[6][2]])
# get the center of the bounding box. This
# is still in object space
cent = (vmin + vmax) * 0.5
# make a matrix with the center point
cm = Matrix.Translation(cent)
# make a new matrix of the point in world
# space.
cworld = c.matrix_world * cm
# Get the position of cworld in relationship
# to the pivot point. See above how to do this
cwToPiv = c.matrix_world.inverted() * cworld

# multiply every point by the inverse of
# cwToPiv
for i in c.data.vertices:
    i.co = cwToPiv.inverted() * i.co
# Now apply the bounding box center
# in world space to the world space
# of the object
c.matrix_world = cworld
#

Of course we can use this technique to se the pivot point to anywhere in the bounding box of the object. All we need to do is use a little math to set the value of cent (rename the variable to be easier to read). Everything else should after that point should be the same