Saturday, December 10, 2011

Per Geometry Caching (In Progress)

Started working on implementing per geometry photon caching. This is basically storing photons at each geometry instead of at a global scene level. This will help with performance during the gathering step, since we will now only have to look at photons on the geometry, and not photons in the whole scene. It will also eliminate unintended color bleeding since only photons on the geometry will effect the color of that geometry.

I reasoned that if I create a new photon list for each geometry in the scene to store its photons, it will be quite inefficient, since I will need three of these lists and each list is actually a texture at the GLSL level. So I decided to tackle problem by keeping my global photon list, but partition them so that each part correspond to a geometry (e.g., photon0-18 are on geometry0, photons19-42 are on geometry1, and so on.)

I am able to do this successfully, and visualize it (since the data is passed down as a texture.)


The first row is color, second is position, and third is angles. It is clear that data is partitioned. For example, take a look at the top row representing color. The first section is all yellow; this corresponds to geometry0 which is a yellow wall, so its photon colors must be yellow. Next is the opposite blue wall, then there are 4 other gray walls/floors, and finally the three shapes in the scene, colored red, green, and purple respectively.

The next step is to do a look up in the shader. In a regular programming language, this would be trivial, but GLSL ES does not allow variable array indexing, or variable loop lengths. This is my current problem: I have to figure out how to efficiently do a photon lookup within those partitions in GLSL.

I was going to do:

// idx - index of geometry
for (int i=PHOTON_START[idx]; i<PHOTON_END[idx]; i++) {
       // gather photons, compute color
}

However, const arrays are not allowed in GLSL ES. So my next alternative (quite nasty Javascript hack) is to have Javascript hard-code multiple IF statements:

if (idx == 0) {
       for (int i=PHOTON_START_01; i<PHOTON_END_01; i++) {
       // compute color...
       }
}
if (idx == 1) {
       for (int i=PHOTON_START_02; i<PHOTON_END_02; i++) {
       // compute color...
       }
}
...

I'm not sure if there's a smarter way to do this. This would be quite a few IF statements, one per geometry, and it would not scale well. And if the hardware would visit every inner IF statements anyway (something I'd have to figure out), then this would not improve performance at all (plus it would make it worse because of all the conditionals.)

No comments:

Post a Comment