26static_assert(
sizeof(ShaderClosure) >=
sizeof(
Bssrdf),
"Bssrdf is too large!");
32 const float s =
sqrtf(3.0f * (1.0f - alpha_prime));
33 return 0.5f * alpha_prime * (1.0f +
expf(-fourthirdA * s)) *
expf(-s);
51 constexpr const int max_num_iterations = 12;
52 for (
int i = 0;
i < max_num_iterations; ++
i) {
53 xmid = 0.5f * (x0 + x1);
75 const float inv_eta = 1.0f /
bssrdf->ior;
76 const float F_dr = inv_eta * (-1.440f * inv_eta + 0.710f) + 0.668f + 0.0636f *
bssrdf->ior;
77 const float fourthirdA = (4.0f / 3.0f) * (1.0f + F_dr) /
99#define BURLEY_TRUNCATE 16.0f
100#define BURLEY_TRUNCATE_CDF 0.9963790093708328f
105 return 1.9f -
A + 3.5f * (
A - 0.8f) * (
A - 0.8f);
145 const float exp_r_3_d =
expf(-r / (3.0f * d));
146 const float exp_r_d = exp_r_3_d * exp_r_3_d * exp_r_3_d;
147 return (exp_r_d + exp_r_3_d) / (4.0f * d);
165 const float tolerance = 1e-6f;
166 const int max_iteration_count = 10;
174 r =
expf(xi * xi * 2.4f) - 1.0f;
181 for (
int i = 0;
i < max_iteration_count;
i++) {
182 const float exp_r_3 =
expf(-r / 3.0f);
183 const float exp_r = exp_r_3 * exp_r_3 * exp_r_3;
184 const float f = 1.0f - 0.25f * exp_r - 0.75f * exp_r_3 - xi;
185 const float f_ = 0.25f * exp_r + 0.25f * exp_r_3;
187 if (
fabsf(f) < tolerance || f_ == 0.0f) {
228 float sampled_radius;
233 sampled_radius = 0.0f;
238 if (channel_radius > 0.0f) {
239 const float next_sum =
sum + 1.0f;
242 sampled_radius = channel_radius;
284 bssrdf->sample_weight = sample_weight;
314 diffuse_weight =
bssrdf->weight;
339 if (bssrdf_channels > 0) {
349 bssrdf->sample_weight = 0.0f;
MINLINE float safe_sqrtf(float a)
CCL_NAMESPACE_BEGIN ccl_device ccl_private ShaderClosure * closure_alloc(ccl_private ShaderData *sd, const uint size, ClosureType type, Spectrum weight)
ccl_device_inline ccl_private ShaderClosure * bsdf_alloc(ccl_private ShaderData *sd, const int size, Spectrum weight)
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ccl_device int bsdf_diffuse_setup(ccl_private DiffuseBsdf *bsdf)
ccl_device void bssrdf_setup_radius(ccl_private Bssrdf *bssrdf, const ClosureType type)
ccl_device_inline Spectrum bssrdf_burley_compatible_mfp(Spectrum r)
ccl_device void bssrdf_sample(const Spectrum radius, float xi, ccl_private float *r, ccl_private float *h)
ccl_device_forceinline float bssrdf_burley_root_find(const float xi)
ccl_device float bssrdf_dipole_compute_Rd(const float alpha_prime, const float fourthirdA)
ccl_device_forceinline float bssrdf_pdf(const Spectrum radius, const float r)
ccl_device_inline ccl_private Bssrdf * bssrdf_alloc(ccl_private ShaderData *sd, Spectrum weight)
ccl_device float bssrdf_burley_eval(const float d, const float r)
ccl_device float bssrdf_num_channels(const Spectrum radius)
ccl_device void bssrdf_burley_sample(const float d, const float xi, ccl_private float *r, ccl_private float *h)
#define BURLEY_TRUNCATE_CDF
ccl_device void bssrdf_burley_setup(ccl_private Bssrdf *bssrdf)
ccl_device float bssrdf_dipole_compute_alpha_prime(const float rd, const float fourthirdA)
ccl_device_inline float bssrdf_burley_fitting(const float A)
ccl_device float bssrdf_burley_pdf(const float d, const float r)
ccl_device int bssrdf_setup(ccl_private ShaderData *sd, ccl_private Bssrdf *bssrdf, const int path_flag, ClosureType type)
ccl_device_forceinline Spectrum bssrdf_eval(const Spectrum radius, const float r)
static T sum(const btAlignedObjectArray< T > &items)
#define ccl_device_forceinline
#define SPECTRUM_CHANNELS
#define ccl_device_inline
#define FOREACH_SPECTRUM_CHANNEL(counter)
#define GET_SPECTRUM_CHANNEL(v, i)
#define BSSRDF_MIN_RADIUS
#define CCL_NAMESPACE_END
#define CLOSURE_WEIGHT_CUTOFF
constexpr T clamp(T, U, U) RET
@ CLOSURE_BSSRDF_BURLEY_ID
@ CLOSURE_BSSRDF_RANDOM_WALK_ID
@ CLOSURE_BSSRDF_RANDOM_WALK_SKIN_ID
@ PATH_RAY_DIFFUSE_ANCESTOR
ccl_device_inline dual1 reduce_add(const dual< T > a)
closure color bssrdf(string method, normal N, vector radius, color albedo) BUILTIN