Tuesday, October 18, 2011

I haz a Cornell Box!

Ray traced. Reflection depth 2. Results look correct. Should be ready for the next step.

The code is live at http://iamnop.co.cc/webgl

Monday, October 17, 2011

Simple Shapes

I have set up a basic set of shapes and corresponding intersection methods.

With the limitations I encountered, here is my simple Shape struct:
struct Shape {
  bool geometry;
  vec3 pos;
  float radius;
  vec3 color;
};

I'm planning to go with this for now and move onto photon casting and scattering. When I do have time to come back, I am planning to implement a few basic matrix transformation functions and use a transformation matrix for the shapes and for ray tracing (transforming in and out of object coordinates.)

Everything seems to be working okay. Here's a screen capture:

Saturday, October 15, 2011

Problems Encountered

The goal for this week was to set up a working scene graph so that the framework would be ready for the main global illumination pipeline.

I decided to implement the scene graph building in the shader itself. However, I soon ran into problems. The first problem was that GLSL ES does not support pointers, and therefore, I would not be able to build a real scene graph on the shader. So I decided that I would leave the scene graph for later and work with individual objects with their own individual transformations (with respect to the world.) This would require matrix math to create translation, rotation, and scale matrices along with several other matrix operations in order to apply and undo transformations. I was planning to use GLM for the math library. However, I found out that GLSL ES does not support the #include directive. I tried looking around for options, but could not find anything useful. So I then decided I would work with very basic sphere and cube structs that have position and radius values.

Once I have the basic structs, I keep them in an array of shapes. I then proceeded to write the intersection code for the structs, as well as the intersection code for the world, iterating over the array of shapes and finding an intersection.

Once I had intersection code, I started writing the recursive ray tracing function that will utilize the intersection checks I just added. After I wrote the ray tracing code, complete with reflection and refraction, I encountered an unknown compilation error. And after a long time of looking over my code and Googling for answers, I realized that GLSL ES does not allow for recursive function calls. (I found the reference for GLSL ES which is useful.) So I had to revert my code back to the original non-recursive ray tracing.

A lot of time this week was spent troubleshooting and figuring out the limitations of GLSL ES, the hard way. At the moment, I don't have ray tracing working perfectly with my new intersection code. The spheres have a fuzzy grainy texture, which I assume is attributed to floating point precision error.

Over the next few days, I hope to have complete and debug the intersection code for both spheres and cubes. The reason that I focused on having just the basic ray tracing working with my new code is because photon casting will be using the same code.

I do have some concerns for recursion support. I'm not sure if photon scattering will work without recursion. I will have to look into that.

Thursday, October 6, 2011

I Have Ray Tracing!

I spent this past week figuring out how to set up a framework using Three.js for rendering. More specifically I looked at the following:
  1. How to set up a working mouse-controlled camera
  2. How a shader is setup and used from Three.js
  3. How to pass variables to the shader from Three.js
  4. Learn OpenGL shading language (GLSL)
Along the way, I realized that there is very little documentation on Three.js. The API is a work in progress, and Google searches return nothing more than a handful of basic tutorials.

After a few hours of poking around, I finally found the places that I can use for reference. They are not as great as APIs but they will work:
  1. A large collection of Three.js examples written by the author himself (http://mrdoob.github.com/three.js/)
  2. The actual source code on github, which is as close to an API as I could find.(https://github.com/mrdoob/three.js/tree/master/src)
In addition to those sources, I looked at two specific related WebGL implementations to see how the framework is setup:
  1. Ray Tracing (http://people.mozilla.com/~sicking/webgl/ray.html). Simple and easy to understand. I actually emailed the author to inquire further about his framework.
  2. Path Tracing (http://madebyevan.com/webgl-path-tracing/). Amazing implementation and the original source of my inspiration. Builds the scene into the shader dynamically using Javascript, very fancy.
Relying mainly on the two existing implementations, I designed and implemented my framework. The rendered image will be displayed as a texture on a quad; thus, there isn't much on the WebGL side at all. As far as WebGL knows, there is only a one simple geometry in the scene. This is implemented as a quad facing in the positive z direction to a static camera.

The quad acts like a screen, and the custom shader on this quad is where all the rendering happens. The shader will look at some the actual scene to be rendered, performs the necessary computations, and outputs an final image onto the quad.

At the moment, I implemented a camera from Three.js that is controlled by the mouse, and I used the base code from the ray tracing example in my shader to set up ray tracing and a simple dummy scene. The result is successful. I have real-time ray tracing and an interactive camera. The results can be viewed here: http://iamnop.co.cc/webgl, and here is a screenshot (since I realized that I am constantly changing the code on the page.)


For next week, I will need to first build my scene graph. At the moment, I have not decided how or where I am going to implement the scene to be rendered, whether it would be built on Three.js's scene graph with values that are passed to the shader, or whether it would be build and used within the shader itself, which is what the two existing implementation did.

Once I have a proper scene graph set up, I can finally start working on rendering with global illumination. I will mainly rely on one of Hendrik Jensen's sources that I have. They are thorough and include all necessary implementation details and mathematical formulas.

Thursday, September 29, 2011

WebGL Time!

I spent my time this week reading about and learning WebGL. I was looking at ways in which I could do my renderer on Javascript and WebGL.

I started the week by going to the guest lecture by Patric Cozzi on WebGL, and it was highly helpful. I learned about the main big ideas of WebGL, some tips and gotchas, and a handful of Javascript syntax. However, more importantly, I learned about dev tools that help such as JSLint and WebGL inspector, and I also took away names of several WebGL libraries that could be helpful.

Later in the week I started reading WebGL tutorials on learningwebgl.com.

At the same time, I also looked for libraries that I could use. I came across several:
  • glMatrix.js provides fast and simple matrix class and functions
  • sylvester.js offers vectors and matrices with extensive functions and flexible constructors
  • Scene.js is a Javascript scene graph framework
However, there was one that clearly stood out: Three.js. Three.js is an extensive libraries that is designed to help developer draw 3D scenes that renders through WebGL. It has all the necessary classes such as mathematical functions, vectors, matrices, and scene graph objects, and various geometry classes.

I have decided that I would use Three.js to handle all non-rendering related work such as setting up a scene graph and moving the camera. This work will be done on the Javascript side. The heavy rendering work would be done on the shader level, which benefits from the hardware acceleration; Javascript too slow for rendering.

I have set up a simple WebGL application using Three.js. It has a basic scene graph and mouse controlled camera (click and drag on application.) The app can be found here: http://iamnop.co.cc/webgl/.

Next week I will spend my time setting up this WebGL framework so that everything is ready for rendering. Then I would move onto setting up the necessary shaders in order to do the rendering work.

Wednesday, September 21, 2011

Rendering Diagram

This week I read up on rendering with photon mapping in greater detail and was able to come up with a diagram to help understand the process. However, I left out Final Gathering, which is another method to obtain radiance from the photon map. Final Gather is a very costly process but produces more accurate results. Since I'm implementing this on WebGL and aiming for a decent level of performance, I have decided to leave it out for now and make it an optional component.

Next week, I will work on setting up initial WebGL framework, look for usable libraries, and write basic classes. There are still a lot of unknowns in the area that I will need to look into.

Anyway, here's my pretty diagram of the rendering process. Optimizations are highlighted in a brighter blue.

Thursday, September 15, 2011

Senior Design - First Post!

It's been a tough process picking my topic. I originally had two ideas: 1) an Android AR app that lets you place furniture in any room, and 2) photon mapper on WebGL. In the end, I thought the AR project was a little too scary since it involves a lot of computer vision, although the prospect of playing around with Android SDK is still very attractive. So I decided I wanted to stick to basic computer graphics topics (which makes it safe because there's tons of resources out there), but taken to a new platform (I always wanted to play with WebGL), and that's how I came about my topic.

Here's the abstract:

Rendering is the process of generating a 2D image from a description of a 3D scene through a computer program, and it is one of the primary focuses of computer graphics. Years of research in the field has perfected the science of rendering such that today’s movies and films are able to produce almost perfect life-like images. With the advanced rendering methods we have today, it is difficult, sometimes impossible, to tell apart computer graphics from real-life photography. However, recently, web technology has been seeing many amazing improvements, and every day we are finding the web to be a more powerful and versatile platform.
The goal of this project is to bring realistic rendering with global illumination capabilities to the web platform through WebGL. The renderer uses regular ray tracing for direction illumination and uses photon mapping for indirect illumination. The renderer is expected to run on the latest WebGL supported browser, on any machine. The user can also modify the scene and the renderer can respond interactively. Because of these constraints, the target scene is quite simple, with only a few primitive objects.

I'll probably be spending the next week doing lots of reading, along with reading up on basic WebGL tutorials and setting up a basic framework, maybe getting a cube to show up on screen.