Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/kernel/closure/bsdf_microfacet.h')
-rw-r--r--intern/cycles/kernel/closure/bsdf_microfacet.h379
1 files changed, 197 insertions, 182 deletions
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h
index f29897bc55d..4eb7cd5df22 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet.h
@@ -357,146 +357,129 @@ ccl_device void bsdf_microfacet_ggx_blur(ccl_private ShaderClosure *sc, float ro
bsdf->alpha_y = fmaxf(roughness, bsdf->alpha_y);
}
-ccl_device Spectrum bsdf_microfacet_ggx_eval_reflect(ccl_private const ShaderClosure *sc,
+ccl_device Spectrum bsdf_microfacet_ggx_eval_reflect(ccl_private const MicrofacetBsdf *bsdf,
+ const float3 N,
const float3 I,
const float3 omega_in,
- ccl_private float *pdf)
+ ccl_private float *pdf,
+ const float alpha_x,
+ const float alpha_y,
+ const float cosNO,
+ const float cosNI)
{
- ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
- float alpha_x = bsdf->alpha_x;
- float alpha_y = bsdf->alpha_y;
- bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
- float3 N = bsdf->N;
-
- if (m_refractive || alpha_x * alpha_y <= 1e-7f) {
+ if (!(cosNI > 0 && cosNO > 0)) {
*pdf = 0.0f;
return zero_spectrum();
}
- float cosNO = dot(N, I);
- float cosNI = dot(N, omega_in);
-
- if (cosNI > 0 && cosNO > 0) {
- /* get half vector */
- float3 m = normalize(omega_in + I);
- float alpha2 = alpha_x * alpha_y;
- float D, G1o, G1i;
-
- if (alpha_x == alpha_y) {
- /* isotropic
- * eq. 20: (F*G*D)/(4*in*on)
- * eq. 33: first we calculate D(m) */
- float cosThetaM = dot(N, m);
- float cosThetaM2 = cosThetaM * cosThetaM;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
- float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
-
- if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
- /* use GTR1 for clearcoat */
- D = D_GTR1(cosThetaM, bsdf->alpha_x);
-
- /* the alpha value for clearcoat is a fixed 0.25 => alpha2 = 0.25 * 0.25 */
- alpha2 = 0.0625f;
- }
- else {
- /* use GTR2 otherwise */
- D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
- }
+ /* get half vector */
+ float3 m = normalize(omega_in + I);
+ float alpha2 = alpha_x * alpha_y;
+ float D, G1o, G1i;
+
+ if (alpha_x == alpha_y) {
+ /* isotropic
+ * eq. 20: (F*G*D)/(4*in*on)
+ * eq. 33: first we calculate D(m) */
+ float cosThetaM = dot(N, m);
+ float cosThetaM2 = cosThetaM * cosThetaM;
+ float cosThetaM4 = cosThetaM2 * cosThetaM2;
+ float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
- /* eq. 34: now calculate G1(i,m) and G1(o,m) */
- G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
- G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
+ if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
+ /* use GTR1 for clearcoat */
+ D = D_GTR1(cosThetaM, bsdf->alpha_x);
+
+ /* the alpha value for clearcoat is a fixed 0.25 => alpha2 = 0.25 * 0.25 */
+ alpha2 = 0.0625f;
}
else {
- /* anisotropic */
- float3 X, Y, Z = N;
- make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
+ /* use GTR2 otherwise */
+ D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
+ }
- /* distribution */
- float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m));
- float slope_x = -local_m.x / (local_m.z * alpha_x);
- float slope_y = -local_m.y / (local_m.z * alpha_y);
- float slope_len = 1 + slope_x * slope_x + slope_y * slope_y;
+ /* eq. 34: now calculate G1(i,m) and G1(o,m) */
+ G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
+ G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
+ }
+ else {
+ /* anisotropic */
+ float3 X, Y, Z = N;
+ make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
- float cosThetaM = local_m.z;
- float cosThetaM2 = cosThetaM * cosThetaM;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
+ /* distribution */
+ float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m));
+ float slope_x = -local_m.x / (local_m.z * alpha_x);
+ float slope_y = -local_m.y / (local_m.z * alpha_y);
+ float slope_len = 1 + slope_x * slope_x + slope_y * slope_y;
- D = 1 / ((slope_len * slope_len) * M_PI_F * alpha2 * cosThetaM4);
+ float cosThetaM = local_m.z;
+ float cosThetaM2 = cosThetaM * cosThetaM;
+ float cosThetaM4 = cosThetaM2 * cosThetaM2;
- /* G1(i,m) and G1(o,m) */
- float tanThetaO2 = (1 - cosNO * cosNO) / (cosNO * cosNO);
- float cosPhiO = dot(I, X);
- float sinPhiO = dot(I, Y);
+ D = 1 / ((slope_len * slope_len) * M_PI_F * alpha2 * cosThetaM4);
- float alphaO2 = (cosPhiO * cosPhiO) * (alpha_x * alpha_x) +
- (sinPhiO * sinPhiO) * (alpha_y * alpha_y);
- alphaO2 /= cosPhiO * cosPhiO + sinPhiO * sinPhiO;
+ /* G1(i,m) and G1(o,m) */
+ float tanThetaO2 = (1 - cosNO * cosNO) / (cosNO * cosNO);
+ float cosPhiO = dot(I, X);
+ float sinPhiO = dot(I, Y);
- G1o = 2 / (1 + safe_sqrtf(1 + alphaO2 * tanThetaO2));
+ float alphaO2 = (cosPhiO * cosPhiO) * (alpha_x * alpha_x) +
+ (sinPhiO * sinPhiO) * (alpha_y * alpha_y);
+ alphaO2 /= cosPhiO * cosPhiO + sinPhiO * sinPhiO;
- float tanThetaI2 = (1 - cosNI * cosNI) / (cosNI * cosNI);
- float cosPhiI = dot(omega_in, X);
- float sinPhiI = dot(omega_in, Y);
+ G1o = 2 / (1 + safe_sqrtf(1 + alphaO2 * tanThetaO2));
- float alphaI2 = (cosPhiI * cosPhiI) * (alpha_x * alpha_x) +
- (sinPhiI * sinPhiI) * (alpha_y * alpha_y);
- alphaI2 /= cosPhiI * cosPhiI + sinPhiI * sinPhiI;
+ float tanThetaI2 = (1 - cosNI * cosNI) / (cosNI * cosNI);
+ float cosPhiI = dot(omega_in, X);
+ float sinPhiI = dot(omega_in, Y);
- G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2));
- }
+ float alphaI2 = (cosPhiI * cosPhiI) * (alpha_x * alpha_x) +
+ (sinPhiI * sinPhiI) * (alpha_y * alpha_y);
+ alphaI2 /= cosPhiI * cosPhiI + sinPhiI * sinPhiI;
- float G = G1o * G1i;
+ G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2));
+ }
- /* eq. 20 */
- float common = D * 0.25f / cosNO;
+ float G = G1o * G1i;
- Spectrum F = reflection_color(bsdf, omega_in, m);
- if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
- F *= 0.25f * bsdf->extra->clearcoat;
- }
+ /* eq. 20 */
+ float common = D * 0.25f / cosNO;
- Spectrum out = F * G * common;
+ Spectrum F = reflection_color(bsdf, omega_in, m);
+ if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
+ F *= 0.25f * bsdf->extra->clearcoat;
+ }
- /* eq. 2 in distribution of visible normals sampling
- * `pm = Dw = G1o * dot(m, I) * D / dot(N, I);` */
+ Spectrum out = F * G * common;
- /* eq. 38 - but see also:
- * eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
- * `pdf = pm * 0.25 / dot(m, I);` */
- *pdf = G1o * common;
+ /* eq. 2 in distribution of visible normals sampling
+ * `pm = Dw = G1o * dot(m, I) * D / dot(N, I);` */
- return out;
- }
+ /* eq. 38 - but see also:
+ * eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
+ * `pdf = pm * 0.25 / dot(m, I);` */
+ *pdf = G1o * common;
- return zero_spectrum();
+ return out;
}
-ccl_device Spectrum bsdf_microfacet_ggx_eval_transmit(ccl_private const ShaderClosure *sc,
+ccl_device Spectrum bsdf_microfacet_ggx_eval_transmit(ccl_private const MicrofacetBsdf *bsdf,
+ const float3 N,
const float3 I,
const float3 omega_in,
- ccl_private float *pdf)
+ ccl_private float *pdf,
+ const float alpha_x,
+ const float alpha_y,
+ const float cosNO,
+ const float cosNI)
{
- ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
- float alpha_x = bsdf->alpha_x;
- float alpha_y = bsdf->alpha_y;
- float m_eta = bsdf->ior;
- bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
- float3 N = bsdf->N;
-
- if (!m_refractive || alpha_x * alpha_y <= 1e-7f) {
- *pdf = 0.0f;
- return zero_spectrum();
- }
-
- float cosNO = dot(N, I);
- float cosNI = dot(N, omega_in);
-
if (cosNO <= 0 || cosNI >= 0) {
*pdf = 0.0f;
return zero_spectrum(); /* vectors on same side -- not possible */
}
/* compute half-vector of the refraction (eq. 16) */
+ float m_eta = bsdf->ior;
float3 ht = -(m_eta * omega_in + I);
float3 Ht = normalize(ht);
float cosHO = dot(Ht, I);
@@ -533,6 +516,30 @@ ccl_device Spectrum bsdf_microfacet_ggx_eval_transmit(ccl_private const ShaderCl
return make_spectrum(out);
}
+ccl_device Spectrum bsdf_microfacet_ggx_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
+{
+ ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
+ const float alpha_x = bsdf->alpha_x;
+ const float alpha_y = bsdf->alpha_y;
+ const bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
+ const float3 N = bsdf->N;
+ const float cosNO = dot(N, I);
+ const float cosNI = dot(N, omega_in);
+
+ if (((cosNI < 0.0f) != m_refractive) || alpha_x * alpha_y <= 1e-7f) {
+ *pdf = 0.0f;
+ return zero_spectrum();
+ }
+
+ return (cosNI < 0.0f) ? bsdf_microfacet_ggx_eval_transmit(
+ bsdf, N, I, omega_in, pdf, alpha_x, alpha_y, cosNO, cosNI) :
+ bsdf_microfacet_ggx_eval_reflect(
+ bsdf, N, I, omega_in, pdf, alpha_x, alpha_y, cosNO, cosNI);
+}
+
ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg,
ccl_private const ShaderClosure *sc,
float3 Ng,
@@ -811,111 +818,95 @@ ccl_device_inline float bsdf_beckmann_aniso_G1(
return ((2.181f * a + 3.535f) * a) / ((2.577f * a + 2.276f) * a + 1.0f);
}
-ccl_device Spectrum bsdf_microfacet_beckmann_eval_reflect(ccl_private const ShaderClosure *sc,
+ccl_device Spectrum bsdf_microfacet_beckmann_eval_reflect(ccl_private const MicrofacetBsdf *bsdf,
+ const float3 N,
const float3 I,
const float3 omega_in,
- ccl_private float *pdf)
+ ccl_private float *pdf,
+ const float alpha_x,
+ const float alpha_y,
+ const float cosNO,
+ const float cosNI)
{
- ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
- float alpha_x = bsdf->alpha_x;
- float alpha_y = bsdf->alpha_y;
- bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
- float3 N = bsdf->N;
-
- if (m_refractive || alpha_x * alpha_y <= 1e-7f) {
+ if (!(cosNO > 0 && cosNI > 0)) {
*pdf = 0.0f;
return zero_spectrum();
}
- float cosNO = dot(N, I);
- float cosNI = dot(N, omega_in);
-
- if (cosNO > 0 && cosNI > 0) {
- /* get half vector */
- float3 m = normalize(omega_in + I);
-
- float alpha2 = alpha_x * alpha_y;
- float D, G1o, G1i;
-
- if (alpha_x == alpha_y) {
- /* isotropic
- * eq. 20: (F*G*D)/(4*in*on)
- * eq. 25: first we calculate D(m) */
- float cosThetaM = dot(N, m);
- float cosThetaM2 = cosThetaM * cosThetaM;
- float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
- D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4);
-
- /* eq. 26, 27: now calculate G1(i,m) and G1(o,m) */
- G1o = bsdf_beckmann_G1(alpha_x, cosNO);
- G1i = bsdf_beckmann_G1(alpha_x, cosNI);
- }
- else {
- /* anisotropic */
- float3 X, Y, Z = N;
- make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
+ /* get half vector */
+ float3 m = normalize(omega_in + I);
- /* distribution */
- float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m));
- float slope_x = -local_m.x / (local_m.z * alpha_x);
- float slope_y = -local_m.y / (local_m.z * alpha_y);
+ float alpha2 = alpha_x * alpha_y;
+ float D, G1o, G1i;
- float cosThetaM = local_m.z;
- float cosThetaM2 = cosThetaM * cosThetaM;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
+ if (alpha_x == alpha_y) {
+ /* isotropic
+ * eq. 20: (F*G*D)/(4*in*on)
+ * eq. 25: first we calculate D(m) */
+ float cosThetaM = dot(N, m);
+ float cosThetaM2 = cosThetaM * cosThetaM;
+ float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
+ float cosThetaM4 = cosThetaM2 * cosThetaM2;
+ D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4);
+
+ /* eq. 26, 27: now calculate G1(i,m) and G1(o,m) */
+ G1o = bsdf_beckmann_G1(alpha_x, cosNO);
+ G1i = bsdf_beckmann_G1(alpha_x, cosNI);
+ }
+ else {
+ /* anisotropic */
+ float3 X, Y, Z = N;
+ make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
- D = expf(-slope_x * slope_x - slope_y * slope_y) / (M_PI_F * alpha2 * cosThetaM4);
+ /* distribution */
+ float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m));
+ float slope_x = -local_m.x / (local_m.z * alpha_x);
+ float slope_y = -local_m.y / (local_m.z * alpha_y);
- /* G1(i,m) and G1(o,m) */
- G1o = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNO, dot(I, X), dot(I, Y));
- G1i = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNI, dot(omega_in, X), dot(omega_in, Y));
- }
+ float cosThetaM = local_m.z;
+ float cosThetaM2 = cosThetaM * cosThetaM;
+ float cosThetaM4 = cosThetaM2 * cosThetaM2;
- float G = G1o * G1i;
+ D = expf(-slope_x * slope_x - slope_y * slope_y) / (M_PI_F * alpha2 * cosThetaM4);
- /* eq. 20 */
- float common = D * 0.25f / cosNO;
- float out = G * common;
+ /* G1(i,m) and G1(o,m) */
+ G1o = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNO, dot(I, X), dot(I, Y));
+ G1i = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNI, dot(omega_in, X), dot(omega_in, Y));
+ }
- /* eq. 2 in distribution of visible normals sampling
- * pm = Dw = G1o * dot(m, I) * D / dot(N, I); */
+ float G = G1o * G1i;
- /* eq. 38 - but see also:
- * eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
- * pdf = pm * 0.25 / dot(m, I); */
- *pdf = G1o * common;
+ /* eq. 20 */
+ float common = D * 0.25f / cosNO;
+ float out = G * common;
- return make_spectrum(out);
- }
+ /* eq. 2 in distribution of visible normals sampling
+ * pm = Dw = G1o * dot(m, I) * D / dot(N, I); */
+
+ /* eq. 38 - but see also:
+ * eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
+ * pdf = pm * 0.25 / dot(m, I); */
+ *pdf = G1o * common;
- return zero_spectrum();
+ return make_spectrum(out);
}
-ccl_device Spectrum bsdf_microfacet_beckmann_eval_transmit(ccl_private const ShaderClosure *sc,
+ccl_device Spectrum bsdf_microfacet_beckmann_eval_transmit(ccl_private const MicrofacetBsdf *bsdf,
+ const float3 N,
const float3 I,
const float3 omega_in,
- ccl_private float *pdf)
+ ccl_private float *pdf,
+ const float alpha_x,
+ const float alpha_y,
+ const float cosNO,
+ const float cosNI)
{
- ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
- float alpha_x = bsdf->alpha_x;
- float alpha_y = bsdf->alpha_y;
- float m_eta = bsdf->ior;
- bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
- float3 N = bsdf->N;
-
- if (!m_refractive || alpha_x * alpha_y <= 1e-7f) {
- *pdf = 0.0f;
- return zero_spectrum();
- }
-
- float cosNO = dot(N, I);
- float cosNI = dot(N, omega_in);
-
if (cosNO <= 0 || cosNI >= 0) {
*pdf = 0.0f;
return zero_spectrum();
}
+
+ const float m_eta = bsdf->ior;
/* compute half-vector of the refraction (eq. 16) */
float3 ht = -(m_eta * omega_in + I);
float3 Ht = normalize(ht);
@@ -950,6 +941,30 @@ ccl_device Spectrum bsdf_microfacet_beckmann_eval_transmit(ccl_private const Sha
return make_spectrum(out);
}
+ccl_device Spectrum bsdf_microfacet_beckmann_eval(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
+{
+ ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
+ const float alpha_x = bsdf->alpha_x;
+ const float alpha_y = bsdf->alpha_y;
+ const bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
+ const float3 N = bsdf->N;
+ const float cosNO = dot(N, I);
+ const float cosNI = dot(N, omega_in);
+
+ if (((cosNI < 0.0f) != m_refractive) || alpha_x * alpha_y <= 1e-7f) {
+ *pdf = 0.0f;
+ return zero_spectrum();
+ }
+
+ return (cosNI < 0.0f) ? bsdf_microfacet_beckmann_eval_transmit(
+ bsdf, N, I, omega_in, pdf, alpha_x, alpha_y, cosNO, cosNI) :
+ bsdf_microfacet_beckmann_eval_reflect(
+ bsdf, N, I, omega_in, pdf, alpha_x, alpha_y, cosNO, cosNI);
+}
+
ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg,
ccl_private const ShaderClosure *sc,
float3 Ng,