Saturday, November 24, 2012

PDF- New set of particles

I created a new set of particles with better jittering to see if that would help with the grid-like layout of the previous test.  It did.  I also culled this set in one batch to see if that removed the banding/overlapping I was getting from before.  It did.  The banding effect could just be from the bad jittering in the first set.  Still need to test to check.

This set had an initial 4.7M position set.  It was culled down to 1.7M, then further minimized using a quadratic PDF.  Here are some renders :-).

Top View.

Perspective View.

with size variation.

Close Up.

with size variation.

Friday, November 23, 2012

Probability Density Function- Quadric

Quadric tests....

NOTE- I'm pretty sure that the speckly nature of these images is due to a weird error in the texture map/culling script, causes some of the particles to get a grey/black color and full opacity.  Its the next bug I'm going after over the next few days.

PDF Equation.
Side view with PDF.

Side view with size variation.

Top view with PDF.

Perspective view with PDF.

Close up with PDF.
Perspective view with size variation.

Close up with size variation.

Probability Density Functions- Cubic

Cubic tests...

PDF Equation
Side view of small set with PDF.
Side view of small set with size variation.
Top view of 1.7M set with PDF.
Perspective view of 1.7M set with PDF.

Close up of 1.7M set with PDF.
Perspective view with size variation.
Close up with size variation.

Probability Density Functions- Quadratic

Some quadratic falloff tests... The radius size change becomes less of an issue now since the larger ones are more scattered and don't obscure the detail below.

PDF Equation
Side view of small set after PDF.
Side view with larger radius for outside particles.
Top view of PDF on 1.7M set.
Perspective View of PDF on 1.7M set.
Close-up of PDF on 1.7M set.
Perspective View of PDF with more size variation.

Close-up of PDF with size variation.

Probability Density Functions- Linear

In an effort to break up the particle sets more, I'm running the culled sets through a probability density function.  This basically means that particles that are farther away from the surface will be more likely to be thrown away.  Since this calculation relies on distance from the surface, this will be a post initial cull operation.  Below I'm playing with different function orders to see what kinds of falloff I get.




Thursday, November 22, 2012

Look Development: Current State

So still playing with my values... here's where I'm at with 1.7M particles.  You can see some weird banding in the top down view where the subsets are overlapping.  I'm not sure how/why this is happening.  I'm hoping to run a full size set tomorrow and see if that fixes the problem.  Also, I'm getting some weird black particles sprinkled throughout the set- not sure why that's happening either.

State from before...
Side View of Falloff Attempt




Perspective View of Falloff on 1.7M
Top View of Falloff on 1.7M
Plot of ramp function for transparency.

Look Dev- Expression Editor Code

Within Maya, I needed a stable way to play with the falloff curves for the opacity and radius values.  I decided to use the expression editor to "jerry-rig" some ramp behaviors as the actual ramps weren't behaving properly.  Also, these equations should be easy to transfer to the shader code in the C renderer.  Anyway, here's the code:

// Inverting and scaling initial opacity from texture map to get a base transparency
particleShape1.userScalar1PP = 1 - (0.01 * particleShape1.opacityPP);

//Transparency Ramp Values (linear interpolation)

//Distance where slope changes
float $minDist = 0.0;
float $fallOff1 = 0.05;
float $fallOff2 = 0.35;
float $fallOff3 = .9;

//Transparency targets where slope changes
float $transStart = .7;
float $transMid1 = .85;
float $transMid2 = 0.95;
float $transEnd = 1.0;

//Calculates rates of change for linear interpolation
float $slope1 = ($transMid1 - $transStart) / ($fallOff1 - $minDist);
float $slope2 = ($transMid2 - $transMid1) / ($fallOff2 - $fallOff1);
float $slope3 = ($transEnd - $transMid2) / ($fallOff3 - $fallOff2);
float $yInter2 = $transMid2 - ($slope2 * $fallOff2);
float $yInter3 = $transEnd - ($slope3 * $fallOff3);

//Radius Ramp Values (linear interpolation)

//Max/Min Randomization of radius
float $minRadRand = 1.0;
float $maxRadRand = 1.5;

//Radius targets where slope changes
float $minRad = .1;
float $midRad1 = .13;
float $midRad2 = .15;
float $maxRad = .18;

//Calculates rates of change for linear interpolation
float $slope4 = ($midRad1 - $minRad) / ($fallOff1 - $minDist);
float $slope5 = ($midRad2 - $midRad1) / ($fallOff2 - $fallOff1);
float $slope6 = ($maxRad - $midRad2) / ($fallOff3 - $fallOff2);
float $yInter5 = $midRad2 - ($slope5 * $fallOff2);
float $yInter6 = $maxRad - ($slope6 * $fallOff3);

// Sets the transparencyPP values
if(particleShape1.DistanceFromSurfacePP < $fallOff1)
    particleShape1.userScalar2PP = particleShape1.userScalar1PP * ($slope1 * particleShape1.DistanceFromSurfacePP + $transStart);   
else if(particleShape1.DistanceFromSurfacePP >= $fallOff1 && particleShape1.DistanceFromSurfacePP < $fallOff2)
    particleShape1.userScalar2PP = particleShape1.userScalar1PP * ($slope2 * particleShape1.DistanceFromSurfacePP + $yInter2);
else if(particleShape1.DistanceFromSurfacePP >= $fallOff2 && particleShape1.DistanceFromSurfacePP < $fallOff3)
    particleShape1.userScalar2PP = particleShape1.userScalar1PP * ($slope3 * particleShape1.DistanceFromSurfacePP + $yInter3);
else
    particleShape1.userScalar2PP = 1;   

// Resets the radiusPP
particleShape1.radiusPP = particleShape1.radius;

// Sets the radiusPP values
if(particleShape1.DistanceFromSurfacePP < $fallOff1)
    particleShape1.radiusPP = $slope4 * particleShape1.DistanceFromSurfacePP + $minRad;
else if(particleShape1.DistanceFromSurfacePP >= $fallOff1 && particleShape1.DistanceFromSurfacePP < $fallOff2)
    particleShape1.radiusPP = $slope5 * particleShape1.DistanceFromSurfacePP + $yInter5;
else if(particleShape1.DistanceFromSurfacePP >= $fallOff2 && particleShape1.DistanceFromSurfacePP < $fallOff3)
    particleShape1.radiusPP = $slope6 * particleShape1.DistanceFromSurfacePP + $yInter6;
else
    particleShape1.radiusPP = $maxRad;

// Adds in a random extra value to create texture in size
particleShape1.radiusPP = particleShape1.radiusPP * rand($minRadRand, $maxRadRand);

Particle Generation Methodology

So here are the steps I'm going through to create particles (splats) for my nebula.

1. Generator.cpp: Takes in an OBJ file (or 2 or 3) of a mesh, creates a bounding box, and voxelizes it to create particle positions.  The positions are jittered and then written out to a text file.

2. SubDivSet.cpp: Takes an initial set of positions and subdivides it using a max amount per file.  For example, given a 4.8M set, with a 500K limit, we'd get 9 text files with 500K positions and 1 file with the remaining 300K.  I'm doing this to break up the culling operation, which can get a little slow with larger data sets.

NOTE- May have an issue here... In recombining the sets, I'm getting overlapping sections.  Need to look into this.

3. ParticleCuller.py: Runs through mayapy in the terminal.  Uses a pre-set up file to compare the position sets to the initial mesh.  Discards positions that are too far away, and does a texture lookup for the others to assign RGB and opacity.  500K sets take 10-20 minutes to run, depending on how many positions work (the more we get, the more texture lookups are needed, the slower the code runs).  Saves a new maya file, which we can write out a PDA file from using this MEL command:

dynExport -mnf 1 -mxf 1 -os 2 -atr position -atr rgbPP -atr opacityPP -p "pda" -f "pda" particle1; 

NOTEThe texture lookup in the particleculler.py script fails about 6% of the time.  As of right now, I'm isolating the failed (black) particles and pushing them through the particleCuller again.  When run through the script editor, this seems to succeed for every particle.  (See my post on 12/2/2012). 

3B. Find_Black.cpp: Loops through culled particles looking for RGB values all equal to zero.  Separates the initial set into 2, so that the failed particles can be re-run through the culling script.  Both of these files can be combined using combinePDA.cpp.

4. CombinePDA.cpp: For each of the PDA files, combine them together into a single data set.  In this case, I combine each attribute into single files- so all of the rgbPP data goes into one, all of the positions into another, etc.  From here, the data could go into the C render code, or be converted into a PDC for lookdev work in Maya.

5. PDCWriterS106.cpp: Translates each attribute into a single PDC file which can be read into Maya for look dev testing.

Thursday, November 15, 2012

Look Development, PT. 2

Short camera move on 5s that moves from a top view to a side view.  Colors are a little washed out...




Look Development Tests

So I've divided up my set into 10 mini sets to make testing easier.  I'm using the expression editor in Maya to create linear interpolated falloffs for opacity and size.  This is just with the initial set, so there still needs to be a probabilistic density/cull function that will create a little more variety in the shape/surface of the cloud.  Anyway, here are some tests, mostly from most recent to oldest.