Friday, April 30, 2010

Final Presentation Videos

Here are the results that I showed at the presentation today. I really, really want to keep refining the project to get higher quality results by the time the final write-up is due. But, I'm going to have to switch gears over to finishing the 660 shader first. As you can see, I wasn't able to get the 660 shader working in time to color the hair strands, so I made a hasty decision to get LOD clusters working. They look kind of silly (perhaps if they were textured, they would look better). Another sore spot is the unconstrained hair movement at the point where each Bullet rope is anchored to the collider. I've searched through the Bullet API for a way to constrain the anchor "swing", but after hours of trying different parameters, this is what I ended up getting. Also, note that these videos were not recorded in real time (~3x the original speed). Terrible, I know.



I've learned a lot from this project, even if the results don't match up to what I set out to do. (Especially with regard to stitching together a lot of different APIs, in this case OpenGL, FLTK, OpenMesh, Bullet, (a Timer class), and the ConvexHullDecomposition library). There was a lot that I didn't put into my presentation...I didn't leave myself enough time to make it. But, I suppose since our presentations were supposed to only be 10 minutes, this was a "blessing" in disguise.

Wednesday, April 28, 2010

That Blasted 660 Shader!

Blast! This does not look like hair! What is that crazy random highlight on the side? I wanted to show what I've been working on, though.

Tuesday, April 27, 2010

Improved KF data

Goal: Get better test data (including a deforming head mesh as well as corresponding KF data)

I've written a Maya plugin that generates a KF file based on the keyed position and orientation of a selected object in the Maya scene. Now I have the ability to create all kinds of "low dynamic movements", such as this head shake. [Note that the key hair properties still need adjusting; I should definitely pump up their mass]

Alas, figuring out how to deform the mesh is probably going to remain unresolved. This was supposed to be where Cat's pipeline merged with mine (i.e., she would give me an OpenMesh data structure with deforming vertices). Creating a deforming mesh on my own would require a good chunk of work...or would it? I could fake a deformed mesh, I suppose. Since the control node stores position and orientation data for the rigid collider, I could steal that data, make some transformation matrices and iteratively transform all the vertices in the loaded head accordingly. Obviously, this isn't the same as creating some kind of DeformedMesh class structure, but it would definitely help illustrate the functionality of my project. I'll try this out and see how it goes.

Our presentations are on Friday. Here's what I'm going to try to accomplish by then:
  • predecimation/prescaling of the original input head OBJ
  • implement a threshold to prevent interpolation between key hairs that are too far away from each other (like the ones on either side of the nose)
  • fix memory leaks
  • a basic hair shader (depending on whether or not I can pull through with CIS660...)
  • animated original head ("pseudo deformed" by the method described above)
  • enable CUDA
Based on Bullet's current limitations, that last one probably isn't possible. I was informed by one of the lead Bullet developers that CUDA robustness is going to be a feature of the next release version. Unfortunately, I need CUDA support now, not later. Blarg.

Friday, April 23, 2010

Improved Collider Tracking

Goal: Make the head collider oblivious to the forces introduced by the key hairs

I'm getting there! Unfortunately, since the CPU calculations are slow, it's difficult to see what the true weight/speed of the movement is. So, I've captured a simulation with only 20 key hairs. Things are still a bit slow, but more coherent than the full head of hair result. Behold!
The rest of today will be dedicated to working on the Marschner shader. Methinks making a look-up table for different directions to the light source is ideal. This is pretty straight forward for the Gaussian lobe calculations; the M_R, M_TT, and M_TRT functions all take 2 arguments (the azimuth and inclination angle of the light source) and output only one value; meaning they can be combined into a single colored texture with 3 channels. There are 2 advantages to trying this texture storage technique: (1) I can visualize the flattened lobe/coloring distribution for debugging purposes, and (2) I found a tutorial on how to make a GLSL shader that assigns textures. Everybody wins! (maybe)

Beta Pipeline

This is the pipeline I showed at my Alpha Review (more like Beta, since I've been beating this project with a stick for 2 semesters). It's going to get a make-over for my final presentation, but the modules are going to stay pretty much the same.

Sunday, April 18, 2010

"Hacky" Collider Tracking

Goal: Use control laws to extrapolate the linear and angular velocity (or force) necessary to move the head rigid body so that its position/orientation matches that of the control node

The (hairless) head collider can now move and twist to match the control node! Unfortunately, my means of accomplishing this are a bit "hacky": at each frame of the simulation, I set the collider's position/orientation equal to that of the control node. The "proper" method sets linear/angular velocities or forces, but I'm running low on time, so I'll use the "hacky" approach for now.
We're in the home stretch now! Final demos are in 2 weeks. In the remaining time, I hope to accomplish the following:
  • A memory management overhaul (ironically, in an attempt to make my code more compact and legible, I somehow introduced even more deallocation problems than before)
  • [CIS660] Finish the hair shader (using the work of Zinke and Marschner as a guide)
  • Translate the hair shader code into a GPU vertex shader language (GLSL most likely)
  • Make the head collider oblivious to the forces introduced by the key hairs (alas, I cannot simply set the position/orientation of the hairy head collider; it wiggles around and drifts due to the extra inertia/weight produced by the attached hairs - I'm waiting to see what the Bullet forums has to say about this one)
  • UI cleanup (plug in UI features that haven't been implemented yet, such as automatic scene rescaling and a means for specifying simulation/rendering parameters)
  • Get better test data (including a deforming head mesh as well as corresponding KF data)

Wednesday, April 14, 2010

Projected Key Hairs

Goal: Fix Bullet hair oscillations by projecting hair roots onto the head collider.

Projection onto the collider seems to be working now. I ran into some usage issues with the convex hull decomposition library (but an e-mail to its developer cleared things up). Since my collider is composed of multiple hulls, I have to iterate through all of them, checking to see if a scalp vertex projection onto the current hull yields a better result than for the previous hull. My "best choice" heuristic for this decision is based on distance (i.e. the intersection point farthest along the ray that points from the collider's center --> the scalp vertex). The results look good, meaning that the key hairs are now growing out from the collider instead of from the scalp mesh. As I predicted, Bullet is much happier with this hair anchor position, and only a few of the key hairs oscillate slightly. How to resolve the remaining oscillations is going to be tough. I could turn to the forums, but I fear this is an issue with the robustness of the engine (since I've already tried maxing/zeroing out all the parameters associated with a Bullet soft body). Oh well, can't hurt to try again.

Each convex hull in the collider has its own pastel-y color now! As you can see, there's still a need for a pass in the pipeline that takes the original (very dense) input mesh, decimates it, scales it up slightly, and then sends the result to the convex hull decomposer. One issue that crops up now that the key hairs are grown from the collider and not from the scalp is floating key hairs. Since the collider and the original head mesh have slightly different boundaries, some of the key hairs will not be connected to the original head. To fix this (for now), I drew in an extra segment connecting the key hair roots to the center of the scalp, like so:

Wednesday, April 7, 2010

Marschner Progress (III)

This sucker displays the following components of the Marschner scattering model:
  • Ambient
  • Diffuse
  • R lobe (color and distribution), although more parameter tweaking is required
  • TT lobe (distribution only)
  • TRT lobe (distribution only)
Just to put this all into perspective, here is a schematic of the R, TT, and TRT lobes:

Monday, April 5, 2010

Marschner Progress (II)

Looking slightly better. Slightly.

Friday, April 2, 2010

Not the prettiest thing...

First results for the Marschner BRDF. Yeah...it needs a lot more work...