I have a forward path tracer working, except that it works too good to be realistic.
float trace_path_forward2(const vec3 eye, const vec3 direction, const float hue, const float eta)
{
const vec3 mask = hsv2rgb(vec3(hue, 1.0, 1.0));
Vertex A, B, C;
const int index = int(round(stepAndOutputRNGFloat(prng_state)*float(ubo.light_tri_count - 1)));
get_triangle_vertices_by_light_index(A, B, C, index);
const vec3 light_o = getRandomPointOnTriangle(A.pos, B.pos, C.pos);
const vec3 light_d = cosWeightedRandomHemisphereDirection(get_normal_by_light_index(index), prng_state);
const float energy = 1.0;
int step_count = 0;
vec3 step_locations[max_bounces + 2];
vec3 step_directions[max_bounces + 2];
step_locations[step_count] = light_o;
step_directions[step_count] = light_d;
step_count++;
if(false == is_clear_line_of_sight(eye, light_o))
{
vec3 o = light_o;
vec3 d = light_d;
for(int i = 0; i < max_bounces; i++)
{
traceRayEXT(topLevelAS, gl_RayFlagsOpaqueEXT, 0xff, 0, 0, 0, o, 0.001, d, 10000.0, 0);
const vec3 hitPos = o + d * rayPayload.dist;
o = hitPos + rayPayload.normal * 0.01;
d = cosWeightedRandomHemisphereDirection(rayPayload.normal, prng_state);
step_locations[step_count] = o;
step_directions[step_count] = d;
step_count++;
if(true == is_clear_line_of_sight(eye, step_locations[step_count - 1]))
break;
}
}
step_locations[step_count] = eye;
step_directions[step_count] = -direction;
step_count++;
// Reverse the path
uint start = 0;
uint end = step_count - 1;
while(start < end)
{
vec3 temp = step_locations[start];
step_locations[start] = step_locations[end];
step_locations[end] = temp;
temp = step_directions[start];
step_directions[start] = step_directions[end];
step_directions[end] = temp;
start++;
end--;
}
float ret_colour = 0;
float local_colour = energy;
float total = 0;
for(int i = 0; i < step_count - 1; i++)
{
vec3 step_o = step_locations[i];
vec3 step_d = -step_directions[i];
traceRayEXT(topLevelAS, gl_RayFlagsOpaqueEXT, 0xff, 0, 0, 0, step_o, 0.001, step_d, 10000.0, 0);
if(rayPayload.dist == -1)
return 0.0;
local_colour *= (rayPayload.color.r*mask.r + rayPayload.color.g*mask.g + rayPayload.color.b*mask.b);
total += mask.r;
total += mask.g;
total += mask.b;
if(i == step_count - 2)
ret_colour += local_colour;
}
return ret_colour / total;
}
As you can see, the light contribution is always 1.0.
Any insights?