Samiam’s Scribble Pad

November 6, 2010

Open Computer Graphics Storage Formats

Filed under: Uncategorized — admin @ 12:42 pm

We all know that OpenEXR has pretty much standardised the storage formate for image planes

But now there are few new contenders for

With the future of the industry being more widely outsourced this standardisation between packages seems pretty important.

Somethings happened a long time ago

  • Documents: PDF
  • Edits: EDL
  • Halfbaked scene descriptions: FBX
  • Render Intermediates: RIB

But I really hope that people can start to be a little more uniform with thier formats that they are using

October 31, 2010

Python Implementation of Spherical Harmonics Stratified Sampling

Filed under: Uncategorized — admin @ 7:32 pm

Its Sunday afternoon and its time to write some code, this is pretty much lifted verbatim from Robin Green’s 2003 Paper: Spherical Harmonic Lighting the Gritty Details

So for the next trick is to put this as a large table into a shader so I can bake out a set of 9 cooefficients (4 bands) for Shadowed Diffuse Transfer, these I will store per sample in a point cloud to be looked up during a shading stage.

Then after that I can implement the Image Based Lights, then I can do really quick Image Based lighting using Spherical Harmonics

Lots of fun!

I made a big mess of this but luckily Markus Kransler was able to fix it up:

Here is the amended code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#!/usr/bin/env python 
 
class SHSample():
	sph=(0.0,0.0)
	vec=(0.0,0.0,0.0)
	coeff={}
	pass
 
def P(l,m,x):
	import math
	#Associated Legendre Polynomial P(l,m,x) at x
	pmm = 1.0
	if m > 0:
		somx2=math.sqrt(1.0-(x*x))
		fact = 1.0
		for i in xrange(1,m+1,1):
			pmm *= (-fact)*somx2
			fact += 2.0
	if l == m:
		return pmm
 
	pmmp1 = x * ((2.0*m)+1.0)*pmm
 
	if l == m+1:
		return pmmp1
 
	plm = 0.0
 
	for ll in xrange(m+2,l+1,1):
		plm = ((2.0*ll - 1.0) * x * pmmp1 - (ll + m - 1.0) * pmm) / (ll - m);
		pmm = pmmp1
		pmmp1 = plm
 
	return plm
 
def K(l,m):
	import math
	temp = float((((2.0*l)+1.0)*math.factorial(l-m))/(4.0*math.pi*math.factorial(l+m)))
	return math.sqrt(temp)
 
def SH(l,m,theta,phi):
	import math
	sqrt2 = math.sqrt(2.0)
	if m==0:
		return K(l,0)*P(l,0,math.cos(theta))
	elif m > 0:
		return sqrt2*K(l,m)*math.cos(m*phi)*P(l,m,math.cos(theta))
	else:
		return sqrt2*K(l,-m)*math.sin(-m*phi)*P(l,-m,math.cos(theta))
 
 
def setupSamples(sqrtNumSamples=64,numBands=4):
	import random,math
	counter = 0
	oneOverN = 1.0/float(sqrtNumSamples)
	samples = [SHSample() for i in range(sqrtNumSamples*sqrtNumSamples)]
 
	for i in range(sqrtNumSamples):
		for j in range(sqrtNumSamples):
			x = (i+ random.random())*oneOverN
			theta = 2.0*math.acos(math.sqrt(1-x))
 
			y = (j+ random.random())*oneOverN
			phi = 2.0*math.pi*y
 
			samples[counter].sph=(theta,phi)
 
			vec = (math.sin(theta)*math.cos(phi),\
			math.sin(theta)*math.sin(phi),\
			math.cos(theta))
			samples[counter].vec = vec
 
			tmpDict = {}
			for l in range(numBands):
				for m in xrange(-l,l+1,1):
					index = l*(l+1)+m
					sh= SH(l,m,theta,phi)
					tmpDict[index]=sh
			samples[counter].coeff=tmpDict
			counter +=1
	return samples
 
 
for i in setupSamples():
	print i.coeff

October 19, 2010

Some papers to read and implement

Filed under: Uncategorized — admin @ 12:51 pm

October 14, 2010

Point Cloud in Nuke using “PositionToPoints”, 3delight Rendman Shader Language and cortex-vfx

Filed under: Uncategorized — Tags: , , , , — admin @ 1:51 pm

Here is the end result:

Nuke Node "PositionToPoints" with 3d EXR inputs

First things first I need a model to work with

Model

Shader

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
surface bakeColourAndPosition(
uniform float diffuseAmount = 1;
varying color surfaceColour = color(0.18,0.18,0.18);
varying color opacityColour = color(0.99,0.99,0.99);
uniform string bakeFile="/tmp/out.bake";
)
{
   varying normal Nn = normalize(N);
   Ci = diffuse(Nn)*surfaceColour*diffuseAmount*Cs;
   Oi = opacityColour*Os;
   varying point Pworld = transform("current","world",P);
   bake(concat(bakeFile,"Position"),s,t,Pworld);
   bake(concat(bakeFile,"Colour"),s,t,Ci);
   Ci *= Oi;
}

This shader will produce two text “bakefile” files in the /tmp directory

Note: The texture coordinates are ignored, only using the 3rd,4th and 5th values

  1. one named out.bakeColour with colour information
  2. one named out.bakePosition with position information

Output Bakefiles

  • Download .tar.gz here…

    Due to the SIMD nature of shaders the line count of each of the bake files is the same so they should contain line for line the same information about the Position and Colour Respectively.

    They are in ASCII format so they are easy enough to parse with Python.

    here is an example of thier content:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    out.bakePositionmh
    3
    0 1 -0.07415867 0.17987273 -0.05079475
    0 1 -0.073529155 0.1800126 -0.051191031
    0 1 -0.07289961 0.18015243 -0.051587344
    0 1 -0.072270096 0.18029229 -0.051983685
    0 1 -0.07164058 0.18043211 -0.052379965
    0 1 -0.07101102 0.18057197 -0.052776248
    0 1 -0.07038155 0.1807118 -0.053172619

    Creating Position and Colour EXR files using cortex-vfx

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    
    #!/usr/bin/env python
     
    import sys,os,math
     
    IECoreInstallPath = "/usr/lib/python2.6/site-packages"
     
    if IECoreInstallPath not in sys.path:
    	sys.path.append(IECoreInstallPath)
     
    from IECore import *
     
    bakeFolder = "/tmp"
     
    colorBakeFileLocation = os.path.sep.join([bakeFolder,"out.bakeColour"])
     
    positionBakeFileLocation = os.path.sep.join([bakeFolder,"out.bakePosition"])
     
     
     
     
    def parseBakeFile(bakeFileLocation):
    	data = []
    	counter = 0
    	bakeFile = open(bakeFileLocation,"r")
    	for line in bakeFile.readlines():
    		counter +=1
    		if counter > 2:
    			stuff = line.strip().split(" ")
    			if len(stuff) > 2:
    				data.append((float(stuff[2]),float(stuff[3]),float(stuff[4])))
    	print "Completed parsing %d lines of file %s" % (len(data),bakeFileLocation)
    	bakeFile.close()
    	return data
     
    colourData = parseBakeFile(colorBakeFileLocation)
     
    positionData = parseBakeFile(positionBakeFileLocation)
     
    if len(colourData) == len(positionData):
    	squareSize = int(math.sqrt(len(positionData))) +1
    	print "Square Size: %d, Excess Pixels : %d" % (squareSize,squareSize*squareSize - len(colourData))
    	width = squareSize
    	height = squareSize
    	x = FloatVectorData( width * height )
    	y = FloatVectorData( width * height )
    	z = FloatVectorData( width * height )
     
    	r = FloatVectorData( width * height )
    	g = FloatVectorData( width * height )
    	b = FloatVectorData( width * height )
     
    	for i in range(len(colourData)):
    		r[i]=colourData[i][0]
    		g[i]=colourData[i][1]
    		b[i]=colourData[i][2]
    		x[i]=positionData[i][0]
    		y[i]=positionData[i][1]
    		z[i]=positionData[i][2]
     
    	boxColour = Box2i( V2i( 0, 0 ), V2i( width-1, height-1 ) )
    	boxPosition = Box2i( V2i( 0, 0 ), V2i( width-1, height-1 ) )
     
    	imageColour = ImagePrimitive( boxColour, boxColour )
    	imagePosition = ImagePrimitive( boxPosition, boxPosition )
     
    	imagePosition["R"]= PrimitiveVariable( PrimitiveVariable.Interpolation.Vertex, x)
    	imagePosition["G"]= PrimitiveVariable( PrimitiveVariable.Interpolation.Vertex, y)
    	imagePosition["B"]= PrimitiveVariable( PrimitiveVariable.Interpolation.Vertex, z)
     
    	imageColour["R"]= PrimitiveVariable( PrimitiveVariable.Interpolation.Vertex, r)
    	imageColour["G"]= PrimitiveVariable( PrimitiveVariable.Interpolation.Vertex, g)
    	imageColour["B"]= PrimitiveVariable( PrimitiveVariable.Interpolation.Vertex, b)
     
    	writePosition = Writer.create( imagePosition, "/tmp/outPosition.exr" )
    	writeColour = Writer.create( imageColour, "/tmp/outColour.exr" )
    	writePosition.write()
    	writeColour.write()

    See more about cortex-vfx on google code:

    Using Nuke to read the Position and Colour Data

    File > Script Command [X] > PositionToPoints

    File > Script Command > PositionToPoints

    If you werent able to create your own pair of EXRs you can download the pair here in .tar.bz2 format

    So then you just need to connect them up to the input nodes for the PositionToPoints 3d node as follows:

    Nuke Node "PositionToPoints" with 3d EXR inputs

    If you thought this was useful leave a comment, or if you thought it was stupid leave a comment about how to improve it

    Sam

September 30, 2010

Alias Wavefront OBJ Export in Maya Python with Examples

Filed under: Uncategorized — Tags: , , , , , — admin @ 5:45 pm

Before I start I wanted to explain why I think this is a classic exercise

If you can represent a mesh in OBJ text format you pretty much understand how the data polygonal data exists in the package you are using and you have enough skill to pack it into a data structure to put it to disk.

So here is what you should get a good understanding of:

  • The classic Wavefront OBJ file format
  • The the components of a polygon mesh
  • Using the Python Commands to access the polygon information from the scene
  • Writing data structures to disk

The Structure of a Wavefront OBJ

so we should start with the OBJ of a 1x1x1 cube

An OBJ is great at encoding the surface of an object

which is made up of:

  • Position of the Surface: P
  • Normal of the Surface: N
  • Texture Values of the Surface: st

It is described by stating the values of the surface at discrete points in space along with some connectivity information of how those points are joined together in space as a mesh.

Using the connectivity information a small amount of discrete information can be interpolated continuously to form the surface.

The inner structure of an OBJ has lots of parts

  • “g” 2 groups: of components belonging to one mesh
  • “v” 8 vertices: 3d points, (x-pos,y-pos,z-pos) describing the Position of the surface
  • “vt” 14 texture verticies: 2d points (u-pos,v-pos) describing the layout of the texture on the surface
  • “vn” 24 vertex normals: 3d vectors (x-direction,y-direction,z-direction) describing the angle of the surface
  • “f” 8 faces: each containing indecies to 4 vertices, 4 texture verticies and 4 vertex normals describing the connectivity of the positional, normal and texture information

A diagram of what is the difference between a face, vertex, vertex normal and a texture vertex, would be great here, but you will have to use your imagination

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# This file uses centimeters as units for non-parametric coordinates.
 
mtllib cube.mtl
g default
v -0.500000 -0.500000 0.500000
v 0.500000 -0.500000 0.500000
v -0.500000 0.500000 0.500000
v 0.500000 0.500000 0.500000
v -0.500000 0.500000 -0.500000
v 0.500000 0.500000 -0.500000
v -0.500000 -0.500000 -0.500000
v 0.500000 -0.500000 -0.500000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.375000 0.250000
vt 0.625000 0.250000
vt 0.375000 0.500000
vt 0.625000 0.500000
vt 0.375000 0.750000
vt 0.625000 0.750000
vt 0.375000 1.000000
vt 0.625000 1.000000
vt 0.875000 0.000000
vt 0.875000 0.250000
vt 0.125000 0.000000
vt 0.125000 0.250000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 0.000000 -1.000000
vn 0.000000 0.000000 -1.000000
vn 0.000000 0.000000 -1.000000
vn 0.000000 0.000000 -1.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 -1.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn -1.000000 0.000000 0.000000
vn -1.000000 0.000000 0.000000
vn -1.000000 0.000000 0.000000
vn -1.000000 0.000000 0.000000
s off
g pCube1
usemtl initialShadingGroup
f 1/1/1 2/2/2 4/4/3 3/3/4
f 3/3/5 4/4/6 6/6/7 5/5/8
f 5/5/9 6/6/10 8/8/11 7/7/12
f 7/7/13 8/8/14 2/10/15 1/9/16
f 2/2/17 8/11/18 6/12/19 4/4/20
f 7/13/21 1/1/22 3/3/23 5/14/24

Feel free to read the Wavefront OBJ File format Specification that I found on the internet.

If you want a copy of this file, your copy and paste buffer will work a treat or you could open up Maya and save out a unit cube on the origin.

Its a unit cube on the origin, named pCube1, using initialShadingGroup as a material.

You can see the eight vertices are 0.5 units away from the origin in each three axes with the eight permuations of the signs of each axis. This makes the spacing between vertices 1 unit apart.

The vertex normals are unit in length facing either up, down, left, right, front or back, these normalised vectors are repeated a number of times as there are only 6 discrete values but 24 records.

The texture vertices make squares that are 0.25 units in texture space in an upside down T-layout, with some of the texture verticies being shared between texture faces.

The order in which the faces are created is a left hand rule where the order of the vertices specifies which is the inside of the face as indicated by the fingers and the direction of the face normal is specified by the thumb.

The same left hand rule applies to the texture verticies determining if the texture is mirrored or not.

Edges are implied as the edges between verticies that make up a face.

The number of edges in a face is determined by how many Point/Texture/Normal groups there are in a face

Lets explain that a little further with a single face OBJ

1
2
3
4
5
6
7
8
9
10
11
12
13
mtllib cube.mtl
g default
v -0.5 -0.5 0.5
v 0.5 -0.5 0.5
v -0.5 0.5 0.5
v 0.5 0.5 0.5
vt 0 0
vt 1 0
vt 1 1
vt 0 1
vn 0 0 1
g zPlanePointFive
f 1/1/1 2/2/1 4/3/1 3/4/1

This is a Unit sized face on the Z Plane at +0.5 units in Z

On line 13 we can see the single face definition, it creates a four sided face that goes in the following order

13
f 1/1/1 2/2/1 4/3/1 3/4/1

v/vt/vn : vertex position/ vertex texture / vertex normal, repeated for the number of faces

The edge created from the last vertex back to the first is implied but not explicity defined.

The order is as follows:

for vertex position: 1,2,4,3
for vertex texture position: 1,2,3,4
for vertex normals direction: 1,1,1,1

For Position we can see the face formed on the Z Plane

  • vert #1 : -x,-y (inital point no edge)
  • vert #2 : +x,-y (edge #1, left to right)
  • vert #4 : +x, +y (edge #2, up)
  • vert #3 : -x, +y (edge #3, right to left)
  • back to inital vert : (edge #4, down, return to initial point)

For texture it goes around 0-1 UV space, left to right, up, right to left and then down.

All of the faces recycle the same face normal, the only face normal, face normal number ONE!!1!

Now we understand the OBJ we understand how the components are connected in the OBJ, we just need to find out about the same info in Maya and we can write an OBJ exporter

Getting at the Geometric Data for Polygonal Object in Maya with Python

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import maya
 
def log(message,prefix="Debug",hush=False):
	if not hush:
		print("%s : %s " % (prefix,message))
 
def getData(shapeNode):
 
    vertexValues = []
    vertNormalValues =[]
    textureValues =[]
 
    vertList = []
    vertNormalList = []
    vertTextureList = []
 
 
    oldSelection = maya.cmds.ls(selection=True)
    maya.cmds.select(shapeNode)
 
    #Verts
    numVerts = maya.cmds.polyEvaluate(vertex=True)
    log("NumVerts : %s" % numVerts)
    vertexValues = [maya.cmds.pointPosition("%s.vtx[%d]" % (shapeNode,i)) for i in range(numVerts)]
    log("Verticies:" +  str(vertexValues))
 
 
    #Normals
    faceNormals=[]
    numFaceNormals = 0
    for face in range(maya.cmds.polyEvaluate(face=True)):
        maya.cmds.select("%s.f[%d]" % (shapeNode,face))
        vertexFaces = maya.cmds.polyListComponentConversion(fromFace=True,toVertexFace=True)
        vertexFaces= maya.cmds.filterExpand(vertexFaces,selectionMask=70,expand=True)
        faceNormals.append([])
        for vertexFace in vertexFaces:
            vertNormalValues.append(maya.cmds.polyNormalPerVertex(vertexFace, query=True, xyz=True))
            numFaceNormals  += 1
            faceNormals[-1].append(numFaceNormals )
    log("Num Face Normals: " + str(numFaceNormals))
    log("Face Normals: " + str(vertNormalValues))
 
    #Texture Coordinates
    numTexVerts = maya.cmds.polyEvaluate(uvcoord=True)
    log("NumTexVerts: " + str(numTexVerts))
    textureValues = [maya.cmds.getAttr("%s.uvpt[%d]" % (shapeNode,i)) for i in range(numTexVerts)]
    log("Texture Coordinates: " + str(textureValues))
 
    #Faces
    numFaces = maya.cmds.polyEvaluate(face=True)
    log("NumFaces : %s" % numFaces)
    vnIter = 0
    faceValues = []
    for i in range(numFaces):
        log("Face %d of %d" % (i+1,numFaces))
        maya.cmds.select("%s.f[%d]" % (shapeNode,i))
 
        #Verts (v)
        faceVerts = maya.cmds.polyInfo(faceToVertex=True)
 
        #This is hacky and should be replaced with snazzy regex
        faceVerts =  [int(fv)+1 for fv in faceVerts[0].split(":")[-1].strip().replace("  "," ").replace("  "," ").replace("  "," ").replace(" ",",").split(",")]
        log("v: " + str(faceVerts) )
        vertList.append(faceVerts)
 
        #Normals (vn)
        maya.cmds.select("%s.f[%d]" % (shapeNode,i))
        log("vn: " + str(faceNormals[i]))
        vertNormalList.append(faceNormals[i])
 
        #Texture (vt)
        maya.cmds.select("%s.f[%d]" % (shapeNode,i))
        tex = maya.cmds.polyListComponentConversion(fromFace=True,toUV=True)
        tex= maya.cmds.filterExpand(tex,selectionMask=35,expand=True)
        tex=[int(i.split("map")[-1].strip("[]")) +1 for i in tex]
        log("vt: " + str(tex))
        #Order is incorrect, need to get in same order as vertex ordering
        tmpDict = {}
        for t in tex:
            maya.cmds.select("%s.map[%d]" % (shapeNode,t-1))
            vertFromTex = maya.cmds.polyListComponentConversion(fromUV=True,toVertex=True)
            tmpDict[int(vertFromTex[0].split("[")[-1].split("]")[0]) + 1] = t
        orderedTex=[]
        for i in vertList[-1]:
            orderedTex.append(tmpDict[i])
        vertTextureList.append(orderedTex)
 
        face = " ".join( ["%d/%d/%d" % (vertList[-1][i], vertTextureList[-1][i], vertNormalList[-1][i]) for i in range( len( vertTextureList[-1] ) ) ] )
 
        faceValues.append(face)    
        log("")
 
        log("f: " +  face)
        log("--")
    maya.cmds.select(oldSelection)
    return {"v":vertexValues,"vn":vertNormalValues,"vt":textureValues,"f":faceValues,"g":shapeNode}
 
print "GO!"
maya.cmds.file(new=True,force=True)
maya.cmds.polyCube(ch=True,o=True,w=1,h=1,d=1,cuv=4)
dataDict = getData("pCubeShape1")

OK so apart from the messy code structure there is not much to getting the Point/Vertex (v), Normal (vn), Texture/UV/st (vt) data from the scene:

These are the three commands that make it possible to get to the data you want:

  • polyInfo
  • polyEvaluate
  • polyListComponentConversion

but we need to clean up the output with:

  • filterExpand

As well as getting the data out from the scene using

  • pointPosition: P
  • polyNormalPerVertex: N
  • getAttr: st/UV

Writing the OBJ data to Disk using Python File I/O

So to finish it off we simply replace the end of the code with the following:

85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#Continues from the def "getData"
 
def writeData(dataDict):
	outString = "\ng default\n"
	for i in dataDict["v"]:
		log(str(i))
		outString+= "v %f %f %f \n" % (i[0],i[1],i[2])
	for i in dataDict["vt"]:
		log(str(i))
		outString+= "vt %f %f \n" % (i[0][0],i[0][1])
	for i in dataDict["vn"]:
		log(str(i))
		outString+= "vn %f %f %f \n" % (i[0],i[1],i[2])
	outString += "g %s\n" % dataDict["g"]
	for i in dataDict["f"]:
		log(str(i))
		outString += "f %s\n" % i
	outString += "\n"
	log(outString)
	return outString
 
print "GO!"
maya.cmds.file(new=True,force=True)
maya.cmds.polyCube(ch=True,o=True,w=1,h=1,d=10,cuv=4)
fileLocation = "/Users/hodgefamily/out.obj"
f = open(fileLocation,"w")
data = getData("pCubeShape1")
string = writeData(data)
f.writelines(string)
f.close()
maya.cmds.file(new=True,force=True)
maya.cmds.file(fileLocation,i=True,type="OBJ",rpr="out")
print "STOP"

A friend of mine took my code and cleaned up up Thanks Katrin, you can download it here Katrin's Source Code

July 14, 2010

SALA 2010 Stencil

Filed under: Uncategorized — Tags: , — admin @ 10:10 pm

SALA 2010 Stencils

I have finished the long part of creating my artwork for South Australian Living Artists Week 2010.

The piece will be either titled “Industry” or “Hive”, im still trying to make up my mind.

Now I just need to layout my stencils and spray them up the piece will be 60cm x 90 cm. I am hoping to put it up on Saturday but I will wait and see what the weather brings rather than trying to deal with the wind

I will update the post once the exhibition is on

July 9, 2010

Sydney Vacation July 2010

Filed under: Uncategorized — admin @ 9:22 pm
Emma and Anna Relax by the Opera House and the Bridge

Emma and Anna Relax by the Opera House and the Bridge

Last week Anna, Maia and Myself travelled to Sydney to spend some time with my sister Emma and her wonderful partner Yann.

We did the usual tourist things: Shopping on Oxford St, Ferry Ride to Manly, Walk around Circular Quay, Lunch at Darling Harbour.

It was really good to catch up with some folk over there, if we missed you there is always a next time.

Feel free to flick through the Picasa Web Album Click Here!

It was good to put the Last Dragon to bed and take a break before the next movie, which so far is going pretty well

June 21, 2010

HP Lovecraft

Filed under: Uncategorized — admin @ 4:59 pm

I have been introduced to HP Lovecraft but i recently found this instructional video for the kiddies

I hope you enjoy this introduction to the world of HP Lovecraft.

To me this author has an awesome mix where you can get enough description of his horror so your imagination can fill in the blanks.

Its surprising how much of this stuff has already leaking into popular culture without having ever read any of the original texts

Check out what Wikipedia has to Say

May 30, 2010

cortex vfx install on Ubuntu 10.04

Filed under: Uncategorized — Tags: , — admin @ 1:11 pm

A couple of weeks ago at work we discovered a neat trick in Nuke where you can take the RGB values from an image and mix them with the XYZ values from a position pass from renderman to create a point cloud of the front surface of a render. You can also use a P-reference pass to put a creature back into bind pose as a bunch of points. Which allows you to do neat things like 3d roto.

As a result we started thinking would there be a cool way to also display the backfacing surfaces and encode them into RGB and XYZ.

Producing the data would be easy enough using a point cloud or even bending over bake2d to make it work using UV coordinates.

But you could also sort the data in interesting ways so unless you looked at the correlation between RGB and XYZ the image would either be meaning less in raster format, or could have another look to it.

So I went looking for a good python binding to a float or half float image library.

OpenEXR has some functionality see this doc

but then I stumbled on cortex-vfx on google code, it is basically a CG toolkit, like CGKit

After failing to get cortex-vfx to build on my imac, (some problem with python and boost not using the same version of python)

I decided to throw Ubuntu 10.04 onto some hardware and see if I could get cortex vfx to install

here are the bit and pieces that I needed to put onto a fresh install:

  • libilmbase-dev
  • libopenexr-dev
  • libtbb-dev
  • libboost-all-dev
  • libtiff4-dev

here are my options for the scons build so far


CXXFLAGS = ['-pipe', '-Wall', '-O2', '-DNDEBUG', '-DBOOST_DISABLE_ASS
ERTS']
TESTCXXFLAGS = ['-pipe', '-Wall', '-O0']
PYTHONCXXFLAGS = ['-pipe', '-Wall', '-O2', '-DNDEBUG', '-DBOOST_DISAB
LE_ASSERTS']
LINKFLAGS = []
BOOST_INCLUDE_PATH = '/usr/include'
BOOST_LIB_PATH = '/usr/lib'
BOOST_LIB_SUFFIX = ''
OPENEXR_INCLUDE_PATH = '/usr/include/OpenEXR'
OPENEXR_LIB_PATH = '/usr/lib'

Once I get Maya and Nuke installed I can have a look at building against these packages also.

Then hopefully I can find out if it is going to work at all

Its been building for about an hour on this machine with about 11000 bogomips, Intel(R) Pentium(R) D CPU 2.80GHz, hopefully I can post about all the wonderful things cortex-vfx can do

Edit: Huzzah it installed

Now I just need to find some time to do what I intended to do, but I might compile it against Maya and 3delight first

April 28, 2010

Big in Japan

Filed under: Uncategorized — Tags: — admin @ 11:30 pm

09184_1271389084
My bio on a Japanese website

Tommorrow I fly out to Tokyo to show off the RSP reel and do a little bit of a demo Look Development on films.

Im slightly nervous about Tokyo, but I think my talk should be pretty solid, hopefully I will be understood with my thick Australian accent.

Its pretty whacky timing given that we are in the last five weeks of a project and lighting is really hitting its stride, but given I will only be out for 3-4 days it shouldnt be the end of the world

« Newer PostsOlder Posts »

Powered by WordPress