I’m doing some ray marching to do volumetric effects in my renderer. It’s not working out so well. Do you have a favourite algorithm? do you have references?
Ray marching accumulation
I used to own a book on graphics algorithms, and it was red and had a baboon on the cover. Anyone know this book? I forget the title. :(
EDIT: found it… it’s called Advanced Graphics Programming using OpenGL.
The code is:
// Do some white fog
if(rays[i].external_reflection_ray || rays[i].external_refraction_ray)
{
float t0 = 0.0;
float t1 = 0.0;
if(BBoxIntersect(aabb_min, aabb_max, rays[i].origin.xyz, rays[i].direction.xyz, t0, t1))
{
const float target_step_length = 0.125;
const vec3 start = rays[i].origin.xyz + rays[i].direction.xyz*t0;
const vec3 end = rays[i].origin.xyz + rays[i].direction.xyz*t1;
const float num_steps = floor(distance(start, end) / target_step_length);
const vec3 step = (start - end) / num_steps;
vec3 curr_step = start;
for(float j = 0; j < num_steps; j += 1.0)
{
for(int k = 0; k < max_lights; k++)
{
if(false == get_shadow(curr_step, rayPayload.wrd, rayPayload.hitt, ubo.light_positions[k].xyz, rayPayload.normal, 1.0))
{
const vec3 light_steps_start = curr_step;
const vec3 light_steps_end = ubo.light_positions[k].xyz;
const float light_num_steps = floor(distance(light_steps_start, light_steps_end) / target_step_length);
const vec3 light_step = (light_steps_start - light_steps_end)/float(light_num_steps);
vec3 light_curr_step = light_steps_start;
float light_color = 1.0;
for(float l = 0.0; l < light_num_steps; l += 1.0)
{
if(light_color <= 0 || false == in_aabb(light_curr_step, aabb_min, aabb_max))
break;
light_color -= get_sample(light_curr_step)*0.1;
light_curr_step += light_step;
}
dist_color += clamp(light_color, 0.0, 1.0);
}
}
dist_opacity += 0.0001;
curr_step += step;
}
}
}
…
rays[i].base_color = mix(rays[i].base_color, dist_color, clamp(dist_opacity, 0.0, 1.0));
A simpler fog is:
// Do some simple white fog
// It really makes the image better
if(rays[i].external_reflection_ray || rays[i].external_refraction_ray)
{
float dist = 0.0;
if(rays[i].parent_id != -1)
dist = distance(rays[rays[i].parent_id].origin, rays[i].origin);
dist_color = dist/10.0f; // suit to taste
}
Now the real deal is getting this from 2fps to 100fps.
Looks really good - the participating media (fog) looks a lot step-like. Try adding some small random number distance every time you step through it. It helps a LOT.
My current blog on programming, linux and stuff - http://gameprogrammerdiary.blogspot.com
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement