Sampling the unit sphere using square_to_uniform_sphere #968
-
Hi, I want to uniformly sample the unit sphere. To this end, I wrote this function: def uniform_sphere_directions(n2):
n1 = int(np.ceil(np.sqrt(n2)))
offset = 1 / (2 * n1)
x, y = dr.meshgrid(
dr.linspace(mi.Float32, 0, 1, n1, endpoint=False) + offset,
dr.linspace(mi.Float32, 0, 1, n1, endpoint=False) + offset,
)
pt = mi.Point2f(x, y)
return mi.warp.square_to_uniform_sphere(pt) When I call it with n2=36, I get this result: I'm a bit surprised that spacing between points doesn't seem to be equal in the azimuthal and elevation directions. If one considers a full 2pi circle, then for horizontal cross-sections there are 6 points on that circle, whereas for vertical cross-sections, there are 12. If we're uniformly sampling the unit sphere, I wouldn't expect such asymmetry. If I modify my function so the 2nd argument to meshgrid becomes This looks more uniform, but I'm puzzled as there doesn't seem to be a bug here. I went and looked at the implementation in mitsuba: /// Uniformly sample a vector on the unit sphere with respect to solid angles
template <typename Value>
MI_INLINE Vector<Value, 3> square_to_uniform_sphere(const Point<Value, 2> &sample) {
Value z = dr::fnmadd(2.f, sample.y(), 1.f),
r = circ(z);
auto [s, c] = dr::sincos(2.f * dr::Pi<Value> * sample.x());
return { r * c, r * s, z };
} This matches with the theory and implementation from the pbrt book: So I guess my question is, what am I missing here, and does |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Hi @tomas16 , |
Beta Was this translation helpful? Give feedback.
Hi @tomas16 ,$dS = r^2 ~\sin{\theta} d\theta d\phi$ , so along the polar axis points are denser near the equator.$||dp/d\theta||=||dp/d\phi||$ -- the visual uniformity after mapping meshgrid points. In fact, the azimuthal angle covers a $2\pi$ range and the polar angle only covers a range of $\pi$ , so the observed pattern is normal.
The uniform warp guarantees that area patches in the sample space will be mapped to equal-area patches on the sphere -- on a sphere
But this does not really imply