28 const float g2 =
g *
g;
29 const float g3 = g2 *
g;
30 const float g4 = g3 *
g;
31 const float g5 = g4 *
g;
32 const float g6 = g5 *
g;
33 const float g7 = g6 *
g;
35 const float A = 1.8260523782f + -1.28451056436f *
g + -1.79904629312f * g2 +
36 9.19393289202f * g3 + -22.8215585862f * g4 + 32.0234874259f * g5 +
37 -23.6264803333f * g6 + 7.21067002658f * g7;
38 const float B = 4.98511194385f +
40 expf(31.1491581433f *
g + -201.847017512f * g2 + 841.576016723f * g3 +
41 -2018.09288505f * g4 + 2731.71560286f * g5 + -1935.41424244f * g6 +
43 const float C = 1.09686102424f + -0.394704063468f *
g + 1.05258115941f * g2 +
44 -8.83963712726f * g3 + 28.8643230661f * g4 + -46.8802913581f * g5 +
45 38.5402837518f * g6 + -12.7181042538f * g7;
46 const float D = 0.496310210422f + 0.360146581622f *
g + -2.15139309747f * g2 +
47 17.8896899217f * g3 + -55.2984010333f * g4 + 82.065982243f * g5 +
48 -58.5106008578f * g6 + 15.8478295021f * g7;
49 const float E = 4.23190299701f +
51 expf(76.7316253952f *
g + -594.356773233f * g2 + 2448.8834203f * g3 +
52 -5576.68528998f * g4 + 7116.60171912f * g5 + -4763.54467887f * g6 +
54 const float F = 2.40602999408f + -2.51814844609f *
g + 9.18494908356f * g2 +
55 -79.2191708682f * g3 + 259.082868209f * g4 + -403.613804597f * g5 +
56 302.85712436f * g6 + -87.4370473567f * g7;
62 *alpha =
clamp(*alpha, 0.0f, 0.999999f);
64 float sigma_t_prime = 1.0f /
fmaxf(d, 1e-16f);
65 *sigma_t = sigma_t_prime / (1.0f -
g);
70 const float anisotropy,
75 float sigma_t_x, sigma_t_y, sigma_t_z;
76 float alpha_x, alpha_y, alpha_z;
90 const float min_alpha = 0.2f;
91 if (alpha_x < min_alpha) {
92 (*throughput).x *= alpha_x / min_alpha;
95 if (alpha_y < min_alpha) {
96 (*throughput).y *= alpha_y / min_alpha;
99 if (alpha_z < min_alpha) {
100 (*throughput).z *= alpha_z / min_alpha;
104 *sigma_t =
make_float3(sigma_t_x, sigma_t_y, sigma_t_z);
126 return 1.0f / ((
v - cos_theta) * phase_log);
134 return v - (
v + 1.0f) *
expf(-rand * phase_log);
140 return 1.0f /
sqrtf(1.0f -
powf(alpha, 2.44294f - 0.0215813f * alpha + 0.578637f / alpha));
145 float sin_theta =
safe_sqrtf(1.0f - cos_theta * cos_theta);
151 return dir.
x *
T + dir.
y *
B + dir.
z *
D;
163 return hit ?
T : sigma_t *
T;
168 #define SUBSURFACE_RANDOM_WALK_SIMILARITY_LEVEL 9
176 float bssrdf_u, bssrdf_v;
191 if (
dot(-Ng,
D) <= 0.0f) {
203 ray.self.object = object;
204 ray.self.prim = prim;
217 float3 sigma_s = sigma_t * alpha;
229 if (diffusion_length == 1.0f) {
237 const float phase_log =
logf((diffusion_length + 1.0f) / (diffusion_length - 1.0f));
244 bool have_opposite_interface =
false;
245 float opposite_distance = 0.0f;
249 const float guided_fraction = 1.0f -
fmaxf(0.5f,
powf(
fabsf(anisotropy), 0.125f));
251 #ifdef SUBSURFACE_RANDOM_WALK_SIMILARITY_LEVEL
252 float3 sigma_s_star = sigma_s * (1.0f - anisotropy);
253 float3 sigma_t_star = sigma_t - sigma_s + sigma_s_star;
254 float3 sigma_t_org = sigma_t;
255 float3 sigma_s_org = sigma_s;
256 const float anisotropy_org = anisotropy;
257 const float guided_fraction_org = guided_fraction;
264 #ifdef SUBSURFACE_RANDOM_WALK_SIMILARITY_LEVEL
266 float anisotropy, guided_fraction;
269 anisotropy = anisotropy_org;
270 guided_fraction = guided_fraction_org;
271 sigma_t = sigma_t_org;
272 sigma_s = sigma_s_org;
276 guided_fraction = 0.75f;
277 sigma_t = sigma_t_star;
278 sigma_s = sigma_s_star;
291 float backward_fraction = 0.0f;
292 float forward_pdf_factor = 0.0f;
293 float forward_stretching = 1.0f;
294 float backward_pdf_factor = 0.0f;
295 float backward_stretching = 1.0f;
306 bool guide_backward =
false;
307 if (have_opposite_interface) {
311 float x =
clamp(
dot(ray.P -
P, -
N), 0.0f, opposite_distance);
312 backward_fraction = 1.0f /
313 (1.0f +
expf((opposite_distance - 2.0f *
x) / diffusion_length));
318 float scatter_u, scatter_v;
326 if (guide_backward) {
327 cos_theta = -cos_theta;
335 cos_theta =
dot(newD,
N);
353 forward_stretching = (1.0f - cos_theta / diffusion_length);
354 backward_stretching = (1.0f + cos_theta / diffusion_length);
356 sample_sigma_t *= guide_backward ? backward_stretching : forward_stretching;
361 float t = -
logf(1.0f - randt) / sample_sigma_t;
376 scene_intersect_local(kg, &ray, &ss_isect,
object,
NULL, 1);
377 hit = (ss_isect.num_hits > 0);
380 ray.tmax = ss_isect.hits[0].t;
386 have_opposite_interface =
true;
387 opposite_distance =
dot(ray.P + ray.tmax * ray.D -
P, -
N);
408 if (have_opposite_interface) {
413 guided_pdf * forward_pdf_factor, back_pdf * backward_pdf_factor, backward_fraction);
417 guided_pdf *= forward_pdf_factor;
421 pdf =
mix(pdf, guided_pdf, guided_fraction);
427 throughput *= (hit ? transmittance : sigma_s * transmittance) /
dot(channel_pdf, pdf);
MINLINE float safe_sqrtf(float a)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
__forceinline int reduce_max(const avxi &v)
__forceinline int reduce_min(const avxi &v)
ATTR_WARN_UNUSED_RESULT const BMVert * v
#define kernel_assert(cond)
#define ccl_device_forceinline
#define ccl_device_inline
#define CCL_NAMESPACE_END
const KernelGlobalsCPU *ccl_restrict KernelGlobals
ccl_device_forceinline float differential_zero_compact()
#define VOLUME_THROUGHPUT_EPSILON
ccl_device float3 volume_color_transmittance(float3 sigma, float t)
ccl_device float3 henyey_greenstrein_sample(float3 D, float g, float randu, float randv, ccl_private float *pdf)
ccl_device float single_peaked_henyey_greenstein(float cos_theta, float g)
ccl_device float volume_channel_get(float3 value, int channel)
ccl_device int volume_sample_channel(float3 albedo, float3 throughput, float rand, ccl_private float3 *pdf)
ccl_device_inline uint cmj_hash(uint i, uint p)
#define BSSRDF_MAX_BOUNCES
T dot(const vec_base< T, Size > &a, const vec_base< T, Size > &b)
T clamp(const T &a, const T &min, const T &max)
static const pxr::TfToken g("g", pxr::TfToken::Immortal)
ccl_device_inline float path_state_rng_1D(KernelGlobals kg, ccl_private const RNGState *rng_state, int dimension)
ccl_device_inline void path_state_rng_2D(KernelGlobals kg, ccl_private const RNGState *rng_state, int dimension, ccl_private float *fx, ccl_private float *fy)
ccl_device_inline void sample_cos_hemisphere(const float3 N, float randu, float randv, ccl_private float3 *omega_in, ccl_private float *pdf)
IntegratorStateCPU *ccl_restrict IntegratorState
#define INTEGRATOR_STATE_WRITE(state, nested_struct, member)
#define INTEGRATOR_STATE(state, nested_struct, member)
ccl_device_forceinline float diffusion_length_dwivedi(float alpha)
ccl_device_forceinline float3 direction_from_cosine(float3 D, float cos_theta, float randv)
ccl_device_forceinline float sample_phase_dwivedi(float v, float phase_log, float rand)
#define SUBSURFACE_RANDOM_WALK_SIMILARITY_LEVEL
ccl_device_inline bool subsurface_random_walk(KernelGlobals kg, IntegratorState state, RNGState rng_state, ccl_private Ray &ray, ccl_private LocalIntersection &ss_isect)
ccl_device void subsurface_random_walk_coefficients(const float3 albedo, const float3 radius, const float anisotropy, ccl_private float3 *sigma_t, ccl_private float3 *alpha, ccl_private float3 *throughput)
ccl_device_forceinline float3 subsurface_random_walk_pdf(float3 sigma_t, float t, bool hit, ccl_private float3 *transmittance)
ccl_device_forceinline float eval_phase_dwivedi(float v, float phase_log, float cos_theta)
CCL_NAMESPACE_BEGIN ccl_device void subsurface_random_walk_remap(const float albedo, const float d, float g, ccl_private float *sigma_t, ccl_private float *alpha)
static int blend(const Tex *tex, const float texvec[3], TexResult *texres)
ccl_device_inline float3 safe_divide_color(float3 a, float3 b)
ccl_device_inline bool isfinite_safe(float f)
ccl_device_inline void make_orthonormals(const float3 N, ccl_private float3 *a, ccl_private float3 *b)
BLI_INLINE float D(const float *data, const int res[3], int x, int y, int z)