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.
$\begingroup$
$\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$– lightxbulbCommented Sep 16, 2022 at 21:00
Add a comment
|
1 Answer
$\begingroup$
$\endgroup$
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);
}