[Bf-blender-cvs] [1f099fc] cycles_disney_brdf: added clearcoat implementation
Pascal Schoen
noreply at git.blender.org
Mon May 30 09:08:55 CEST 2016
Commit: 1f099fce249cb35e949cc629f7cca2167fca881a
Author: Pascal Schoen
Date: Tue May 3 16:54:49 2016 +0200
Branches: cycles_disney_brdf
https://developer.blender.org/rB1f099fce249cb35e949cc629f7cca2167fca881a
added clearcoat implementation
===================================================================
M intern/cycles/kernel/CMakeLists.txt
M intern/cycles/kernel/closure/bsdf.h
A intern/cycles/kernel/closure/bsdf_disney_clearcoat.h
M intern/cycles/kernel/closure/bsdf_disney_diffuse.h
M intern/cycles/kernel/closure/bsdf_disney_specular.h
M intern/cycles/kernel/osl/CMakeLists.txt
A intern/cycles/kernel/osl/bsdf_disney_clearcoat.cpp
M intern/cycles/kernel/osl/bsdf_disney_diffuse.cpp
M intern/cycles/kernel/osl/bsdf_disney_specular.cpp
M intern/cycles/kernel/osl/osl_closures.cpp
M intern/cycles/kernel/osl/osl_closures.h
M intern/cycles/kernel/shaders/stdosl.h
M intern/cycles/kernel/svm/svm_types.h
===================================================================
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index 9eaac73..bc75adb 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -90,6 +90,7 @@ set(SRC_CLOSURE_HEADERS
closure/volume.h
closure/bsdf_disney_diffuse.h
closure/bsdf_disney_specular.h
+ closure/bsdf_disney_clearcoat.h
)
set(SRC_SVM_HEADERS
diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h
index b92a864..7d4b8bd 100644
--- a/intern/cycles/kernel/closure/bsdf.h
+++ b/intern/cycles/kernel/closure/bsdf.h
@@ -28,6 +28,7 @@
#include "../closure/bsdf_hair.h"
#include "../closure/bsdf_disney_diffuse.h"
#include "../closure/bsdf_disney_specular.h"
+#include "../closure/bsdf_disney_clearcoat.h"
#ifdef __SUBSURFACE__
# include "../closure/bssrdf.h"
#endif
diff --git a/intern/cycles/kernel/closure/bsdf_disney_clearcoat.h b/intern/cycles/kernel/closure/bsdf_disney_clearcoat.h
new file mode 100644
index 0000000..6d09cb0
--- /dev/null
+++ b/intern/cycles/kernel/closure/bsdf_disney_clearcoat.h
@@ -0,0 +1,312 @@
+/*
+ * Adapted from Open Shading Language with this license:
+ *
+ * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
+ * All Rights Reserved.
+ *
+ * Modifications Copyright 2011, Blender Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Sony Pictures Imageworks nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __BSDF_DISNEY_CLEARCOAT_H__
+#define __BSDF_DISNEY_CLEARCOAT_H__
+
+CCL_NAMESPACE_BEGIN
+
+#define MIX(x, y, a) (x * (1.0f - a) + y * a)
+
+/* DISNEY CLEARCOAT */
+
+ccl_device float clear_SchlickFresnel(float u) {
+ float m = clamp(1.0f - u, 0.0f, 1.0f);
+ float m2 = m * m;
+ return m2 * m2 * m; // pow(m, 5)
+}
+
+/* structures */
+struct DisneyClearcoatBRDFParams {
+ // brdf parameters
+ float m_clearcoat;
+ float m_clearcoatGloss;
+
+ // precomputed values
+ float m_clearcoatRoughness;
+
+ void precompute_values() {
+ m_clearcoatRoughness = MIX(0.1f, 0.001f, m_clearcoatGloss);
+ }
+};
+
+typedef struct DisneyClearcoatBRDFParams DisneyClearcoatBRDFParams;
+
+
+ccl_device_inline void clear_microfacet_ggx_sample_slopes(
+ const float cos_theta_i, const float sin_theta_i,
+ float randu, float randv, float *slope_x, float *slope_y,
+ float *G1i)
+{
+ /* special case (normal incidence) */
+ if(cos_theta_i >= 0.99999f) {
+ const float r = safe_sqrtf(randu/(1.0f - randu));
+ const float phi = M_2PI_F * randv;
+ *slope_x = r * cosf(phi);
+ *slope_y = r * sinf(phi);
+ *G1i = 1.0f;
+
+ return;
+ }
+
+ /* precomputations */
+ 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));
+
+ *G1i = 1.0f/G1_inv;
+
+ /* sample slope_x */
+ const float A = 2.0f*randu*G1_inv - 1.0f;
+ const float AA = A*A;
+ const float tmp = 1.0f/(AA - 1.0f);
+ const float B = tan_theta_i;
+ const float BB = B*B;
+ const float D = safe_sqrtf(BB*(tmp*tmp) - (AA - BB)*tmp);
+ const float slope_x_1 = B*tmp - D;
+ const float slope_x_2 = B*tmp + D;
+ *slope_x = (A < 0.0f || slope_x_2*tan_theta_i > 1.0f)? slope_x_1: slope_x_2;
+
+ /* sample slope_y */
+ float S;
+
+ if(randv > 0.5f) {
+ S = 1.0f;
+ randv = 2.0f*(randv - 0.5f);
+ }
+ else {
+ S = -1.0f;
+ randv = 2.0f*(0.5f - randv);
+ }
+
+ const float z = (randv*(randv*(randv*0.27385f - 0.73369f) + 0.46341f)) / (randv*(randv*(randv*0.093073f + 0.309420f) - 1.000000f) + 0.597999f);
+ *slope_y = S * z * safe_sqrtf(1.0f + (*slope_x)*(*slope_x));
+}
+
+ccl_device_inline float3 clear_microfacet_sample_stretched(
+ const float3 omega_i, const float alpha_x, const float alpha_y,
+ const float randu, const float randv,
+ bool beckmann, float *G1i)
+{
+ /* 1. stretch omega_i */
+ float3 omega_i_ = make_float3(alpha_x * omega_i.x, alpha_y * omega_i.y, omega_i.z);
+ omega_i_ = normalize(omega_i_);
+
+ /* get polar coordinates of omega_i_ */
+ float costheta_ = 1.0f;
+ float sintheta_ = 0.0f;
+ float cosphi_ = 1.0f;
+ float sinphi_ = 0.0f;
+
+ if(omega_i_.z < 0.99999f) {
+ costheta_ = omega_i_.z;
+ sintheta_ = safe_sqrtf(1.0f - costheta_*costheta_);
+
+ float invlen = 1.0f/sintheta_;
+ cosphi_ = omega_i_.x * invlen;
+ sinphi_ = omega_i_.y * invlen;
+ }
+
+ /* 2. sample P22_{omega_i}(x_slope, y_slope, 1, 1) */
+ float slope_x, slope_y;
+
+ clear_microfacet_ggx_sample_slopes(costheta_, sintheta_,
+ randu, randv, &slope_x, &slope_y, G1i);
+
+ /* 3. rotate */
+ float tmp = cosphi_*slope_x - sinphi_*slope_y;
+ slope_y = sinphi_*slope_x + cosphi_*slope_y;
+ slope_x = tmp;
+
+ /* 4. unstretch */
+ slope_x = alpha_x * slope_x;
+ slope_y = alpha_y * slope_y;
+
+ /* 5. compute normal */
+ return normalize(make_float3(-slope_x, -slope_y, 1.0f));
+}
+
+ccl_device int bsdf_disney_clearcoat_setup(ShaderClosure *sc)
+{
+ sc->type = CLOSURE_BSDF_DISNEY_CLEARCOAT_ID;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
+}
+
+ccl_device float3 bsdf_disney_clearcoat_eval_reflect(const ShaderClosure *sc,
+ const DisneyClearcoatBRDFParams *params, const float3 I,
+ const float3 omega_in, float *pdf)
+{
+ if (params->m_clearcoat > 0.0f) {
+ float alpha = params->m_clearcoatRoughness;
+ float3 N = sc->N;
+
+ if (alpha <= 1e-4f)
+ return make_float3(0.0f, 0.0f, 0.0f);
+
+ 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 * alpha;
+ float D, G1o, G1i;
+
+ /* 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;
+ //D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
+ D = (alpha2 - 1) / (M_PI_F * logf(alpha2) * (1 + (alpha2 - 1) * cosThetaM2));
+
+ /* eq. 34: now calculate G1(i,m) and G1(o,m) */
+ G1o = 2 / (1 + safe_sqrtf(1 + 0.0625f * (1 - cosNO * cosNO) / (cosNO * cosNO)));
+ G1i = 2 / (1 + safe_sqrtf(1 + 0.0625f * (1 - cosNI * cosNI) / (cosNI * cosNI)));
+
+ float G = G1o * G1i;
+
+ /* eq. 20 */
+ float common = D * 0.25f / cosNO;
+
+ float FH = clear_SchlickFresnel(dot(omega_in, m));
+ float3 F = MIX(make_float3(0.04f, 0.04f, 0.04f), make_float3(1.0f, 1.0f, 1.0f), FH);
+
+ float3 out = F * G * common * 0.25f * params->m_clearcoat;
+
+ /* 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 out;
+ }
+ }
+
+ return make_float3(0.0f, 0.0f, 0.0f);
+}
+
+ccl_device float3 bsdf_disney_clearcoat_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+{
+ return make_float3(0.0f, 0.0f, 0.0f);
+}
+
+ccl_device int bsdf_disney_clearcoat_sample(const ShaderClosure *sc, const DisneyClearcoatBRDFParams *params,
+ float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv,
+ float3 *eval, float3 *omega_in, float3 *domega_in_dx,
+ float3 *domega_in_dy, float *pdf)
+{
+ if (params->m_clearcoat > 0.0f) {
+ float alpha = params->m_clearcoatRoughness;
+ float3 N = sc->N;
+
+ float cosNO = dot(N, I);
+ if (cosNO > 0) {
+ float3 X, Y, Z = N;
+
+ make_orthonormals(Z, &X, &Y);
+
+ /* importance sampling with distribution of visible normals. vectors are
+ * transformed to local space before and after */
+ float3 local_I = make_float3(dot(X, I), dot(Y, I), cosNO);
+ float3 local_m;
+ float3 m;
+ float G1o;
+
+ local_m = clear_microfacet_sample_stretched(local_I, alpha, alpha,
+ randu, randv, false, &G1o);
+
+ m = X*local_m.x + Y*local_m.y + Z*local_m.z;
+ float cosThetaM = local_m.z;
+
+ /* reflection or refraction? */
+ float cosMO = dot(m, I);
+
+ if (cosMO > 0) {
+ /* eq. 39 - compute actual reflected direction */
+ *omega_in = 2 * cosMO * m - I;
+
+ if (dot(Ng, *omega_in) > 0) {
+ if (alpha <= 1e-4f) {
+ /* some high number for MIS */
+ *pdf = 1e6f;
+ *eval = make_float3(1e6f, 1e6f, 1e6f);
+ }
+ else {
+ /* microfacet normal is visible to this ray */
+ /* eq. 33 */
+ float alpha2 = alpha * alpha;
+ float D, G1i;
+
+ float cosThetaM2 = cosThetaM * cosThetaM;
+ //float cosThetaM4 = cosThetaM2 * cosThetaM2;
+ //float tanThetaM2 = 1/(cosThetaM2) - 1;
+ //D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
+ D = (alpha2 - 1) / (M_PI_F * logf(alpha2) * (1 + (alpha2 - 1) * cosThetaM2));
+
+ /* eval BRDF*cosNI */
+ float
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list