## November 12, 2011

### trying to calculate localVisibility with Spherical Harmonics

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

In hidsight, baking a lookup table of vectors and the spherical harmonics, might lead to artifacts, but with 1024 samples it doesnt look too bad

Feel free to download the source to sing along, its all based on the Sony Paper from 2003 see the PDF from SCEA

Python executable that write Spherical Harmonics Renderman header: sh1.py

And a simple shader to calculate transmission based on the table of stratified samples above: localVisibility.sl

Its a bit clunky because I couldn’t work out how to do two dimensional arrays in RSL, im glad to fix it up if it is possible.

The preprocessor thing isnt that sweet either :/

As below:

```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 #include "SH.h"   surface localVisibility( uniform float maxDistance = 10; uniform string outputFolder = ""; ) { SHVECTOR SHSPH0 SHSPH1 SHCOEFF0 SHCOEFF1 SHCOEFF2 SHCOEFF3 SHCOEFF4 SHCOEFF5 SHCOEFF6 SHCOEFF7 SHCOEFF8 vector Nworld = vector(transform("world",N)); point Pworld = transform("world",P); uniform float numSamples = 1024; uniform float numCoeffs = 9; varying float results={0,0,0,0,0,0,0,0,0}; uniform float i,j; varying float faceforward = 0; varying float occl = 0; for(i=0;i<numSamples;i=i+1){ float Hs = samplesVector[i].Nworld; point destinationWorld = Pworld + samplesVector[i]*maxDistance; point destinationCurrent = transform("world","current",destinationWorld); if (Hs > 0){ faceforward += 1; float isHit = comp(transmission(P,destinationCurrent),0); if (isHit > 0) { occl += 1; for(j=0;j<numCoeffs;j=j+1){ varying float value = isHit; if (j == 0) { value *= samplesCoeffs0[i]; } if (j == 1) { value *= samplesCoeffs1[i]; } if (j == 2) { value *= samplesCoeffs2[i]; } if (j == 3) { value *= samplesCoeffs3[i]; } if (j == 4) { value *= samplesCoeffs4[i]; } if (j == 5) { value *= samplesCoeffs5[i]; } if (j == 6) { value *= samplesCoeffs6[i]; } if (j == 7) { value *= samplesCoeffs7[i]; } if (j == 8) { value *= samplesCoeffs8[i]; } results[j] += value;   } } } } for (j=0;j<numCoeffs;j=j+1){ results[j] /= faceforward; } occl /= faceforward; faceforward /= numSamples; Ci = color(results,results,results); Oi = 1; Ci *= Oi;   }```

I dont think it is working yet, but it compiles and renders

Sam

## 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: First things first I need a model to work with

#### Model

```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

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),float(stuff),float(stuff))) 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] g[i]=colourData[i] b[i]=colourData[i] x[i]=positionData[i] y[i]=positionData[i] z[i]=positionData[i]   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()```

#### Using Nuke to read the Position and Colour Data

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: 