0
$\begingroup$

Edit: I've pinpointed the problem. If I change:

local_colour *= (rayPayload.color.r*mask.r + rayPayload.color.g*mask.g + rayPayload.color.b*mask.b);

into

local_colour += (rayPayload.color.r*mask.r + rayPayload.color.g*mask.g + rayPayload.color.b*mask.b);

... then I get caustics, but not vibrant colour. Any path tracing experts care to enlighten me as to what I'm doing wrong? :)

The problem:

My code to do path tracing is:

float trace_path2(out vec3 final_pos, const int steps, const vec3 origin, const vec3 direction, const float hue, float eta)
{
    const RayPayload r = rayPayload;

    vec3 hitPos = vec3(0.0);

    float ret_colour = 0;

    vec3 o = origin;
    vec3 d = direction;

    int count = 0;

    
    float energy = 100.0;

    float local_colour = energy;


    float total = 0;

    for(int i = 0; i < steps; i++)
    {
        const float tmin = 0.001;
        const float tmax = 10000.0;
        traceRayEXT(topLevelAS, gl_RayFlagsOpaqueEXT, 0xff, 0, 0, 0, o.xyz, tmin, d.xyz, tmax, 0);

        const vec3 mask = hsv2rgb(vec3(hue, 1.0, 1.0));

        total += mask.r;
        total += mask.g;
        total += mask.b;

        local_colour *= (rayPayload.color.r*mask.r + rayPayload.color.g*mask.g + rayPayload.color.b*mask.b);

        if(rayPayload.distance == -1)
            break;

        hitPos = o + d * rayPayload.distance;

        if(rayPayload.color.r == 1.0 && rayPayload.color.g == 1.0 && rayPayload.color.b == 1.0)
            ret_colour += local_colour;


        vec3 o_reflect = hitPos + rayPayload.normal * 0.01;
        vec3 d_reflect = reflect(d, rayPayload.normal);

        vec3 temp_o = o_reflect;
        vec3 temp_d = d_reflect;

        if(rayPayload.reflector < 1.0) // if less than fully reflective, do scattering
        {
            vec3 o_scatter = hitPos + rayPayload.normal * 0.01;
            vec3 d_scatter = cosWeightedRandomHemisphereDirection(rayPayload.normal, prng_state);

            temp_o = mix(temp_o, o_scatter, 1.0 - rayPayload.reflector);
            temp_d = mix(temp_d, d_scatter, 1.0 - rayPayload.reflector);
        }

        return rayPayload.opacity;

        if(rayPayload.opacity < 1.0) // if partially transparent, do refraction
        {
            vec3 o_transparent = vec3(0.0);
            vec3 d_transparent = vec3(0.0);

            // Incoming
            if(dot(d, rayPayload.normal) <= 0.0)
            {
                o_transparent = hitPos.xyz - rayPayload.normal * 0.01f;
                d_transparent = refract(d, rayPayload.normal, eta);
            }
            else // Outgoing
            {
                vec3 temp_dir = refract(d, -rayPayload.normal, 1.0 / eta);

                if(temp_dir != vec3(0.0))
                {
                    o_transparent = hitPos.xyz + rayPayload.normal * 0.01f;
                    d_transparent = temp_dir;
                }
                else
                {
                    // total internal reflection
                    o_transparent = hitPos.xyz - rayPayload.normal * 0.01f;
                    d_transparent = reflect(d, -rayPayload.normal);
                }
            }

            temp_o = mix(temp_o, o_transparent, 1.0 - rayPayload.opacity);
            temp_d = mix(temp_d, d_transparent, 1.0 - rayPayload.opacity);
        }
            
        o = temp_o;
        d = normalize(temp_d);
        
    }

    final_pos = hitPos;
    rayPayload = r;
    return ret_colour / total;
}

When I make the statement return rayPayload.opacity; it returns the following image, which is what I expect:

enter image description here

However, if you comment out that return statement, the if statement on the next line is never run, even though it's obviously not 1.0 in some parts of the image. It's the strangest problem.

The full code is at: https://github.com/sjhalayka/cornell_box_textured

Basically, I have reflection caustics working, but I cannot get refraction caustics to work yet (in the new version 2.0 of my path tracer).

Any big errors that I'm not seeing here?

Thanks for your time.

$\endgroup$
2
  • $\begingroup$ Can't dive into your code (though it seems you found the problem anyway). But regarding the question posted as a title: Vulkan with glsl on most cards supports debugPrintfEXT (see LunarG paper about it). You have to be careful to limit the output - I print only when pressing a key and only for the center pixel. This limits the output to something I can actually read through and analyze. Also, depending on the bug checkout NVidia NSight. $\endgroup$
    – Tare
    Commented Sep 21, 2023 at 7:17
  • $\begingroup$ Thank you so much for the guidance. $\endgroup$ Commented Sep 21, 2023 at 15:26

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.