Vulkan ray tracing glossy reflections

Started by
5 comments, last by taby 1 year ago

Is there a common method to do glossy reflections in Vulkan ray tracing?

Kind of like this:

Advertisement

The way to calculate glossy reflections with ray tracing is by tracing many rays per pixel and randomly reflecting each one according to the BRDF for secondary and further bounces, and then averaging the result for all rays. This classic paper has all of the details for how to do this with low noise. This does take a lot of rays though, so you might need to combine it with TAA for real time or use other hacks to blur the noise away.

So I’ve decided to sample many angles per reflection, to get glossy reflections. What would be the best way to pass the necessary pseudorandom numbers into the shader? Part of the uniform buffer object? Doesn’t seem efficient. Perhaps there’s a better way?

Aha, I found a PRNG in GLSL:

https://github.com/nvpro-samples/vk_mini_path_tracer/blob/b0c0e9e25ef1eed5b4ab388e5e817e6cb5bdac00/vk_mini_path_tracer/shaders/raytrace.comp.glsl#L26

I found a way to do it quickly.

specular
glossy

The code is:

//...
float refl = 1.0;

if(rays[i].parent_id != -1)
	refl = rays[rays[i].parent_id].reflection_constant;

if(rays[i].external_reflection_ray && refl != 1.0)
{
	vec3 rdir = normalize(vec3(stepAndOutputRNGFloat(prng_state), stepAndOutputRNGFloat(prng_state), stepAndOutputRNGFloat(prng_state)));
	vec3 dir = normalize(rays[i].direction.xyz);

	if(dot(rdir, dir) < 0.0)
		rdir = -rdir;
			
	rays[i].direction.xyz = mix(rdir, rays[i].direction.xyz, refl);
}

traceRayEXT(topLevelAS, rayFlags, cullMask, 0, 0, 0, rays[i].origin.xyz, tmin, rays[i].direction.xyz, tmax, 0);

vec4 hitPos = rays[i].origin + rays[i].direction * rayPayload.distance;
//...

I also applied the same effect to shadows.

This topic is closed to new replies.

Advertisement