30 const T im = this->re * other.im + this->im * other.re;
31 this->re = this->re * other.re - this->im * other.im;
38 return complex<T>{this->re * other, this->im * other};
55 const float eta_cos_theta_t_sq =
sqr(eta) - (1.0f -
sqr(cos_theta_i));
56 if (eta_cos_theta_t_sq <= 0) {
72 cos_theta_i =
fabsf(cos_theta_i);
74 const float cos_theta_t = -
safe_sqrtf(eta_cos_theta_t_sq) / eta;
77 *r_cos_theta_t = cos_theta_t;
81 const float r_s = (cos_theta_i + eta * cos_theta_t) / (cos_theta_i - eta * cos_theta_t);
82 const float r_p = (cos_theta_t + eta * cos_theta_i) / (eta * cos_theta_i - cos_theta_t);
85 *r_cos_phi =
make_float2(2 * (r_s >= 0.0f) - 1, 2 * (r_p >= 0.0f) - 1);
104 const float cos_theta_t,
107 return (inv_eta *
dot(normal, incident) + cos_theta_t) * normal - inv_eta * incident;
114 const float c =
fabsf(cosi);
115 float g = eta * eta - 1 + c * c;
118 const float A = (g - c) / (g + c);
119 const float B = (c * (g + c) - 1) / (c * (g - c) + 1);
120 return 0.5f *
A *
A * (1 +
B *
B);
133 return 0.997118f + eta * (0.1014f - eta * (0.965241f + eta * 0.130607f));
135 return (eta - 1.0f) / (4.08567f + 1.00071f * eta);
145 const float ambient_ior,
152 const float eta1 = ambient_ior;
156 const float eta1_sq =
sqr(eta1);
159 const Spectrum two_eta2_k2 = 2.0f * eta2 * k2;
161 const Spectrum t1 = eta2_sq - k2_sq - eta1_sq * (1.0f -
sqr(cosi));
169 if (r_R_s && r_R_p) {
172 const Spectrum t3 = (eta2_sq - k2_sq) * cosi;
173 const Spectrum t4 = two_eta2_k2 * cosi;
175 sqr(t3 + eta1 * u) +
sqr(t4 + eta1 *
v));
178 if (r_phasor_s && r_phasor_p) {
179 const Spectrum re_s = -u_sq - v_sq +
sqr(eta1 * cosi);
180 const Spectrum im_s = -2.0f * eta1 * cosi *
v;
185 const Spectrum re_p =
sqr((eta2_sq + k2_sq) * cosi) - eta1_sq * (u_sq + v_sq);
186 const Spectrum im_p = 2.0f * eta1 * cosi * (two_eta2_k2 * u - (eta2_sq - k2_sq) *
v);
198 return (R_s + R_p) * 0.5f;
216 const float f = 6.0f / 7.0f;
217 const float f5 =
sqr(
sqr(f)) * f;
219 return F_schlick * (7.0f / (f5 * f)) * (
one_spectrum() - tint);
225 const float f = 6.0f / 7.0f;
226 const float f5 =
sqr(
sqr(f)) * f;
228 return (7.0f / (f5 * f)) * (F_schlick - F82);
235 const float s5 =
sqr(
sqr(s)) * s;
237 return saturate(F_schlick -
B * cosi * s5 * s);
252 const float sqrt_f0 =
sqrtf(
clamp(f0, 0.0f, 0.99f));
253 return (1.0f + sqrt_f0) / (1.0f - sqrt_f0);
258 return sqr((ior - 1.0f) / (ior + 1.0f));
263 const float m =
clamp(1.0f - u, 0.0f, 1.0f);
264 const float m2 = m * m;
292 const float Iz =
dot(
I, Ng);
296 const float threshold =
min(0.9f * Iz, 0.01f);
297 if (
dot(Ng,
R) >= threshold) {
345 const float Ix =
dot(
I,
X);
347 const float a =
sqr(Ix) +
sqr(Iz);
348 const float b = 2.0f * (a + Iz * threshold);
349 const float c =
sqr(threshold + Iz);
354 const float Nz2 = (Ix < 0) ? 0.25f * (
b +
safe_sqrtf(
sqr(
b) - 4.0f * a * c)) / a :
360 return Nx *
X + Nz * Ng;
379 const float azimuthal_roughness)
381 const float x = azimuthal_roughness;
382 return (((((0.245f *
x) + 5.574f) *
x - 10.73f) *
x + 2.532f) *
x - 0.215f) *
x + 5.969f;
390 return sigma * sigma;
394 const float pheomelanin)
441template<
typename SpectrumOrFloat>
444 const SpectrumOrFloat R23,
448 const float T121 = 1.0f - R12;
450 const SpectrumOrFloat R123 = R12 * R23;
451 const SpectrumOrFloat r123 =
sqrt(R123);
452 const SpectrumOrFloat Rs =
sqr(T121) * R23 / (1.0f - R123);
460 SpectrumOrFloat Cm = (Rs - T121);
463 for (
int m = 1; m < 4; m++) {
466 R += Cm * 2.0f * (accumulator.
re * S.re + accumulator.
im * S.im);
467 accumulator *= phasor;
483template<
typename SpectrumOrFloat>
485 const float ambient_ior,
489 const float cos_theta_1,
494 float film_ior = thin_film.
ior;
505 cos_theta_1, film_ior / ambient_ior, &cos_theta_2, &phasor12_real);
512 SpectrumOrFloat R23_s, R23_p;
516 if (F82 !=
nullptr) {
520 const Spectrum n = substrate_ior.
re / film_ior;
522 const Spectrum F0 = (
sqr(n - 1.0f) + k_sq) / (
sqr(n + 1.0f) + k_sq);
527 -cos_theta_2, film_ior, substrate_ior,
nullptr,
nullptr, &phasor23_s, &phasor23_p);
531 -cos_theta_2, film_ior, substrate_ior, &R23_s, &R23_p, &phasor23_s, &phasor23_p);
538 -cos_theta_2, substrate_ior.
re / film_ior, r_cos_theta_3, &phasor23_real);
548 phasor23_s = {phasor23_real.
x, 0.0f};
549 phasor23_p = {phasor23_real.
y, 0.0f};
553 const float OPD = -2.0f * film_ior * thin_film.
thickness * cos_theta_2;
MINLINE float safe_sqrtf(float a)
MINLINE float safe_divide(float a, float b)
ATTR_WARN_UNUSED_RESULT const BMVert * v
ccl_device void fresnel_conductor_polarized(const float cosi, const float ambient_ior, const complex< Spectrum > conductor_ior, ccl_private Spectrum *r_R_s, ccl_private Spectrum *r_R_p, ccl_private complex< Spectrum > *r_phasor_s, ccl_private complex< Spectrum > *r_phasor_p)
ccl_device Spectrum fresnel_conductor(const float cosi, const complex< Spectrum > ior)
ccl_device Spectrum fresnel_iridescence(KernelGlobals kg, const float ambient_ior, const FresnelThinFilm thin_film, const complex< SpectrumOrFloat > substrate_ior, ccl_private const Spectrum *F82, const float cos_theta_1, ccl_private float *r_cos_theta_3)
ccl_device_inline complex< Spectrum > iridescence_lookup_sensitivity(KernelGlobals kg, const float OPD)
ccl_device_inline Spectrum fresnel_conductor_Fss(const complex< Spectrum > ior)
ccl_device float3 maybe_ensure_valid_specular_reflection(ccl_private ShaderData *sd, const float3 N)
ccl_device float ior_from_F0(const float f0)
ccl_device float fresnel_dielectric_cos(const float cosi, const float eta)
ccl_device float schlick_fresnel(const float u)
ccl_device float F0_from_ior(const float ior)
ccl_device_inline Spectrum bsdf_principled_hair_sigma_from_reflectance(const Spectrum color, const float azimuthal_roughness)
ccl_device float2 fresnel_dielectric_polarized(float cos_theta_i, const float eta, ccl_private float *r_cos_theta_t, ccl_private float2 *r_cos_phi)
ccl_device_inline float bsdf_principled_hair_albedo_roughness_scale(const float azimuthal_roughness)
ccl_device_inline Spectrum fresnel_f82_B(const Spectrum F0, const Spectrum F82)
ccl_device_inline Spectrum fresnel_f82_Fss(const Spectrum F0, const Spectrum B)
ccl_device_inline float fresnel_dielectric_Fss(const float eta)
ccl_device_forceinline float fresnel_dielectric(const float cos_theta_i, const float eta, ccl_private float *r_cos_theta_t)
ccl_device_inline float3 iridescence_airy_summation(KernelGlobals kg, const float R12, const SpectrumOrFloat R23, const float OPD, const complex< SpectrumOrFloat > phasor)
ccl_device float3 ensure_valid_specular_reflection(const float3 Ng, const float3 I, float3 N)
ccl_device_inline Spectrum bsdf_principled_hair_sigma_from_concentration(const float eumelanin, const float pheomelanin)
ccl_device_inline float3 refract_angle(const float3 incident, const float3 normal, const float cos_theta_t, const float inv_eta)
ccl_device_inline Spectrum fresnel_f82(const float cosi, const Spectrum F0, const Spectrum B)
ccl_device_forceinline Spectrum interpolate_fresnel_color(const float3 L, const float3 H, const float ior, Spectrum F0)
ccl_device_inline Spectrum closure_layering_weight(const Spectrum layer_albedo, const Spectrum weight)
ccl_device_inline Spectrum fresnel_f82tint_B(const Spectrum F0, const Spectrum tint)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
ccl_device_inline Spectrum safe_divide_color(Spectrum a, Spectrum b, const float fallback=0.0f)
reduce_max(value.rgb)") DEFINE_VALUE("REDUCE(lhs
dot(value.rgb, luminance_coefficients)") DEFINE_VALUE("REDUCE(lhs
#define kernel_assert(cond)
#define ccl_device_forceinline
const ThreadKernelGlobalsCPU * KernelGlobals
#define ccl_device_inline
#define THIN_FILM_TABLE_SIZE
#define ccl_static_constexpr
#define ccl_device_inline_method
#define CCL_NAMESPACE_END
constexpr T clamp(T, U, U) RET
@ SD_USE_BUMP_MAP_CORRECTION
ccl_device_inline Spectrum rgb_to_spectrum(const float3 rgb)
CCL_NAMESPACE_BEGIN ccl_device float lookup_table_read(KernelGlobals kg, float x, const int offset, const int size)
ccl_device_inline bool isnan_safe(const float f)
ccl_device_inline float inverse_lerp(const float a, const float b, const float x)
MINLINE float smoothstep(float edge0, float edge1, float x)
ccl_device_inline float2 one_float2()
ccl_device_inline bool isequal(const float2 a, const float2 b)
ccl_device_inline float3 safe_normalize_fallback(const float3 a, const float3 fallback)
ccl_device_inline auto is_zero_mask(const float3 a)
ccl_device_inline_method complex< T > operator*(ccl_private const float &other)
ccl_device_inline_method complex< T > operator*=(ccl_private const complex< T > &other)
ccl_static_constexpr bool conductive
ccl_static_constexpr bool conductive