45#define MNEE_MAX_ITERATIONS 64
46#define MNEE_MAX_INTERSECTION_COUNT 10
47#define MNEE_SOLVER_THRESHOLD 0.001f
48#define MNEE_MINIMUM_STEP_SIZE 0.0001f
49#define MNEE_MAX_CAUSTIC_CASTERS 6
50#define MNEE_MIN_DISTANCE 0.001f
51#define MNEE_MIN_PROGRESS_DISTANCE 0.0001f
52#define MNEE_MIN_DETERMINANT 0.0001f
53#define MNEE_PROJECTION_DISTANCE_MULTIPLIER 2.f
99 a.
x *
b.x + a.
y *
b.z, a.
x *
b.y + a.
y *
b.w, a.
z *
b.x + a.
w *
b.z, a.
z *
b.y + a.
w *
b.w);
105 return m.
x * m.
w - m.
y * m.
z;
132 sd_vtx->type = isect->type;
138 sd_vtx->time = ray->time;
140 sd_vtx->prim = isect->prim;
141 sd_vtx->ray_length = isect->t;
143 sd_vtx->u = isect->u;
144 sd_vtx->v = isect->v;
155 sd_vtx->P = (1.f - isect->u - isect->v) *
verts[0] + isect->u *
verts[1] + isect->v *
verts[2];
164 kg, sd_vtx->object, sd_vtx->prim, sd_vtx->time,
verts,
normals);
199 const float inv_n_len = 1.f / n_len;
202 dn_du -= vtx->n *
dot(vtx->n, dn_du);
203 dn_dv -= vtx->n *
dot(vtx->n, dn_dv);
207 const float inv_len_dp_du = 1.f /
len(dp_du);
208 dp_du *= inv_len_dp_du;
209 dn_du *= inv_len_dp_du;
211 const float dpdu_dot_dpdv =
dot(dp_du, dp_dv);
212 dp_dv -= dpdu_dot_dpdv * dp_du;
213 dn_dv -= dpdu_dot_dpdv * dn_du;
215 const float inv_len_dp_dv = 1.f /
len(dp_dv);
216 dp_dv *= inv_len_dp_dv;
217 dn_dv *= inv_len_dp_dv;
234 vtx->n_offset = n_offset;
242 vtx->object = sd_vtx->object;
243 vtx->prim = sd_vtx->prim;
244 vtx->shader = sd_vtx->shader;
249#if defined(__KERNEL_METAL__)
257 const int vertex_count,
260 const bool light_fixed_direction,
263 for (
int vi = 0; vi < vertex_count; vi++) {
267 float3 wi = (vi == 0) ? surface_sample_pos -
v.p : vertices[vi - 1].p -
v.p;
276 float3 wo = (vi == vertex_count - 1) ?
278 vertices[vi + 1].p -
v.p;
288 if (
dot(wi,
v.ng) < .0f) {
294 const float ilh = 1.f /
len(
H);
301 const float dp_du_dot_n =
dot(
v.dp_du,
v.n);
302 float3 s =
v.dp_du - dp_du_dot_n *
v.n;
303 const float inv_len_s = 1.f /
len(s);
313 dH_du = (v_prev.dp_du - wi *
dot(wi, v_prev.dp_du)) * ili;
314 dH_dv = (v_prev.dp_dv - wi *
dot(wi, v_prev.dp_dv)) * ili;
315 dH_du -=
H *
dot(dH_du,
H);
316 dH_dv -=
H *
dot(dH_dv,
H);
324 if (vi == vertex_count - 1 && light_fixed_direction) {
325 dH_du = ili * (-
v.dp_du + wi *
dot(wi,
v.dp_du));
326 dH_dv = ili * (-
v.dp_dv + wi *
dot(wi,
v.dp_dv));
329 dH_du = -
v.dp_du * (ili + ilo) + wi * (
dot(wi,
v.dp_du) * ili) +
330 wo * (
dot(wo,
v.dp_du) * ilo);
331 dH_dv = -
v.dp_dv * (ili + ilo) + wi * (
dot(wi,
v.dp_dv) * ili) +
332 wo * (
dot(wo,
v.dp_dv) * ilo);
334 dH_du -=
H *
dot(dH_du,
H);
335 dH_dv -=
H *
dot(dH_dv,
H);
339 float3 ds_du = -inv_len_s * (
dot(
v.dp_du,
v.dn_du) *
v.n + dp_du_dot_n *
v.dn_du);
340 float3 ds_dv = -inv_len_s * (
dot(
v.dp_du,
v.dn_dv) *
v.n + dp_du_dot_n *
v.dn_dv);
341 ds_du -= s *
dot(s, ds_du);
342 ds_dv -= s *
dot(s, ds_dv);
349 dot(dH_dv, t) +
dot(
H, dt_dv));
352 if (vi < vertex_count - 1) {
354 dH_du = (v_next.dp_du - wo *
dot(wo, v_next.dp_du)) * ilo;
355 dH_dv = (v_next.dp_dv - wo *
dot(wo, v_next.dp_dv)) * ilo;
356 dH_du -=
H *
dot(dH_du,
H);
357 dH_dv -=
H *
dot(dH_dv,
H);
384 float4 Lk = vertices[0].b;
389 C[0] = vertices[0].constraint;
391 for (
int k = 1; k < vertex_count; k++) {
394 Lk = vertices[k].b -
mat22_mult(
A, vertices[k - 1].c);
402 dx[vertex_count - 1] =
mat22_mult(Li[vertex_count - 1],
C[vertex_count - 1]);
403 for (
int k = vertex_count - 2; k > -1; k--) {
415 const bool light_fixed_direction,
416 const int vertex_count,
427 projection_ray.
tmin = 0.0f;
428 projection_ray.
time = sd->time;
437 bool reduce_stepsize =
false;
438 bool resolve_constraint =
true;
440 if (resolve_constraint) {
443 vertex_count, vertices, sd->P, light_fixed_direction,
light_sample))
449 float constraint_norm = 0.f;
450 for (
int vi = 0; vi < vertex_count; vi++) {
451 constraint_norm =
fmaxf(constraint_norm,
len(vertices[vi].constraint));
466 for (
int vi = 0; vi < vertex_count; vi++) {
474 const float3 wo = tentative_p - sd->P;
475 if (
dot(sd->Ng, wo) <= 0.f) {
477 tentative_p =
mv.p +
beta * (dx[vi].
x *
mv.dp_du + dx[vi].
y *
mv.dp_dv);
486 projection_ray.
self.
prim = sd->prim;
487 projection_ray.
P = sd->P;
493 projection_ray.
P = pv.p;
498 bool projection_success =
false;
506 if (projection_isect.
object ==
mv.object) {
507 projection_success =
true;
515 if (!projection_success) {
516 reduce_stepsize =
true;
528 kg, &tv,
mv.bsdf,
mv.eta,
mv.n_offset, &projection_ray, &projection_isect, sd_vtx);
539 if (!reduce_stepsize) {
540 for (
int vi = 0; vi < vertex_count; vi++) {
544 const float3 wi = (vi == 0 ? sd->P : tentative[vi - 1].
p) - tv.p;
546 const float3 wo = (vi == vertex_count - 1) ? light_fixed_direction ? ls->D : ls->P - tv.p :
547 tentative[vi + 1].
p - tv.p;
549 if (
dot(tv.n, wi) *
dot(tv.n, wo) >= 0.f) {
550 reduce_stepsize =
true;
556 if (reduce_stepsize) {
558 reduce_stepsize =
false;
559 resolve_constraint =
false;
571 for (
int vi = 0; vi < vertex_count; vi++) {
572 vertices[vi] = tentative[vi];
576 resolve_constraint =
true;
587 const float sample_u,
588 const float sample_v)
594 if (alpha_x == alpha_y) {
595 const float phi = sample_v *
M_2PI_F;
597 alpha2 = alpha_x * alpha_x;
601 if (sample_v > .5f) {
605 const float alpha_x2 = alpha_x * alpha_x;
606 const float alpha_y2 = alpha_y * alpha_y;
607 alpha2 = 1.f / (cos_phi * cos_phi / alpha_x2 +
sin_phi *
sin_phi / alpha_y2);
611 float tan2_theta = alpha2;
613 tan2_theta *= -
logf(1.0f - sample_u);
616 tan2_theta *= sample_u / (1.0f - sample_u);
618 const float cos2_theta = 1.0f / (1.0f + tan2_theta);
636 const float cosNI =
dot(bsdf->N, wi);
637 const float cosNO =
dot(bsdf->N, wo);
640 const float cosHI =
dot(Ht, wi);
642 const float alpha2 = bsdf->alpha_x * bsdf->alpha_y;
643 const float cosThetaM =
dot(bsdf->N, Ht);
667 return bsdf->weight * transmittance *
G *
fabsf(cosHI / (cosNI *
sqr(cosThetaM)));
673 const bool light_fixed_direction,
674 const int vertex_count,
683 float4 Lk = vertices[0].b;
689 float det_dh_dx = Lk_det;
691 for (
int k = 1; k < vertex_count; k++) {
694 Lk = vertices[k].b -
mat22_mult(vertices[k].a,
U[k - 1]);
706 const int mi = vertex_count - 1;
718 float3 wi = vertex_count == 1 ? sd->P - m.p : vertices[mi - 1].p - m.p;
719 const float ili = 1.f /
len(wi);
724 if (
dot(wi, m.ng) < .0f) {
731 if (light_fixed_direction) {
737 const float ilh = 1.f /
len(
H);
740 const float ilo = -eta * ilh;
744 const float cos_phi =
dot(wo, s);
750 dH_dtheta -=
H *
dot(dH_dtheta,
H);
751 dH_dphi -=
H *
dot(dH_dphi,
H);
756 dot(dH_dtheta, s),
dot(dH_dphi, s),
dot(dH_dtheta, t),
dot(dH_dphi, t));
764 float ilo = 1.f /
len(wo);
769 const float ilh = 1.f /
len(
H);
774 float3 dH_du = (dp_du - wo *
dot(wo, dp_du)) * ilo;
775 float3 dH_dv = (dp_dv - wo *
dot(wo, dp_dv)) * ilo;
776 dH_du -=
H *
dot(dH_du,
H);
777 dH_dv -=
H *
dot(dH_dv,
H);
789 for (
int k = vertex_count - 2; k > -1; k--) {
794 *dh_dx =
fabsf(det_dh_dx);
804 const bool light_fixed_direction,
805 const int vertex_count,
818 kg, ls, vertices[vertex_count - 1].p, vertices[vertex_count - 1].n, path_flag);
850 sd, ls, light_fixed_direction, vertex_count, vertices, &dx1_dxlight, &dh_dx))
856 const float dw0_dx1 =
fabsf(
dot(wo, vertices[0].n)) /
sqr(wo_len);
859 const float G =
fminf(dw0_dx1 * dx1_dxlight, 2.f);
868 probe_ray.
tmin = 0.0f;
871 probe_ray.
time = sd->time;
880 for (
int vi = 0; vi < vertex_count; vi++) {
928 wo = (vi == vertex_count - 1) ? (light_fixed_direction ? ls->D : ls->P -
v.p) :
929 vertices[vi + 1].p -
v.p;
970 probe_ray.
tmin = 0.0f;
974 probe_ray.
tmax = ls->t;
978 probe_ray.
D = ls->P - probe_ray.
P;
983 probe_ray.
time = sd->time;
988 int vertex_count = 0;
1025 bool found_refractive_microfacet_bsdf =
false;
1026 for (
int ci = 0; ci < sd_mnee->num_closure; ci++) {
1027 ccl_private ShaderClosure *bsdf = &sd_mnee->closure[ci];
1031 found_refractive_microfacet_bsdf =
true;
1035 const float eta = (sd_mnee->flag &
SD_BACKFACING) ? 1.0f / microfacet_bsdf->
ior :
1036 microfacet_bsdf->ior;
1039 if (microfacet_bsdf->alpha_x > 0.f && microfacet_bsdf->alpha_y > 0.f) {
1043 microfacet_bsdf->alpha_x,
1044 microfacet_bsdf->alpha_y,
1054 if (!found_refractive_microfacet_bsdf) {
1067 if (vertex_count == 0) {
1098 bool light_fixed_direction = (ls->t ==
FLT_MAX);
1101 if (klight->area.tan_half_spread == 0.0f) {
1103 light_fixed_direction =
true;
1109 if (
mnee_newton_solver(kg, sd, sd_mnee, ls, light_fixed_direction, vertex_count, vertices)) {
1112 kg,
state, sd, sd_mnee, ls, light_fixed_direction, vertex_count, vertices, throughput))
1117 return vertex_count;
MINLINE float safe_sqrtf(float a)
ATTR_WARN_UNUSED_RESULT const BMVert * v
ccl_device_inline float bsdf_G(const float alpha2, const float cos_N)
ccl_device_forceinline void microfacet_fresnel(KernelGlobals kg, const ccl_private MicrofacetBsdf *bsdf, const float cos_theta_i, ccl_private float *r_cos_theta_t, ccl_private Spectrum *r_reflectance, ccl_private Spectrum *r_transmittance)
ccl_device_inline float cos_theta(const float3 w)
ccl_device float sin_phi(const float3 w)
ccl_device_inline float sin_theta(const float3 w)
dot(value.rgb, luminance_coefficients)") DEFINE_VALUE("REDUCE(lhs
static __attribute__((constructor)) void cpu_check()
ccl_device_forceinline float intersection_t_offset(const float t)
ccl_device_forceinline int intersection_get_object_flags(KernelGlobals kg, const ccl_private Intersection *ccl_restrict isect)
ccl_device_forceinline void light_sample_update(KernelGlobals kg, ccl_private LightSample *ls, const float3 P, const float3 N, const uint32_t path_flag)
CCL_NAMESPACE_BEGIN ccl_device_noinline_cpu Spectrum light_sample_shader_eval(KernelGlobals kg, IntegratorState state, ccl_private ShaderData *ccl_restrict emission_sd, ccl_private LightSample *ccl_restrict ls, const float time)
#define CLOSURE_IS_GLASS(type)
#define ccl_device_forceinline
#define kernel_data_fetch(name, index)
const ThreadKernelGlobalsCPU * KernelGlobals
#define ccl_device_inline
#define CLOSURE_IS_REFRACTION(type)
#define CCL_NAMESPACE_END
ccl_device_forceinline float differential_make_compact(const float dD)
ccl_device_forceinline float differential_zero_compact()
ccl_device_inline void triangle_vertices_and_normals(KernelGlobals kg, const int prim, float3 P[3], float3 N[3])
static float normals[][3]
VecBase< float, D > normalize(VecOp< float, D >) RET
VecBase< float, 3 > cross(VecOp< float, 3 >, VecOp< float, 3 >) RET
float distance(VecOp< float, D >, VecOp< float, D >) RET
ccl_device_intersect bool scene_intersect(KernelGlobals kg, const ccl_private Ray *ray, const uint visibility, ccl_private Intersection *isect)
ccl_device_inline Transform object_get_transform(KernelGlobals kg, const ccl_private ShaderData *sd)
#define object_normal_transform_auto
#define object_position_transform_auto
ccl_device_inline bool light_sample(KernelGlobals kg, const int lamp, const float2 rand, const float3 P, const float3 N, const int shader_flags, const uint32_t path_flag, ccl_private LightSample *ls)
@ CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID
@ SD_OBJECT_NEGATIVE_SCALE
@ SD_OBJECT_TRANSFORM_APPLIED
@ SD_OBJECT_CAUSTICS_CASTER
ccl_device_inline void bsdf_eval_mul(ccl_private BsdfEval *eval, const float value)
ccl_device_inline float sin_from_cos(const float c)
ccl_device_inline float beta(const float x, const float y)
ccl_device void fast_sincosf(float x, ccl_private float *sine, ccl_private float *cosine)
CCL_NAMESPACE_BEGIN ccl_device_inline float2 zero_float2()
ccl_device_inline float2 normalize_len(const float2 a, ccl_private float *t)
ccl_device_inline void make_orthonormals(const float3 N, ccl_private float3 *a, ccl_private float3 *b)
CCL_NAMESPACE_BEGIN ccl_device_inline float4 zero_float4()
ccl_device_forceinline bool mnee_solve_matrix_h_to_x(const int vertex_count, ccl_private ManifoldVertex *vertices, ccl_private float2 *dx)
#define MNEE_MAX_INTERSECTION_COUNT
ccl_device_forceinline Spectrum mnee_eval_bsdf_contribution(KernelGlobals kg, ccl_private ShaderClosure *closure, const float3 wi, const float3 wo)
#define MNEE_MAX_ITERATIONS
#define MNEE_MIN_PROGRESS_DISTANCE
#define MNEE_MIN_DETERMINANT
ccl_device_forceinline float2 mnee_sample_bsdf_dh(ClosureType type, const float alpha_x, const float alpha_y, const float sample_u, const float sample_v)
ccl_device_inline float mat22_inverse(const float4 m, ccl_private float4 &m_inverse)
ccl_device_forceinline bool mnee_compute_constraint_derivatives(const int vertex_count, ccl_private ManifoldVertex *vertices, const ccl_private float3 &surface_sample_pos, const bool light_fixed_direction, const float3 light_sample)
#define MNEE_MIN_DISTANCE
ccl_device_forceinline bool mnee_compute_transfer_matrix(const ccl_private ShaderData *sd, const ccl_private LightSample *ls, const bool light_fixed_direction, const int vertex_count, ccl_private ManifoldVertex *vertices, ccl_private float *dx1_dxlight, ccl_private float *dh_dx)
ccl_device_inline float mat22_determinant(const float4 m)
#define MNEE_PROJECTION_DISTANCE_MULTIPLIER
#define MNEE_MAX_CAUSTIC_CASTERS
ccl_device_inline float2 mat22_mult(const float4 a, const float2 b)
ccl_device_forceinline void mnee_setup_manifold_vertex(KernelGlobals kg, ccl_private ManifoldVertex *vtx, ccl_private ShaderClosure *bsdf, const float eta, const float2 n_offset, const ccl_private Ray *ray, const ccl_private Intersection *isect, ccl_private ShaderData *sd_vtx)
ccl_device_forceinline bool mnee_path_contribution(KernelGlobals kg, IntegratorState state, ccl_private ShaderData *sd, ccl_private ShaderData *sd_mnee, ccl_private LightSample *ls, const bool light_fixed_direction, const int vertex_count, ccl_private ManifoldVertex *vertices, ccl_private BsdfEval *throughput)
ccl_device_forceinline bool mnee_newton_solver(KernelGlobals kg, const ccl_private ShaderData *sd, ccl_private ShaderData *sd_vtx, const ccl_private LightSample *ls, const bool light_fixed_direction, const int vertex_count, ccl_private ManifoldVertex *vertices)
ccl_device_forceinline int kernel_path_mnee_sample(KernelGlobals kg, IntegratorState state, ccl_private ShaderData *sd, ccl_private ShaderData *sd_mnee, const ccl_private RNGState *rng_state, ccl_private LightSample *ls, ccl_private BsdfEval *throughput)
#define MNEE_MINIMUM_STEP_SIZE
#define MNEE_SOLVER_THRESHOLD
ccl_device_inline void motion_triangle_vertices_and_normals(KernelGlobals kg, const int object, const int prim, const float time, float3 verts[3], float3 normals[3])
CCL_NAMESPACE_BEGIN ccl_device_inline float3 motion_triangle_point_from_uv(KernelGlobals kg, ccl_private ShaderData *sd, const float u, const float v, const float3 verts[3])
ccl_device_inline float2 path_state_rng_2D(KernelGlobals kg, const ccl_private RNGState *rng_state, const int dimension)
ccl_device_inline void shader_setup_from_sample(KernelGlobals kg, ccl_private ShaderData *ccl_restrict sd, const float3 P, const float3 Ng, const float3 I, const int shader, const int object, const int prim, const float u, const float v, const float t, const float time, const bool object_space, const bool is_lamp)
ccl_device_inline void shader_setup_from_ray(KernelGlobals kg, ccl_private ShaderData *ccl_restrict sd, const ccl_private Ray *ccl_restrict ray, const ccl_private Intersection *ccl_restrict isect)
CCL_NAMESPACE_BEGIN ccl_device void shader_setup_object_transforms(KernelGlobals kg, ccl_private ShaderData *ccl_restrict sd, const float time)
#define INTEGRATOR_STATE_WRITE(state, nested_struct, member)
#define INTEGRATOR_STATE(state, nested_struct, member)
IntegratorStateCPU * IntegratorState
ccl_private ShaderClosure * bsdf
ccl_device float surface_shader_bsdf_eval(KernelGlobals kg, IntegratorState state, ccl_private ShaderData *sd, const float3 wo, ccl_private BsdfEval *bsdf_eval, const uint light_shader_flags)
ccl_device void surface_shader_eval(KernelGlobals kg, ConstIntegratorGenericState state, ccl_private ShaderData *ccl_restrict sd, ccl_global float *ccl_restrict buffer, const uint32_t path_flag, bool use_caustics_storage=false)