Samiam’s Scribble Pad

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

3 Comments »

  1. [...] and  tonnes of Nuke information from Nukepedia. Sam Hodge has a tutorial about creating point clouds in Nuke using 3delight and Cortex. And Cloud Compare lets you compare very large point clouds. MRV is a [...]

    Pingback by » Blog Archive » More Aqsis realtime rendering — December 13, 2010 @ 10:33 pm

  2. Hi Sam

    I use Renderman Studio 3 with Maya 2010 (PRMan). Is your shader working with only 3delight? I tried compile the shader with shader.exe and it said “‘bake’ is not a build-in, user definied, or plug-in function.

    How should I use this in Maya?

    Cheers
    Agoston

    Comment by Agoston Princz — March 15, 2011 @ 2:45 am

  3. Sorry I dont own Renderman Studio, so I cant help you out, you can get 1 free license of 3delight if you want to try out the technique

    Sam

    Comment by admin — March 15, 2011 @ 7:47 am

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress