Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/kernel/closure/bsdf_microfacet.h
| Show All 40 Lines | |||||
| ccl_device_inline void microfacet_beckmann_sample_slopes(KernelGlobals kg, | ccl_device_inline void microfacet_beckmann_sample_slopes(KernelGlobals kg, | ||||
| const float cos_theta_i, | const float cos_theta_i, | ||||
| const float sin_theta_i, | const float sin_theta_i, | ||||
| float randu, | float randu, | ||||
| float randv, | float randv, | ||||
| ccl_private float *slope_x, | ccl_private float *slope_x, | ||||
| ccl_private float *slope_y, | ccl_private float *slope_y, | ||||
| ccl_private float *G1i) | ccl_private float *lambda_i) | ||||
| { | { | ||||
| /* Special case (normal incidence). */ | /* Special case (normal incidence). */ | ||||
| if (cos_theta_i >= 0.99999f) { | if (cos_theta_i >= 0.99999f) { | ||||
| const float r = sqrtf(-logf(randu)); | const float r = sqrtf(-logf(randu)); | ||||
| const float phi = M_2PI_F * randv; | const float phi = M_2PI_F * randv; | ||||
| *slope_x = r * cosf(phi); | *slope_x = r * cosf(phi); | ||||
| *slope_y = r * sinf(phi); | *slope_y = r * sinf(phi); | ||||
| *G1i = 1.0f; | *lambda_i = 0.0f; | ||||
| return; | return; | ||||
| } | } | ||||
| /* Precomputations. */ | /* Precomputations. */ | ||||
| const float tan_theta_i = sin_theta_i / cos_theta_i; | const float tan_theta_i = sin_theta_i / cos_theta_i; | ||||
| const float inv_a = tan_theta_i; | const float inv_a = tan_theta_i; | ||||
| const float cot_theta_i = 1.0f / tan_theta_i; | const float cot_theta_i = 1.0f / tan_theta_i; | ||||
| const float erf_a = fast_erff(cot_theta_i); | const float erf_a = fast_erff(cot_theta_i); | ||||
| const float exp_a2 = expf(-cot_theta_i * cot_theta_i); | const float exp_a2 = expf(-cot_theta_i * cot_theta_i); | ||||
| const float SQRT_PI_INV = 0.56418958354f; | const float SQRT_PI_INV = 0.56418958354f; | ||||
| const float Lambda = 0.5f * (erf_a - 1.0f) + (0.5f * SQRT_PI_INV) * (exp_a2 * inv_a); | const float Lambda = 0.5f * (erf_a - 1.0f) + (0.5f * SQRT_PI_INV) * (exp_a2 * inv_a); | ||||
| const float G1 = 1.0f / (1.0f + Lambda); /* masking */ | |||||
| *G1i = G1; | *lambda_i = Lambda; | ||||
| /* Based on paper from Wenzel Jakob | /* Based on paper from Wenzel Jakob | ||||
| * An Improved Visible Normal Sampling Routine for the Beckmann Distribution | * An Improved Visible Normal Sampling Routine for the Beckmann Distribution | ||||
| * | * | ||||
| * http://www.mitsuba-renderer.org/~wenzel/files/visnormal.pdf | * http://www.mitsuba-renderer.org/~wenzel/files/visnormal.pdf | ||||
| * | * | ||||
| * Reformulation from OpenShadingLanguage which avoids using inverse | * Reformulation from OpenShadingLanguage which avoids using inverse | ||||
| * trigonometric functions. | * trigonometric functions. | ||||
| ▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | |||||
| */ | */ | ||||
| ccl_device_inline void microfacet_ggx_sample_slopes(const float cos_theta_i, | ccl_device_inline void microfacet_ggx_sample_slopes(const float cos_theta_i, | ||||
| const float sin_theta_i, | const float sin_theta_i, | ||||
| float randu, | float randu, | ||||
| float randv, | float randv, | ||||
| ccl_private float *slope_x, | ccl_private float *slope_x, | ||||
| ccl_private float *slope_y, | ccl_private float *slope_y, | ||||
| ccl_private float *G1i) | ccl_private float *lambda_i) | ||||
| { | { | ||||
| /* Special case (normal incidence). */ | /* Special case (normal incidence). */ | ||||
| if (cos_theta_i >= 0.99999f) { | if (cos_theta_i >= 0.99999f) { | ||||
| const float r = sqrtf(randu / (1.0f - randu)); | const float r = sqrtf(randu / (1.0f - randu)); | ||||
| const float phi = M_2PI_F * randv; | const float phi = M_2PI_F * randv; | ||||
| *slope_x = r * cosf(phi); | *slope_x = r * cosf(phi); | ||||
| *slope_y = r * sinf(phi); | *slope_y = r * sinf(phi); | ||||
| *G1i = 1.0f; | *lambda_i = 0.0f; | ||||
| return; | return; | ||||
| } | } | ||||
| /* Precomputations. */ | /* Precomputations. */ | ||||
| const float tan_theta_i = sin_theta_i / cos_theta_i; | const float tan_theta_i = sin_theta_i / cos_theta_i; | ||||
| const float G1_inv = 0.5f * (1.0f + safe_sqrtf(1.0f + tan_theta_i * tan_theta_i)); | const float G1_inv = 0.5f * (1.0f + safe_sqrtf(1.0f + tan_theta_i * tan_theta_i)); | ||||
| *G1i = 1.0f / G1_inv; | *lambda_i = G1_inv - 1.0f; | ||||
| /* Sample slope_x. */ | /* Sample slope_x. */ | ||||
| const float A = 2.0f * randu * G1_inv - 1.0f; | const float A = 2.0f * randu * G1_inv - 1.0f; | ||||
| const float AA = A * A; | const float AA = A * A; | ||||
| const float tmp = 1.0f / (AA - 1.0f); | const float tmp = 1.0f / (AA - 1.0f); | ||||
| const float B = tan_theta_i; | const float B = tan_theta_i; | ||||
| const float BB = B * B; | const float BB = B * B; | ||||
| const float D = safe_sqrtf(BB * (tmp * tmp) - (AA - BB) * tmp); | const float D = safe_sqrtf(BB * (tmp * tmp) - (AA - BB) * tmp); | ||||
| Show All 20 Lines | |||||
| template<MicrofacetType m_type> | template<MicrofacetType m_type> | ||||
| ccl_device_forceinline float3 microfacet_sample_stretched(KernelGlobals kg, | ccl_device_forceinline float3 microfacet_sample_stretched(KernelGlobals kg, | ||||
| const float3 wi, | const float3 wi, | ||||
| const float alpha_x, | const float alpha_x, | ||||
| const float alpha_y, | const float alpha_y, | ||||
| const float randu, | const float randu, | ||||
| const float randv, | const float randv, | ||||
| ccl_private float *G1i) | ccl_private float *lambda_i) | ||||
| { | { | ||||
| /* 1. stretch wi */ | /* 1. stretch wi */ | ||||
| float3 wi_ = make_float3(alpha_x * wi.x, alpha_y * wi.y, wi.z); | float3 wi_ = make_float3(alpha_x * wi.x, alpha_y * wi.y, wi.z); | ||||
| wi_ = normalize(wi_); | wi_ = normalize(wi_); | ||||
| /* Compute polar coordinates of wi_. */ | /* Compute polar coordinates of wi_. */ | ||||
| float costheta_ = 1.0f; | float costheta_ = 1.0f; | ||||
| float sintheta_ = 0.0f; | float sintheta_ = 0.0f; | ||||
| Show All 9 Lines | if (wi_.z < 0.99999f) { | ||||
| sinphi_ = wi_.y * invlen; | sinphi_ = wi_.y * invlen; | ||||
| } | } | ||||
| /* 2. sample P22_{wi}(x_slope, y_slope, 1, 1) */ | /* 2. sample P22_{wi}(x_slope, y_slope, 1, 1) */ | ||||
| float slope_x, slope_y; | float slope_x, slope_y; | ||||
| if (m_type == MicrofacetType::BECKMANN) { | if (m_type == MicrofacetType::BECKMANN) { | ||||
| microfacet_beckmann_sample_slopes( | microfacet_beckmann_sample_slopes( | ||||
| kg, costheta_, sintheta_, randu, randv, &slope_x, &slope_y, G1i); | kg, costheta_, sintheta_, randu, randv, &slope_x, &slope_y, lambda_i); | ||||
| } | } | ||||
| else { | else { | ||||
| microfacet_ggx_sample_slopes(costheta_, sintheta_, randu, randv, &slope_x, &slope_y, G1i); | microfacet_ggx_sample_slopes(costheta_, sintheta_, randu, randv, &slope_x, &slope_y, lambda_i); | ||||
| } | } | ||||
| /* 3. rotate */ | /* 3. rotate */ | ||||
| float tmp = cosphi_ * slope_x - sinphi_ * slope_y; | float tmp = cosphi_ * slope_x - sinphi_ * slope_y; | ||||
| slope_y = sinphi_ * slope_x + cosphi_ * slope_y; | slope_y = sinphi_ * slope_x + cosphi_ * slope_y; | ||||
| slope_x = tmp; | slope_x = tmp; | ||||
| /* 4. unstretch */ | /* 4. unstretch */ | ||||
| Show All 39 Lines | ccl_device_forceinline float bsdf_clearcoat_D(float alpha2, float cos_NH) | ||||
| if (alpha2 >= 1.0f) { | if (alpha2 >= 1.0f) { | ||||
| return M_1_PI_F; | return M_1_PI_F; | ||||
| } | } | ||||
| const float t = 1.0f + (alpha2 - 1.0f) * cos_NH * cos_NH; | const float t = 1.0f + (alpha2 - 1.0f) * cos_NH * cos_NH; | ||||
| return (alpha2 - 1.0f) / (M_PI_F * logf(alpha2) * t); | return (alpha2 - 1.0f) / (M_PI_F * logf(alpha2) * t); | ||||
| } | } | ||||
| /* Monodirectional shadowing-masking term. */ | /* Smith shadowing-masking term, here in the non-separable form. | ||||
| * For details, see: | |||||
| * Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs. | |||||
| * Eric Heitz, JCGT Vol. 3, No. 2, 2014. | |||||
| * https://jcgt.org/published/0003/02/03/ */ | |||||
| template<MicrofacetType m_type> | template<MicrofacetType m_type> | ||||
| ccl_device_inline float bsdf_G1_from_sqr_alpha_tan_n(float sqr_alpha_tan_n) | ccl_device_inline float bsdf_lambda_from_sqr_alpha_tan_n(float sqr_alpha_tan_n) | ||||
| { | { | ||||
| if (m_type == MicrofacetType::GGX) { | if (m_type == MicrofacetType::GGX) { | ||||
| return 2.0f / (1.0f + sqrtf(1.0f + sqr_alpha_tan_n)); | /* Equation 72. */ | ||||
| return 0.5f * (sqrtf(1.0f + sqr_alpha_tan_n) - 1.0f); | |||||
| } | } | ||||
| else { | else { | ||||
| /* m_type == MicrofacetType::BECKMANN */ | /* m_type == MicrofacetType::BECKMANN | ||||
| * Approximation from below Equation 69. */ | |||||
| if (sqr_alpha_tan_n < 0.39f) { | |||||
| /* Equivalent to a >= 1.6f, but also handles sqr_alpha_tan_n == 0.0f cleanly. */ | |||||
| return 0.0f; | |||||
| } | |||||
| const float a = inversesqrtf(sqr_alpha_tan_n); | const float a = inversesqrtf(sqr_alpha_tan_n); | ||||
| return (a > 1.6f) ? 1.0f : ((2.181f * a + 3.535f) * a) / ((2.577f * a + 2.276f) * a + 1.0f); | return ((0.396f * a - 1.259f) * a + 1.0f) / ((2.181f * a + 3.535f) * a); | ||||
| } | } | ||||
| } | } | ||||
| template<MicrofacetType m_type> ccl_device_inline float bsdf_G1(float alpha2, float cos_N) | template<MicrofacetType m_type> ccl_device_inline float bsdf_lambda(float alpha2, float cos_N) | ||||
| { | { | ||||
| return bsdf_G1_from_sqr_alpha_tan_n<m_type>(alpha2 * fmaxf(1.0f / (cos_N * cos_N) - 1.0f, 0.0f)); | return bsdf_lambda_from_sqr_alpha_tan_n<m_type>(alpha2 * fmaxf(1.0f / sqr(cos_N) - 1.0f, 0.0f)); | ||||
| } | } | ||||
| template<MicrofacetType m_type> | template<MicrofacetType m_type> | ||||
| ccl_device_inline float bsdf_aniso_G1(float alpha_x, float alpha_y, float3 V) | ccl_device_inline float bsdf_aniso_lambda(float alpha_x, float alpha_y, float3 V) | ||||
| { | { | ||||
| return bsdf_G1_from_sqr_alpha_tan_n<m_type>((sqr(alpha_x * V.x) + sqr(alpha_y * V.y)) / | const float sqr_alpha_tan_n = (sqr(alpha_x * V.x) + sqr(alpha_y * V.y)) / sqr(V.z); | ||||
| sqr(V.z)); | return bsdf_lambda_from_sqr_alpha_tan_n<m_type>(sqr_alpha_tan_n); | ||||
| } | } | ||||
| /* Smith's separable shadowing-masking term. */ | /* Combined shadowing-masking term. */ | ||||
| template<MicrofacetType m_type> | template<MicrofacetType m_type> | ||||
| ccl_device_inline float bsdf_G(float alpha2, float cos_NI, float cos_NO) | ccl_device_inline float bsdf_G(float alpha2, float cos_NI, float cos_NO) | ||||
| { | { | ||||
| return bsdf_G1<m_type>(alpha2, cos_NI) * bsdf_G1<m_type>(alpha2, cos_NO); | return 1.0f / (1.0f + bsdf_lambda<m_type>(alpha2, cos_NI) + bsdf_lambda<m_type>(alpha2, cos_NO)); | ||||
| } | } | ||||
| /* Normal distribution function. */ | /* Normal distribution function. */ | ||||
| template<MicrofacetType m_type> ccl_device_inline float bsdf_D(float alpha2, float cos_NH) | template<MicrofacetType m_type> ccl_device_inline float bsdf_D(float alpha2, float cos_NH) | ||||
| { | { | ||||
| const float cos_NH2 = sqr(cos_NH); | const float cos_NH2 = sqr(cos_NH); | ||||
| if (m_type == MicrofacetType::BECKMANN) { | if (m_type == MicrofacetType::BECKMANN) { | ||||
| ▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | ccl_device Spectrum bsdf_microfacet_eval(ccl_private const ShaderClosure *sc, | ||||
| } | } | ||||
| /* Compute half vector. */ | /* Compute half vector. */ | ||||
| float3 H = m_refractive ? -(bsdf->ior * wo + wi) : (wi + wo); | float3 H = m_refractive ? -(bsdf->ior * wo + wi) : (wi + wo); | ||||
| const float inv_len_H = 1.0f / len(H); | const float inv_len_H = 1.0f / len(H); | ||||
| H *= inv_len_H; | H *= inv_len_H; | ||||
| const float cos_NH = dot(N, H); | const float cos_NH = dot(N, H); | ||||
| float D, G1i, G1o; | float D, lambdaI, lambdaO; | ||||
| /* TODO: add support for anisotropic transmission. */ | /* TODO: add support for anisotropic transmission. */ | ||||
| if (alpha_x == alpha_y || m_refractive) { /* Isotropic. */ | if (alpha_x == alpha_y || m_refractive) { /* Isotropic. */ | ||||
| float alpha2 = alpha_x * alpha_y; | float alpha2 = alpha_x * alpha_y; | ||||
| if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) { | if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) { | ||||
| D = bsdf_clearcoat_D(alpha2, cos_NH); | D = bsdf_clearcoat_D(alpha2, cos_NH); | ||||
| /* The masking-shadowing term for clearcoat has a fixed alpha of 0.25 | /* The masking-shadowing term for clearcoat has a fixed alpha of 0.25 | ||||
| * => alpha2 = 0.25 * 0.25 */ | * => alpha2 = 0.25 * 0.25 */ | ||||
| alpha2 = 0.0625f; | alpha2 = 0.0625f; | ||||
| } | } | ||||
| else { | else { | ||||
| D = bsdf_D<m_type>(alpha2, cos_NH); | D = bsdf_D<m_type>(alpha2, cos_NH); | ||||
| } | } | ||||
| G1i = bsdf_G1<m_type>(alpha2, cos_NI); | lambdaI = bsdf_lambda<m_type>(alpha2, cos_NI); | ||||
| G1o = bsdf_G1<m_type>(alpha2, cos_NO); | lambdaO = bsdf_lambda<m_type>(alpha2, cos_NO); | ||||
| } | } | ||||
| else { /* Anisotropic. */ | else { /* Anisotropic. */ | ||||
| float3 X, Y; | float3 X, Y; | ||||
| make_orthonormals_tangent(N, bsdf->T, &X, &Y); | make_orthonormals_tangent(N, bsdf->T, &X, &Y); | ||||
| const float3 local_H = make_float3(dot(X, H), dot(Y, H), cos_NH); | const float3 local_H = make_float3(dot(X, H), dot(Y, H), cos_NH); | ||||
| const float3 local_I = make_float3(dot(X, wi), dot(Y, wi), cos_NI); | const float3 local_I = make_float3(dot(X, wi), dot(Y, wi), cos_NI); | ||||
| const float3 local_O = make_float3(dot(X, wo), dot(Y, wo), cos_NO); | const float3 local_O = make_float3(dot(X, wo), dot(Y, wo), cos_NO); | ||||
| D = bsdf_aniso_D<m_type>(alpha_x, alpha_y, local_H); | D = bsdf_aniso_D<m_type>(alpha_x, alpha_y, local_H); | ||||
| G1i = bsdf_aniso_G1<m_type>(alpha_x, alpha_y, local_I); | lambdaI = bsdf_aniso_lambda<m_type>(alpha_x, alpha_y, local_I); | ||||
| G1o = bsdf_aniso_G1<m_type>(alpha_x, alpha_y, local_O); | lambdaO = bsdf_aniso_lambda<m_type>(alpha_x, alpha_y, local_O); | ||||
| } | } | ||||
| const float common = G1i * D / cos_NI * | const float common = D / cos_NI * | ||||
| (m_refractive ? | (m_refractive ? | ||||
| sqr(bsdf->ior * inv_len_H) * fabsf(dot(H, wi) * dot(H, wo)) : | sqr(bsdf->ior * inv_len_H) * fabsf(dot(H, wi) * dot(H, wo)) : | ||||
| 0.25f); | 0.25f); | ||||
| *pdf = common; | *pdf = common / (1.0f + lambdaI); | ||||
| const Spectrum F = m_refractive ? one_spectrum() : reflection_color(bsdf, wo, H); | const Spectrum F = m_refractive ? one_spectrum() : reflection_color(bsdf, wo, H); | ||||
| return F * G1o * common; | return F * common / (1.0f + lambdaO + lambdaI); | ||||
| } | } | ||||
| template<MicrofacetType m_type> | template<MicrofacetType m_type> | ||||
| ccl_device int bsdf_microfacet_sample(KernelGlobals kg, | ccl_device int bsdf_microfacet_sample(KernelGlobals kg, | ||||
| ccl_private const ShaderClosure *sc, | ccl_private const ShaderClosure *sc, | ||||
| float3 Ng, | float3 Ng, | ||||
| float3 wi, | float3 wi, | ||||
| float randu, | float randu, | ||||
| Show All 24 Lines | if (alpha_x == alpha_y) { | ||||
| make_orthonormals(N, &X, &Y); | make_orthonormals(N, &X, &Y); | ||||
| } | } | ||||
| else { | else { | ||||
| make_orthonormals_tangent(N, bsdf->T, &X, &Y); | make_orthonormals_tangent(N, bsdf->T, &X, &Y); | ||||
| } | } | ||||
| /* Importance sampling with distribution of visible normals. Vectors are transformed to local | /* Importance sampling with distribution of visible normals. Vectors are transformed to local | ||||
| * space before and after sampling. */ | * space before and after sampling. */ | ||||
| float G1i; | float lambdaI; | ||||
| const float3 local_I = make_float3(dot(X, wi), dot(Y, wi), cos_NI); | const float3 local_I = make_float3(dot(X, wi), dot(Y, wi), cos_NI); | ||||
| const float3 local_H = microfacet_sample_stretched<m_type>( | const float3 local_H = microfacet_sample_stretched<m_type>( | ||||
| kg, local_I, alpha_x, alpha_y, randu, randv, &G1i); | kg, local_I, alpha_x, alpha_y, randu, randv, &lambdaI); | ||||
| const float3 H = X * local_H.x + Y * local_H.y + N * local_H.z; | const float3 H = X * local_H.x + Y * local_H.y + N * local_H.z; | ||||
| const float cos_NH = local_H.z; | const float cos_NH = local_H.z; | ||||
| const float cos_HI = dot(H, wi); | const float cos_HI = dot(H, wi); | ||||
| bool valid = false; | bool valid = false; | ||||
| if (m_refractive) { | if (m_refractive) { | ||||
| float3 R, T; | float3 R, T; | ||||
| Show All 28 Lines | if (alpha_x * alpha_y <= 1e-7f || (m_refractive && fabsf(m_eta - 1.0f) < 1e-4f)) { | ||||
| if (use_fresnel && !m_refractive) { | if (use_fresnel && !m_refractive) { | ||||
| *eval *= reflection_color(bsdf, *wo, H); | *eval *= reflection_color(bsdf, *wo, H); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| label |= LABEL_GLOSSY; | label |= LABEL_GLOSSY; | ||||
| float cos_NO = dot(N, *wo); | float cos_NO = dot(N, *wo); | ||||
| float D, G1o; | float D, lambdaO; | ||||
| /* TODO: add support for anisotropic transmission. */ | /* TODO: add support for anisotropic transmission. */ | ||||
| if (alpha_x == alpha_y || m_refractive) { /* Isotropic. */ | if (alpha_x == alpha_y || m_refractive) { /* Isotropic. */ | ||||
| float alpha2 = alpha_x * alpha_y; | float alpha2 = alpha_x * alpha_y; | ||||
| if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) { | if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) { | ||||
| D = bsdf_clearcoat_D(alpha2, cos_NH); | D = bsdf_clearcoat_D(alpha2, cos_NH); | ||||
| /* The masking-shadowing term for clearcoat has a fixed alpha of 0.25 | /* The masking-shadowing term for clearcoat has a fixed alpha of 0.25 | ||||
| * => alpha2 = 0.25 * 0.25 */ | * => alpha2 = 0.25 * 0.25 */ | ||||
| alpha2 = 0.0625f; | alpha2 = 0.0625f; | ||||
| /* Recalculate G1i. */ | /* Recalculate lambdaI. */ | ||||
| G1i = bsdf_G1<m_type>(alpha2, cos_NI); | lambdaI = bsdf_lambda<m_type>(alpha2, cos_NI); | ||||
| } | } | ||||
| else { | else { | ||||
| D = bsdf_D<m_type>(alpha2, cos_NH); | D = bsdf_D<m_type>(alpha2, cos_NH); | ||||
| } | } | ||||
| G1o = bsdf_G1<m_type>(alpha2, cos_NO); | lambdaO = bsdf_lambda<m_type>(alpha2, cos_NO); | ||||
| } | } | ||||
| else { /* Anisotropic. */ | else { /* Anisotropic. */ | ||||
| const float3 local_O = make_float3(dot(X, *wo), dot(Y, *wo), cos_NO); | const float3 local_O = make_float3(dot(X, *wo), dot(Y, *wo), cos_NO); | ||||
| D = bsdf_aniso_D<m_type>(alpha_x, alpha_y, local_H); | D = bsdf_aniso_D<m_type>(alpha_x, alpha_y, local_H); | ||||
| G1o = bsdf_aniso_G1<m_type>(alpha_x, alpha_y, local_O); | lambdaO = bsdf_aniso_lambda<m_type>(alpha_x, alpha_y, local_O); | ||||
| } | } | ||||
| const float cos_HO = dot(H, *wo); | const float cos_HO = dot(H, *wo); | ||||
| const float common = G1i * D / cos_NI * | const float common = D / cos_NI * | ||||
| (m_refractive ? fabsf(cos_HI * cos_HO) / sqr(cos_HO + cos_HI / m_eta) : | (m_refractive ? fabsf(cos_HI * cos_HO) / sqr(cos_HO + cos_HI / m_eta) : | ||||
| 0.25f); | 0.25f); | ||||
| *pdf = common; | *pdf = common / (1.0f + lambdaI); | ||||
| Spectrum F = m_refractive ? one_spectrum() : reflection_color(bsdf, *wo, H); | Spectrum F = m_refractive ? one_spectrum() : reflection_color(bsdf, *wo, H); | ||||
| *eval = G1o * common * F; | *eval = F * common / (1.0f + lambdaI + lambdaO); | ||||
| } | } | ||||
| *sampled_roughness = make_float2(alpha_x, alpha_y); | *sampled_roughness = make_float2(alpha_x, alpha_y); | ||||
| *eta = m_refractive ? 1.0f / m_eta : m_eta; | *eta = m_refractive ? 1.0f / m_eta : m_eta; | ||||
| return label; | return label; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 173 Lines • Show Last 20 Lines | |||||