40# define MNEE_MAX_ITERATIONS 64
41# define MNEE_MAX_INTERSECTION_COUNT 10
42# define MNEE_SOLVER_THRESHOLD 0.001f
43# define MNEE_MINIMUM_STEP_SIZE 0.0001f
44# define MNEE_MAX_CAUSTIC_CASTERS 6
45# define MNEE_MIN_DISTANCE 0.001f
46# define MNEE_MIN_PROGRESS_DISTANCE 0.0001f
47# define MNEE_MIN_DETERMINANT 0.0001f
48# define MNEE_PROJECTION_DISTANCE_MULTIPLIER 2.f
93 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);
99 return m.x * m.w - m.y * m.z;
105 float det = mat22_determinant(m);
106 if (
fabsf(det) < MNEE_MIN_DETERMINANT)
108 m_inverse =
make_float4(m.w, -m.y, -m.z, m.x) / det;
125 sd_vtx->type = isect->type;
131 sd_vtx->time = ray->time;
133 sd_vtx->prim = isect->prim;
134 sd_vtx->ray_length = isect->t;
136 sd_vtx->u = isect->u;
137 sd_vtx->v = isect->v;
148 sd_vtx->P = (1.f - isect->u - isect->v) *
verts[0] + isect->u *
verts[1] + isect->v *
verts[2];
157 kg, sd_vtx->object, sd_vtx->prim, sd_vtx->time,
verts, normals);
185 vtx->n =
normalize_len(normals[0] * (1.0f - sd_vtx->u - sd_vtx->v) + normals[1] * sd_vtx->u +
186 normals[2] * sd_vtx->v,
192 const float inv_n_len = 1.f / n_len;
193 float3 dn_du = inv_n_len * (normals[1] - normals[0]);
194 float3 dn_dv = inv_n_len * (normals[2] - normals[0]);
195 dn_du -= vtx->n *
dot(vtx->n, dn_du);
196 dn_dv -= vtx->n *
dot(vtx->n, dn_dv);
200 const float inv_len_dp_du = 1.f /
len(dp_du);
201 dp_du *= inv_len_dp_du;
202 dn_du *= inv_len_dp_du;
204 const float dpdu_dot_dpdv =
dot(dp_du, dp_dv);
205 dp_dv -= dpdu_dot_dpdv * dp_du;
206 dn_dv -= dpdu_dot_dpdv * dn_du;
208 const float inv_len_dp_dv = 1.f /
len(dp_dv);
209 dp_dv *= inv_len_dp_dv;
210 dn_dv *= inv_len_dp_dv;
227 vtx->n_offset = n_offset;
235 vtx->object = sd_vtx->object;
236 vtx->prim = sd_vtx->prim;
237 vtx->shader = sd_vtx->shader;
242# if defined(__KERNEL_METAL__)
249bool mnee_compute_constraint_derivatives(
253 const bool light_fixed_direction,
256 for (
int vi = 0; vi < vertex_count; vi++) {
260 float3 wi = (vi == 0) ? surface_sample_pos -
v.p : vertices[vi - 1].p -
v.p;
262 if (ili < MNEE_MIN_DISTANCE)
268 float3 wo = (vi == vertex_count - 1) ?
270 vertices[vi + 1].p -
v.p;
272 if (ilo < MNEE_MIN_DISTANCE)
279 if (
dot(wi,
v.ng) < .0f)
284 float ilh = 1.f /
len(
H);
291 float dp_du_dot_n =
dot(
v.dp_du,
v.n);
292 float3 s =
v.dp_du - dp_du_dot_n *
v.n;
293 float inv_len_s = 1.f /
len(s);
301 ccl_private ManifoldVertex &v_prev = vertices[vi - 1];
302 dH_du = (v_prev.dp_du - wi *
dot(wi, v_prev.dp_du)) * ili;
303 dH_dv = (v_prev.dp_dv - wi *
dot(wi, v_prev.dp_dv)) * ili;
304 dH_du -=
H *
dot(dH_du,
H);
305 dH_dv -=
H *
dot(dH_dv,
H);
313 if (vi == vertex_count - 1 && light_fixed_direction) {
314 dH_du = ili * (-
v.dp_du + wi *
dot(wi,
v.dp_du));
315 dH_dv = ili * (-
v.dp_dv + wi *
dot(wi,
v.dp_dv));
318 dH_du = -
v.dp_du * (ili + ilo) + wi * (
dot(wi,
v.dp_du) * ili) +
319 wo * (
dot(wo,
v.dp_du) * ilo);
320 dH_dv = -
v.dp_dv * (ili + ilo) + wi * (
dot(wi,
v.dp_dv) * ili) +
321 wo * (
dot(wo,
v.dp_dv) * ilo);
323 dH_du -=
H *
dot(dH_du,
H);
324 dH_dv -=
H *
dot(dH_dv,
H);
328 float3 ds_du = -inv_len_s * (
dot(
v.dp_du,
v.dn_du) *
v.n + dp_du_dot_n *
v.dn_du);
329 float3 ds_dv = -inv_len_s * (
dot(
v.dp_du,
v.dn_dv) *
v.n + dp_du_dot_n *
v.dn_dv);
330 ds_du -= s *
dot(s, ds_du);
331 ds_dv -= s *
dot(s, ds_dv);
338 dot(dH_dv, t) +
dot(
H, dt_dv));
341 if (vi < vertex_count - 1) {
342 ccl_private ManifoldVertex &v_next = vertices[vi + 1];
343 dH_du = (v_next.dp_du - wo *
dot(wo, v_next.dp_du)) * ilo;
344 dH_dv = (v_next.dp_dv - wo *
dot(wo, v_next.dp_dv)) * ilo;
345 dH_du -=
H *
dot(dH_du,
H);
346 dH_dv -=
H *
dot(dH_dv,
H);
369 float4 Li[MNEE_MAX_CAUSTIC_CASTERS];
370 float2 C[MNEE_MAX_CAUSTIC_CASTERS];
374 if (mat22_inverse(Lk, Li[0]) == 0.f)
377 C[0] = vertices[0].constraint;
379 for (
int k = 1; k < vertex_count; k++) {
380 float4 A = mat22_mult(vertices[k].a, Li[k - 1]);
382 Lk = vertices[k].b - mat22_mult(A, vertices[k - 1].c);
383 if (mat22_inverse(Lk, Li[k]) == 0.f)
386 C[k] = vertices[k].constraint - mat22_mult(A, C[k - 1]);
389 dx[vertex_count - 1] = mat22_mult(Li[vertex_count - 1], C[vertex_count - 1]);
390 for (
int k = vertex_count - 2; k > -1; k--)
391 dx[k] = mat22_mult(Li[k], C[k] - mat22_mult(vertices[k].c, dx[k + 1]));
401 const bool light_fixed_direction,
405 float2 dx[MNEE_MAX_CAUSTIC_CASTERS];
406 ManifoldVertex tentative[MNEE_MAX_CAUSTIC_CASTERS];
414 projection_ray.
tmin = 0.0f;
415 projection_ray.
time = sd->time;
424 bool reduce_stepsize =
false;
425 bool resolve_constraint =
true;
426 for (
int iteration = 0; iteration < MNEE_MAX_ITERATIONS; iteration++) {
427 if (resolve_constraint) {
429 if (!mnee_compute_constraint_derivatives(
430 vertex_count, vertices, sd->P, light_fixed_direction,
light_sample))
434 float constraint_norm = 0.f;
435 for (
int vi = 0; vi < vertex_count; vi++)
436 constraint_norm =
fmaxf(constraint_norm,
len(vertices[vi].constraint));
439 if (constraint_norm < MNEE_SOLVER_THRESHOLD)
443 if (!mnee_solve_matrix_h_to_x(vertex_count, vertices, dx))
448 for (
int vi = 0; vi < vertex_count; vi++) {
456 const float3 wo = tentative_p - sd->P;
457 if (
dot(sd->Ng, wo) <= 0.f) {
459 tentative_p =
mv.p +
beta * (dx[vi].
x *
mv.dp_du + dx[vi].
y *
mv.dp_dv);
468 projection_ray.
self.
prim = sd->prim;
469 projection_ray.
P = sd->P;
472 ccl_private const ManifoldVertex &pv = vertices[vi - 1];
475 projection_ray.
P = pv.p;
478 projection_ray.
tmax *= MNEE_PROJECTION_DISTANCE_MULTIPLIER;
480 bool projection_success =
false;
481 for (
int isect_count = 0; isect_count < MNEE_MAX_INTERSECTION_COUNT; isect_count++) {
486 if (projection_isect.
object ==
mv.object) {
487 projection_success =
true;
495 if (!projection_success) {
496 reduce_stepsize =
true;
507 mnee_setup_manifold_vertex(
508 kg, &tv,
mv.bsdf,
mv.eta,
mv.n_offset, &projection_ray, &projection_isect, sd_vtx);
512 const float distance =
len(tv.p -
mv.p);
513 if (distance < MNEE_MIN_PROGRESS_DISTANCE)
518 if (!reduce_stepsize) {
519 for (
int vi = 0; vi < vertex_count; vi++) {
523 const float3 wi = (vi == 0 ? sd->P : tentative[vi - 1].p) - tv.p;
525 const float3 wo = (vi == vertex_count - 1) ? light_fixed_direction ? ls->D : ls->
P - tv.p :
526 tentative[vi + 1].p - tv.p;
528 if (
dot(tv.n, wi) *
dot(tv.n, wo) >= 0.f) {
529 reduce_stepsize =
true;
535 if (reduce_stepsize) {
537 reduce_stepsize =
false;
538 resolve_constraint =
false;
542 if (
beta < MNEE_MINIMUM_STEP_SIZE)
549 for (
int vi = 0; vi < vertex_count; vi++)
550 vertices[vi] = tentative[vi];
553 resolve_constraint =
true;
562mnee_sample_bsdf_dh(
ClosureType type,
float alpha_x,
float alpha_y,
float sample_u,
float sample_v)
567 if (alpha_x == alpha_y) {
570 alpha2 = alpha_x * alpha_x;
577 float alpha_x2 = alpha_x * alpha_x;
578 float alpha_y2 = alpha_y * alpha_y;
579 alpha2 = 1.f / (cos_phi * cos_phi / alpha_x2 +
sin_phi *
sin_phi / alpha_y2);
583 float tan2_theta = alpha2;
585 tan2_theta *= -
logf(1.0f - sample_u);
588 tan2_theta *= sample_u / (1.0f - sample_u);
590 float cos2_theta = 1.0f / (1.0f + tan2_theta);
608 float cosNI =
dot(bsdf->N, wi);
609 float cosNO =
dot(bsdf->N, wo);
612 float cosHI =
dot(Ht, wi);
614 float alpha2 = bsdf->alpha_x * bsdf->alpha_y;
615 float cosThetaM =
dot(bsdf->N, Ht);
626 Spectrum reflectance, transmittance;
638 return bsdf->weight * transmittance *
G *
fabsf(cosHI / (cosNI *
sqr(cosThetaM)));
644 const bool light_fixed_direction,
652 float4 U[MNEE_MAX_CAUSTIC_CASTERS - 1];
655 float Lk_det = mat22_inverse(Lk, Li);
659 float det_dh_dx = Lk_det;
661 for (
int k = 1; k < vertex_count; k++) {
662 U[k - 1] = mat22_mult(Li, vertices[k - 1].c);
664 Lk = vertices[k].b - mat22_mult(vertices[k].a,
U[k - 1]);
665 Lk_det = mat22_inverse(Lk, Li);
675 int mi = vertex_count - 1;
676 ccl_private const ManifoldVertex &m = vertices[mi];
686 float3 wi = vertex_count == 1 ? sd->P - m.p : vertices[mi - 1].p - m.p;
687 float ili = 1.f /
len(wi);
692 if (
dot(wi, m.ng) < .0f)
698 if (light_fixed_direction) {
704 float ilh = 1.f /
len(
H);
707 float ilo = -eta * ilh;
711 float cos_phi =
dot(wo, s);
717 dH_dtheta -=
H *
dot(dH_dtheta,
H);
718 dH_dphi -=
H *
dot(dH_dphi,
H);
723 dot(dH_dtheta, s),
dot(dH_dphi, s),
dot(dH_dtheta, t),
dot(dH_dphi, t));
731 float ilo = 1.f /
len(wo);
736 float ilh = 1.f /
len(
H);
741 float3 dH_du = (dp_du - wo *
dot(wo, dp_du)) * ilo;
742 float3 dH_dv = (dp_dv - wo *
dot(wo, dp_dv)) * ilo;
743 dH_du -=
H *
dot(dH_du,
H);
744 dH_dv -=
H *
dot(dH_dv,
H);
755 float4 Tp = -mat22_mult(Li, dc_dlight);
756 for (
int k = vertex_count - 2; k > -1; k--)
757 Tp = -mat22_mult(
U[k], Tp);
759 *dx1_dxlight =
fabsf(mat22_determinant(Tp)) * dxn_dwn;
760 *dh_dx =
fabsf(det_dh_dx);
770 const bool light_fixed_direction,
784 kg, ls, vertices[vertex_count - 1].p, vertices[vertex_count - 1].n, path_flag);
815 if (!mnee_compute_transfer_matrix(
816 sd, ls, light_fixed_direction, vertex_count, vertices, &dx1_dxlight, &dh_dx))
820 const float dw0_dx1 =
fabsf(
dot(wo, vertices[0].n)) /
sqr(wo_len);
823 const float G =
fminf(dw0_dx1 * dx1_dxlight, 2.f);
833 probe_ray.
tmin = 0.0f;
836 probe_ray.
time = sd->time;
845 for (
int vi = 0; vi < vertex_count; vi++) {
855 if (hit_object !=
v.object ||
fabsf(probe_ray.
tmax - probe_isect.
t) > MNEE_MIN_DISTANCE)
892 wo = (vi == vertex_count - 1) ? (light_fixed_direction ? ls->D : ls->
P -
v.p) :
893 vertices[vi + 1].p -
v.p;
899 Spectrum bsdf_contribution = mnee_eval_bsdf_contribution(kg,
v.bsdf, wi, wo);
935 probe_ray.
tmin = 0.0f;
939 probe_ray.
tmax = ls->t;
943 probe_ray.
D = ls->P - probe_ray.
P;
948 probe_ray.
time = sd->time;
951 ManifoldVertex vertices[MNEE_MAX_CAUSTIC_CASTERS];
953 int vertex_count = 0;
954 for (
int isect_count = 0; isect_count < MNEE_MAX_INTERSECTION_COUNT; isect_count++) {
963 if (vertex_count >= MNEE_MAX_CAUSTIC_CASTERS)
986 bool found_refractive_microfacet_bsdf =
false;
987 for (
int ci = 0; ci < sd_mnee->num_closure; ci++) {
992 found_refractive_microfacet_bsdf =
true;
996 const float eta = (sd_mnee->flag &
SD_BACKFACING) ? 1.0f / microfacet_bsdf->
ior :
997 microfacet_bsdf->ior;
1000 if (microfacet_bsdf->alpha_x > 0.f && microfacet_bsdf->alpha_y > 0.f) {
1003 h = mnee_sample_bsdf_dh(bsdf->type,
1004 microfacet_bsdf->alpha_x,
1005 microfacet_bsdf->alpha_y,
1011 mnee_setup_manifold_vertex(kg, &
mv, bsdf, eta, h, &probe_ray, &probe_isect, sd_mnee);
1015 if (!found_refractive_microfacet_bsdf)
1027 if (vertex_count == 0)
1051 bool light_fixed_direction = (ls->t ==
FLT_MAX);
1054 if (klight->area.tan_half_spread == 0.0f) {
1056 light_fixed_direction =
true;
1062 if (mnee_newton_solver(kg, sd, sd_mnee, ls, light_fixed_direction, vertex_count, vertices)) {
1064 if (!mnee_path_contribution(
1065 kg,
state, sd, sd_mnee, ls, light_fixed_direction, vertex_count, vertices, throughput))
1068 return vertex_count;
MINLINE float safe_sqrtf(float a)
ATTR_WARN_UNUSED_RESULT const BMVert * v
ccl_device_inline float bsdf_G(float alpha2, float cos_N)
ccl_device_forceinline void microfacet_fresnel(KernelGlobals kg, ccl_private const 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)
SIMD_FORCE_INLINE btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
local_group_size(16, 16) .push_constant(Type b
additional_info("compositor_sum_squared_difference_float_shared") .push_constant(Type output_img float dot(value.rgb, luminance_coefficients)") .define("LOAD(value)"
static __attribute__((constructor)) void cpu_check()
ccl_device_forceinline int intersection_get_object_flags(KernelGlobals kg, ccl_private const Intersection *ccl_restrict isect)
ccl_device_forceinline float intersection_t_offset(const float t)
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, float time)
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define kernel_data_fetch(name, index)
#define ccl_device_forceinline
#define ccl_device_inline
#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, int prim, float3 P[3], float3 N[3])
ccl_device_intersect bool scene_intersect(KernelGlobals kg, ccl_private const Ray *ray, const uint visibility, ccl_private Intersection *isect)
ccl_device_inline Transform object_get_transform(KernelGlobals kg, ccl_private const 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)
#define CLOSURE_IS_GLASS(type)
#define CLOSURE_IS_REFRACTION(type)
@ 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, float value)
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 float cross(const float2 a, const float2 b)
CCL_NAMESPACE_BEGIN ccl_device_inline float4 zero_float4()
ccl_device_inline void motion_triangle_vertices_and_normals(KernelGlobals kg, int object, int prim, 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, float3 verts[3])
VecBase< float, 4 > float4
ccl_device_inline float2 path_state_rng_2D(KernelGlobals kg, ccl_private const 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, int shader, int object, int prim, float u, float v, float t, float time, bool object_space, int lamp)
CCL_NAMESPACE_BEGIN ccl_device void shader_setup_object_transforms(KernelGlobals kg, ccl_private ShaderData *ccl_restrict sd, float time)
ccl_device_inline void shader_setup_from_ray(KernelGlobals kg, ccl_private ShaderData *ccl_restrict sd, ccl_private const Ray *ccl_restrict ray, ccl_private const Intersection *ccl_restrict isect)
IntegratorStateCPU *ccl_restrict IntegratorState
#define INTEGRATOR_STATE_WRITE(state, nested_struct, member)
#define INTEGRATOR_STATE(state, nested_struct, member)
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, uint32_t path_flag, bool use_caustics_storage=false)
SPECTRUM_DATA_TYPE Spectrum
ccl_device_inline float sqr(float a)
ccl_device_inline float sin_from_cos(const float c)
ccl_device_inline float beta(float x, float y)
ccl_device_inline void make_orthonormals(const float3 N, ccl_private float3 *a, ccl_private float3 *b)