diff options
author | Lukas Stockner <lukas.stockner@freenet.de> | 2020-06-06 21:08:48 +0300 |
---|---|---|
committer | Lukas Stockner <lukas.stockner@freenet.de> | 2020-06-09 23:19:15 +0300 |
commit | 63a40ed422bc61e9cd952282a636c53a9d8f3fde (patch) | |
tree | af57385fe3851343b642c06bf14896c76727d60b /intern | |
parent | d3f83d9f95504ad02121228477681db6702e9e11 (diff) |
Cycles: Fix uniform cone sampling
This code is currently only used for the Glossy Toon BSDF, but it's a generic
building block that might be used for other things in the future.
To see why the current code does not give a uniform distribution, consider that
it chooses both angles uniformly, but the smaller the angle from the center of
the cone is, the smaller the differential solid angle is (similar to how
sampling disks by choosing radius and phi uniformly does not work).
Differential Revision: https://developer.blender.org/D7948
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/kernel/kernel_montecarlo.h | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/intern/cycles/kernel/kernel_montecarlo.h b/intern/cycles/kernel/kernel_montecarlo.h index acd5086be3a..ac40840133f 100644 --- a/intern/cycles/kernel/kernel_montecarlo.h +++ b/intern/cycles/kernel/kernel_montecarlo.h @@ -85,8 +85,9 @@ ccl_device_inline void sample_uniform_hemisphere( ccl_device_inline void sample_uniform_cone( const float3 N, float angle, float randu, float randv, float3 *omega_in, float *pdf) { - float z = cosf(angle * randu); - float r = sqrtf(max(0.0f, 1.0f - z * z)); + float zMin = cosf(angle); + float z = lerp(zMin, 1.0f, randu); + float r = safe_sqrtf(1.0f - sqr(z)); float phi = M_2PI_F * randv; float x = r * cosf(phi); float y = r * sinf(phi); @@ -94,7 +95,7 @@ ccl_device_inline void sample_uniform_cone( float3 T, B; make_orthonormals(N, &T, &B); *omega_in = x * T + y * B + z * N; - *pdf = 0.5f * M_1_PI_F / (1.0f - cosf(angle)); + *pdf = M_1_2PI_F / (1.0f - zMin); } /* sample uniform point on the surface of a sphere */ |