Monday, April 25, 2011

CG2: Assignment 6

Refraction:





Total Internal Reflection kind of looks bad in this shot since my background is black. But it's there, and that's been my basic scene so I thought I wouldn't change it.

Here's a spruced up scene so you can see the TIR more clearly:





I'll update when I finish the extra.



UPDATE:

Extra...



I missed class and don't know if how to do this was discussed, but essentially what I did was start with a light transparency of 100% for a shadow ray. Each time an object was hit on it's way from a point on an object to a light source, the light transparency factor was multiplied by the transparency of the object in between. After accumulating all of these, I multiply the final shading for that point by it to get the effect of being in some form of shadow.

Wednesday, April 13, 2011

CG2: Assignment 5

This one was easy. I'd already set up my ray tracer to deal with recursion, but hadn't had a use for it so it did nothing. I'd also already written a function CalculateReflection(Vec3D toSource, Vec3D surfaceNormal) that does exactly what is necessary to reflect a ray off of a surface with a given normal. With this at hand and my framework already set up for recursive tracing, this literally amounted to little more than the addition of an if statement.



Note that this was done with 4x supersampling (16 samples per pixel).



The only real interesting snag I hit was when I briefly didn't realize that using the previous ray's point of intersection as the origin for the reflection ray wouldn't work. For obvious reasons, the reflection ray will sometimes decide that the closest intersecting object is the object that it's reflecting off of because of that. Adding to the reflecting ray's origin an extremely small EPSILON value of 0.00001 in the direction of the outgoing ray solved this problem.


Extra #1


I got sick of the boring backdrop, so I added to the scene a bit now that there's a use for it with reflections:

This one has super sampling





Here's one without, you can see the randomness of the rays picked per cone much clearer but the picture isn't as nice.



These were taken with a +/- 5 degree spread for each cone.

Sunday, April 10, 2011

CG2: Midterm Project Update

Alright, some preliminaries...

 

Name: Michael Mayo

Professor: Warren R. Carithers

Course: 4003-571

Project Updates URL: http://mseanmayo.uni.cc/news/?cat=6

 

Now then. My original project proposal didn't quite adhere to the template provided for whatever reason (I think I just completely forgot it existed) so I'll have to improvise on the "schedule" I've been following so far.

 

Here's a quick run-down of the original objectives I had for this project, along with what I have completed or revised:

  • Volumetric Display of MRI data (Revised, see below)

  • Volumetric Density Mapping (Removed)

  • Three-Dimensional Object Segmentation (Unnecessary)


 

So yeah, it would APPEAR as if I had failed in my original plans for this project. However I can assure you anything BUT has occurred. A timeline was also absent from my original proposal, so I'll have to get right into the meat of what I've accomplished so far and then go from there.

 

What's been done


As is mentioned above, MRI data visualization has been revised while the other two core items have been either dropped or deemed unnecessary. What this boils down to is the realization I had after achieving initial results that there was more than enough work to be done with MRI visualization in general. I decided that rather than focus on developing interesting density equations to display interesting effects, or try to segment the volumes themselves, I'd focus all of my energy into developing as much visualization tech. as possible for MRI data. Before I go on, here are the results of such visualizations thus far:



 

As you can see, there are quite a number of ways to render the data. My initial attempts focused on a rudimentary technique based off of the original "slices" of the images that make up the 3D texture. I wanted to draw them each on 2D quads in 3D space with a bit of alpha blending between them in order to simulate the effect of peering into a 3D volume. I ran into problems with this approach both due to aliasing effects when looking from the side (2D flat images are quite boring from the profile...) as well as high polygon counts making the approach less than viable if I wanted to do any special post processing or work with the data in any way. Here's an example of the aliasing effect I was encountering:



 

I started reading about a more advanced method for volume visualization known as ray marching, in which rays are fired into the volume and accumulate density values until an opaque threshold is met and the ray terminates. This method was daunting at first due to its complexity. I was worried at first I didn't understand the theory well enough to implement it, and that once I did I wouldn't be able to get it to render fast enough to be interactive (I had this quarter's experience with the ray tracing assignments to reflect on in that respect). However after much frustration I DID manage to get it working with shaders, which gave me all the performance I would need. Pic related:


 

There's tons of more info about how this works and what I've done, but I'm not sure how much I'm supposed to include for this update. I've documented most of it in other posts however, so here they are: link 1, link 2.

 

My general assessment of my own work on this project so far is very positive and optimistic. Initially, as the links above detail, I felt I was far too ambitious with this project. It took me quite a bit of time to get ray marching working correctly, and I had a few other crucial roadblocks in my progress. Overall I think I'm actually getting more done than I had originally envisioned, and faster than I had anticipated. I'm working on cleaning everything up at the moment and adding support for a few different file formats, and then I'll start adding features again and getting this ready for the presentation.

 

What's next


This sums up what I would like to get done for the final presentation, prioritized highest importance first:

  1. Implement Transfer Functions to allow the MRI data to be isolated as the user sees fit.

  2. Provide a User Interface of some sort

  3. Add support for more file formats (public MRI data comes in several)


 

Monday, April 11th marks the beginning of Week 6. I anticipate that transfer functions be implemented by the start of Week 7,  with a user interface of some sort and extra file format support added in the final Week 8 / Week 9 stretch before presentation.

Saturday, April 9, 2011

CG2 Assignment 4

So we had to do procedural shading this time. Checkerboard texture was required so here it is:





Interesting bit about this is that I had a really hard time finding out how to calculate UV coordinates for a quad. If you use triangles, you can apparently do some fancy stuff with barycentric coordinates to figure out UVs, but I couldn't really work that out and my triangle intersection code generates parametric coordinates instead (I guess this is more efficient for intersection tests). So what I ended up doing instead was figuring out the math on my own using vector projections as described on this wikipedia page. Here's my method:

After I've got the intersection registered for the quad, I do the following calculations:

  1. Math::Point3D PoS = ray.origin + ray.dir*intersection.distanceFromEye;

  2. Math::Vec3D uvOffsets(PoS - myOrigin);

  3. intersection.u = Math::Dot(myEdge1, uvOffsets) / myEdge1.lengthSquared();

  4. intersection.v = Math::Dot(myEdge2, uvOffsets) / myEdge2.lengthSquared();

And that's it, intersection.u/v holds the UV coordinates. The cool thing is that the actual projection equation to get the components of the offset relative to the edges of the quad actually only requires the dot product to be divided by the edge's length, but then to normalize the coordinates to u/v space I needed to divide by the length again. Obviously that means that the two divides could be simplified by dividing by the length of the vector squared, avoiding a costly square root calculation on both parts.

I'll update this space as I finish the extras. I'm shooting for a mandelbrot as extra #1.


Update #1: Mandelbrot


Here it is:



Kinda hard to see, but it's there. I'm just drawing it on the floor quad which is why it's at a weird angle.