2
$\begingroup$

I'm not sure I have the right terminology, but in rendering it can be useful to draw cosine weighted samples from a hemisphere. In this case the integral (over the weights) is Pi. Now I don´t want to sample the complete hemisphere, but rather a cone, centered around the polar axis. But not in a uniformly like e.g. the function UniformSampleCone() in pbrt, but rather also in a cosine weighted manner. In other words a subset of the cosine weighted hemisphere. Is there a formula compute the integral of weights for this? I was thinking something like (1 - cos(cone_angle)) * Pi, but it is not quite right.

$\endgroup$
1
  • 2
    $\begingroup$ $\int_{0}^{\theta_{\max}}\int_{0}^{2\pi}C\cos t \sin t \,dt \, d\phi = 1$ then $C = \frac{1}{\pi(1-\cos^2(\theta_{\max}))}$. One way to sample it is $\phi = 2\pi u$ and $\cos\theta = \sqrt{1-v\sin^2(\theta_{\max})}$. $\endgroup$
    – lightxbulb
    Commented Sep 16, 2022 at 21:00

1 Answer 1

3
$\begingroup$

As I was referencing PBRT, here are the functions I ended up with:

fn coneCosine(uv: Vec2f, cos_theta_max: f32) Vec4f {
    const xy = @splat(2, @sqrt(1.0 - cos_theta_max * cos_theta_max)) * diskConcentric(uv);
    const z = @sqrt(std.math.max(0.0, 1.0 - xy[0] * xy[0] - xy[1] * xy[1]));

    return .{ xy[0], xy[1], z, 0.0 };
}

fn conePdfCosine(cos_theta_max: f32) f32 {
    return 1.0 / ((1.0 - (cos_theta_max * cos_theta_max)) * std.math.pi);
}
$\endgroup$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.