Cycles: option to make background visible through glass transparent.
[blender-staging.git] / intern / cycles / kernel / closure / bsdf.h
index 2ab92badc93806e328ecdfaba4339c7ca5891d4b..6f0bdb3fa38214338c8d330b3dfed419bc26c379 100644 (file)
  * limitations under the License.
  */
 
-#include "../closure/bsdf_ashikhmin_velvet.h"
-#include "../closure/bsdf_diffuse.h"
-#include "../closure/bsdf_oren_nayar.h"
-#include "../closure/bsdf_phong_ramp.h"
-#include "../closure/bsdf_diffuse_ramp.h"
-#include "../closure/bsdf_microfacet.h"
-#include "../closure/bsdf_microfacet_multi.h"
-#include "../closure/bsdf_reflection.h"
-#include "../closure/bsdf_refraction.h"
-#include "../closure/bsdf_transparent.h"
-#include "../closure/bsdf_ashikhmin_shirley.h"
-#include "../closure/bsdf_toon.h"
-#include "../closure/bsdf_hair.h"
-#ifdef __SUBSURFACE__
-#  include "../closure/bssrdf.h"
-#endif
+#include "kernel/closure/bsdf_ashikhmin_velvet.h"
+#include "kernel/closure/bsdf_diffuse.h"
+#include "kernel/closure/bsdf_oren_nayar.h"
+#include "kernel/closure/bsdf_phong_ramp.h"
+#include "kernel/closure/bsdf_diffuse_ramp.h"
+#include "kernel/closure/bsdf_microfacet.h"
+#include "kernel/closure/bsdf_microfacet_multi.h"
+#include "kernel/closure/bsdf_reflection.h"
+#include "kernel/closure/bsdf_refraction.h"
+#include "kernel/closure/bsdf_transparent.h"
+#include "kernel/closure/bsdf_ashikhmin_shirley.h"
+#include "kernel/closure/bsdf_toon.h"
+#include "kernel/closure/bsdf_hair.h"
+#include "kernel/closure/bsdf_principled_diffuse.h"
+#include "kernel/closure/bsdf_principled_sheen.h"
+#include "kernel/closure/bssrdf.h"
 #ifdef __VOLUME__
-#  include "../closure/volume.h"
+#  include "kernel/closure/volume.h"
 #endif
 
 CCL_NAMESPACE_BEGIN
 
-ccl_device_inline int bsdf_sample(KernelGlobals *kg,
-                                  ShaderData *sd,
-                                  const ShaderClosure *sc,
-                                  float randu,
-                                  float randv,
-                                  float3 *eval,
-                                  float3 *omega_in,
-                                  differential3 *domega_in,
-                                  float *pdf)
+/* Returns the square of the roughness of the closure if it has roughness,
+ * 0 for singular closures and 1 otherwise. */
+ccl_device_inline float bsdf_get_roughness_squared(const ShaderClosure *sc)
+{
+       if(CLOSURE_IS_BSDF_SINGULAR(sc->type)) {
+               return 0.0f;
+       }
+
+       if(CLOSURE_IS_BSDF_MICROFACET(sc->type)) {
+               MicrofacetBsdf *bsdf = (MicrofacetBsdf*) sc;
+               return bsdf->alpha_x*bsdf->alpha_y;
+       }
+
+       return 1.0f;
+}
+
+ccl_device_forceinline int bsdf_sample(KernelGlobals *kg,
+                                       ShaderData *sd,
+                                       const ShaderClosure *sc,
+                                       float randu,
+                                       float randv,
+                                       float3 *eval,
+                                       float3 *omega_in,
+                                       differential3 *domega_in,
+                                       float *pdf)
 {
        int label;
 
        switch(sc->type) {
                case CLOSURE_BSDF_DIFFUSE_ID:
                case CLOSURE_BSDF_BSSRDF_ID:
-                       label = bsdf_diffuse_sample(sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
+                       label = bsdf_diffuse_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
                                eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
                        break;
 #ifdef __SVM__
                case CLOSURE_BSDF_OREN_NAYAR_ID:
-                       label = bsdf_oren_nayar_sample(sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
+                       label = bsdf_oren_nayar_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
                                eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
                        break;
 #ifdef __OSL__
                case CLOSURE_BSDF_PHONG_RAMP_ID:
-                       label = bsdf_phong_ramp_sample(sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
+                       label = bsdf_phong_ramp_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
                                eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
                        break;
                case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
-                       label = bsdf_diffuse_ramp_sample(sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
+                       label = bsdf_diffuse_ramp_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
                                eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
                        break;
 #endif
                case CLOSURE_BSDF_TRANSLUCENT_ID:
-                       label = bsdf_translucent_sample(sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
+                       label = bsdf_translucent_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
                                eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
                        break;
                case CLOSURE_BSDF_REFLECTION_ID:
-                       label = bsdf_reflection_sample(sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
+                       label = bsdf_reflection_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
                                eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
                        break;
                case CLOSURE_BSDF_REFRACTION_ID:
-                       label = bsdf_refraction_sample(sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
+                       label = bsdf_refraction_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
                                eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
                        break;
                case CLOSURE_BSDF_TRANSPARENT_ID:
-                       label = bsdf_transparent_sample(sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
+                       label = bsdf_transparent_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
                                eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
                        break;
                case CLOSURE_BSDF_MICROFACET_GGX_ID:
+               case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
+               case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
                case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
+               case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
                case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
-                       label = bsdf_microfacet_ggx_sample(kg, sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
+                       label = bsdf_microfacet_ggx_sample(kg, sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
                                eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
                        break;
                case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
-                       label = bsdf_microfacet_multi_ggx_sample(kg, sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
-                               eval, omega_in,  &domega_in->dx, &domega_in->dy, pdf, &ccl_fetch(sd, lcg_state));
+               case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
+                       label = bsdf_microfacet_multi_ggx_sample(kg, sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+                               eval, omega_in,  &domega_in->dx, &domega_in->dy, pdf, &sd->lcg_state);
                        break;
                case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
-                       label = bsdf_microfacet_multi_ggx_glass_sample(kg, sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
-                               eval, omega_in,  &domega_in->dx, &domega_in->dy, pdf, &ccl_fetch(sd, lcg_state));
+               case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
+                       label = bsdf_microfacet_multi_ggx_glass_sample(kg, sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+                               eval, omega_in,  &domega_in->dx, &domega_in->dy, pdf, &sd->lcg_state);
                        break;
                case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
                case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
                case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
-                       label = bsdf_microfacet_beckmann_sample(kg, sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
+                       label = bsdf_microfacet_beckmann_sample(kg, sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
                                eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
                        break;
                case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
                case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID:
-                       label = bsdf_ashikhmin_shirley_sample(sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
+                       label = bsdf_ashikhmin_shirley_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
                                eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
                        break;
                case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
-                       label = bsdf_ashikhmin_velvet_sample(sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
+                       label = bsdf_ashikhmin_velvet_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
                                eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
                        break;
                case CLOSURE_BSDF_DIFFUSE_TOON_ID:
-                       label = bsdf_diffuse_toon_sample(sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
+                       label = bsdf_diffuse_toon_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
                                eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
                        break;
                case CLOSURE_BSDF_GLOSSY_TOON_ID:
-                       label = bsdf_glossy_toon_sample(sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
+                       label = bsdf_glossy_toon_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
                                eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
                        break;
                case CLOSURE_BSDF_HAIR_REFLECTION_ID:
-                       label = bsdf_hair_reflection_sample(sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
+                       label = bsdf_hair_reflection_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
                                eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
                        break;
                case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
-                       label = bsdf_hair_transmission_sample(sc, ccl_fetch(sd, Ng), ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv,
+                       label = bsdf_hair_transmission_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
                                eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
                        break;
+#ifdef __PRINCIPLED__
+               case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
+               case CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID:
+                       label = bsdf_principled_diffuse_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+                               eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+                       break;
+               case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID:
+                       label = bsdf_principled_sheen_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+                               eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+                       break;
+#endif  /* __PRINCIPLED__ */
 #endif
 #ifdef __VOLUME__
                case CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID:
-                       label = volume_henyey_greenstein_sample(sc, ccl_fetch(sd, I), ccl_fetch(sd, dI).dx, ccl_fetch(sd, dI).dy, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+                       label = volume_henyey_greenstein_sample(sc, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
                        break;
 #endif
                default:
@@ -141,13 +173,24 @@ ccl_device_inline int bsdf_sample(KernelGlobals *kg,
                        break;
        }
 
+       /* Test if BSDF sample should be treated as transparent for background. */
+       if(label & LABEL_TRANSMIT) {
+               float threshold_squared = kernel_data.background.transparent_roughness_squared_threshold;
+
+               if(threshold_squared >= 0.0f) {
+                       if(bsdf_get_roughness_squared(sc) <= threshold_squared) {
+                               label |= LABEL_TRANSMIT_TRANSPARENT;
+                       }
+               }
+       }
+
        return label;
 }
 
 #ifndef __KERNEL_CUDA__
 ccl_device
 #else
-ccl_device_inline
+ccl_device_forceinline
 #endif
 float3 bsdf_eval(KernelGlobals *kg,
                  ShaderData *sd,
@@ -157,75 +200,89 @@ float3 bsdf_eval(KernelGlobals *kg,
 {
        float3 eval;
 
-       if(dot(ccl_fetch(sd, Ng), omega_in) >= 0.0f) {
+       if(dot(sd->Ng, omega_in) >= 0.0f) {
                switch(sc->type) {
                        case CLOSURE_BSDF_DIFFUSE_ID:
                        case CLOSURE_BSDF_BSSRDF_ID:
-                               eval = bsdf_diffuse_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = bsdf_diffuse_eval_reflect(sc, sd->I, omega_in, pdf);
                                break;
 #ifdef __SVM__
                        case CLOSURE_BSDF_OREN_NAYAR_ID:
-                               eval = bsdf_oren_nayar_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = bsdf_oren_nayar_eval_reflect(sc, sd->I, omega_in, pdf);
                                break;
 #ifdef __OSL__
                        case CLOSURE_BSDF_PHONG_RAMP_ID:
-                               eval = bsdf_phong_ramp_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = bsdf_phong_ramp_eval_reflect(sc, sd->I, omega_in, pdf);
                                break;
                        case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
-                               eval = bsdf_diffuse_ramp_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = bsdf_diffuse_ramp_eval_reflect(sc, sd->I, omega_in, pdf);
                                break;
 #endif
                        case CLOSURE_BSDF_TRANSLUCENT_ID:
-                               eval = bsdf_translucent_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = bsdf_translucent_eval_reflect(sc, sd->I, omega_in, pdf);
                                break;
                        case CLOSURE_BSDF_REFLECTION_ID:
-                               eval = bsdf_reflection_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = bsdf_reflection_eval_reflect(sc, sd->I, omega_in, pdf);
                                break;
                        case CLOSURE_BSDF_REFRACTION_ID:
-                               eval = bsdf_refraction_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = bsdf_refraction_eval_reflect(sc, sd->I, omega_in, pdf);
                                break;
                        case CLOSURE_BSDF_TRANSPARENT_ID:
-                               eval = bsdf_transparent_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = bsdf_transparent_eval_reflect(sc, sd->I, omega_in, pdf);
                                break;
                        case CLOSURE_BSDF_MICROFACET_GGX_ID:
+                       case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
+                       case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
                        case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
+                       case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
                        case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
-                               eval = bsdf_microfacet_ggx_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = bsdf_microfacet_ggx_eval_reflect(sc, sd->I, omega_in, pdf);
                                break;
                        case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
-                               eval = bsdf_microfacet_multi_ggx_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf, &ccl_fetch(sd, lcg_state));
+                       case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
+                               eval = bsdf_microfacet_multi_ggx_eval_reflect(sc, sd->I, omega_in, pdf, &sd->lcg_state);
                                break;
                        case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
-                               eval = bsdf_microfacet_multi_ggx_glass_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf, &ccl_fetch(sd, lcg_state));
+                       case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
+                               eval = bsdf_microfacet_multi_ggx_glass_eval_reflect(sc, sd->I, omega_in, pdf, &sd->lcg_state);
                                break;
                        case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
                        case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
                        case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
-                               eval = bsdf_microfacet_beckmann_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = bsdf_microfacet_beckmann_eval_reflect(sc, sd->I, omega_in, pdf);
                                break;
                        case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
                        case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID:
-                               eval = bsdf_ashikhmin_shirley_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = bsdf_ashikhmin_shirley_eval_reflect(sc, sd->I, omega_in, pdf);
                                break;
                        case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
-                               eval = bsdf_ashikhmin_velvet_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = bsdf_ashikhmin_velvet_eval_reflect(sc, sd->I, omega_in, pdf);
                                break;
                        case CLOSURE_BSDF_DIFFUSE_TOON_ID:
-                               eval = bsdf_diffuse_toon_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = bsdf_diffuse_toon_eval_reflect(sc, sd->I, omega_in, pdf);
                                break;
                        case CLOSURE_BSDF_GLOSSY_TOON_ID:
-                               eval = bsdf_glossy_toon_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = bsdf_glossy_toon_eval_reflect(sc, sd->I, omega_in, pdf);
                                break;
                        case CLOSURE_BSDF_HAIR_REFLECTION_ID:
-                               eval = bsdf_hair_reflection_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = bsdf_hair_reflection_eval_reflect(sc, sd->I, omega_in, pdf);
                                break;
                        case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
-                               eval = bsdf_hair_transmission_eval_reflect(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = bsdf_hair_transmission_eval_reflect(sc, sd->I, omega_in, pdf);
                                break;
+#ifdef __PRINCIPLED__
+                       case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
+                       case CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID:
+                               eval = bsdf_principled_diffuse_eval_reflect(sc, sd->I, omega_in, pdf);
+                               break;
+                       case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID:
+                               eval = bsdf_principled_sheen_eval_reflect(sc, sd->I, omega_in, pdf);
+                               break;
+#endif  /* __PRINCIPLED__ */
 #endif
 #ifdef __VOLUME__
                        case CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID:
-                               eval = volume_henyey_greenstein_eval_phase(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = volume_henyey_greenstein_eval_phase(sc, sd->I, omega_in, pdf);
                                break;
 #endif
                        default:
@@ -237,63 +294,77 @@ float3 bsdf_eval(KernelGlobals *kg,
                switch(sc->type) {
                        case CLOSURE_BSDF_DIFFUSE_ID:
                        case CLOSURE_BSDF_BSSRDF_ID:
-                               eval = bsdf_diffuse_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = bsdf_diffuse_eval_transmit(sc, sd->I, omega_in, pdf);
                                break;
 #ifdef __SVM__
                        case CLOSURE_BSDF_OREN_NAYAR_ID:
-                               eval = bsdf_oren_nayar_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = bsdf_oren_nayar_eval_transmit(sc, sd->I, omega_in, pdf);
                                break;
                        case CLOSURE_BSDF_TRANSLUCENT_ID:
-                               eval = bsdf_translucent_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = bsdf_translucent_eval_transmit(sc, sd->I, omega_in, pdf);
                                break;
                        case CLOSURE_BSDF_REFLECTION_ID:
-                               eval = bsdf_reflection_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = bsdf_reflection_eval_transmit(sc, sd->I, omega_in, pdf);
                                break;
                        case CLOSURE_BSDF_REFRACTION_ID:
-                               eval = bsdf_refraction_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = bsdf_refraction_eval_transmit(sc, sd->I, omega_in, pdf);
                                break;
                        case CLOSURE_BSDF_TRANSPARENT_ID:
-                               eval = bsdf_transparent_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = bsdf_transparent_eval_transmit(sc, sd->I, omega_in, pdf);
                                break;
                        case CLOSURE_BSDF_MICROFACET_GGX_ID:
+                       case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
+                       case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
                        case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
+                       case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
                        case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
-                               eval = bsdf_microfacet_ggx_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = bsdf_microfacet_ggx_eval_transmit(sc, sd->I, omega_in, pdf);
                                break;
                        case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
-                               eval = bsdf_microfacet_multi_ggx_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf, &ccl_fetch(sd, lcg_state));
+                       case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
+                               eval = bsdf_microfacet_multi_ggx_eval_transmit(sc, sd->I, omega_in, pdf, &sd->lcg_state);
                                break;
                        case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
-                               eval = bsdf_microfacet_multi_ggx_glass_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf, &ccl_fetch(sd, lcg_state));
+                       case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
+                               eval = bsdf_microfacet_multi_ggx_glass_eval_transmit(sc, sd->I, omega_in, pdf, &sd->lcg_state);
                                break;
                        case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
                        case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
                        case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
-                               eval = bsdf_microfacet_beckmann_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = bsdf_microfacet_beckmann_eval_transmit(sc, sd->I, omega_in, pdf);
                                break;
                        case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
                        case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID:
-                               eval = bsdf_ashikhmin_shirley_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = bsdf_ashikhmin_shirley_eval_transmit(sc, sd->I, omega_in, pdf);
                                break;
                        case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
-                               eval = bsdf_ashikhmin_velvet_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = bsdf_ashikhmin_velvet_eval_transmit(sc, sd->I, omega_in, pdf);
                                break;
                        case CLOSURE_BSDF_DIFFUSE_TOON_ID:
-                               eval = bsdf_diffuse_toon_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = bsdf_diffuse_toon_eval_transmit(sc, sd->I, omega_in, pdf);
                                break;
                        case CLOSURE_BSDF_GLOSSY_TOON_ID:
-                               eval = bsdf_glossy_toon_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = bsdf_glossy_toon_eval_transmit(sc, sd->I, omega_in, pdf);
                                break;
                        case CLOSURE_BSDF_HAIR_REFLECTION_ID:
-                               eval = bsdf_hair_reflection_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = bsdf_hair_reflection_eval_transmit(sc, sd->I, omega_in, pdf);
                                break;
                        case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
-                               eval = bsdf_hair_transmission_eval_transmit(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = bsdf_hair_transmission_eval_transmit(sc, sd->I, omega_in, pdf);
+                               break;
+#ifdef __PRINCIPLED__
+                       case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
+                       case CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID:
+                               eval = bsdf_principled_diffuse_eval_transmit(sc, sd->I, omega_in, pdf);
                                break;
+                       case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID:
+                               eval = bsdf_principled_sheen_eval_transmit(sc, sd->I, omega_in, pdf);
+                               break;
+#endif  /* __PRINCIPLED__ */
 #endif
 #ifdef __VOLUME__
                        case CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID:
-                               eval = volume_henyey_greenstein_eval_phase(sc, ccl_fetch(sd, I), omega_in, pdf);
+                               eval = volume_henyey_greenstein_eval_phase(sc, sd->I, omega_in, pdf);
                                break;
 #endif
                        default:
@@ -311,11 +382,16 @@ ccl_device void bsdf_blur(KernelGlobals *kg, ShaderClosure *sc, float roughness)
 #ifdef __SVM__
        switch(sc->type) {
                case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
+               case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
                case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
+               case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
                        bsdf_microfacet_multi_ggx_blur(sc, roughness);
                        break;
                case CLOSURE_BSDF_MICROFACET_GGX_ID:
+               case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
+               case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
                case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
+               case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
                case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
                        bsdf_microfacet_ggx_blur(sc, roughness);
                        break;
@@ -349,10 +425,15 @@ ccl_device bool bsdf_merge(ShaderClosure *a, ShaderClosure *b)
                case CLOSURE_BSDF_REFLECTION_ID:
                case CLOSURE_BSDF_REFRACTION_ID:
                case CLOSURE_BSDF_MICROFACET_GGX_ID:
+               case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
+               case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
                case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
+               case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
                case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
                case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
+               case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
                case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
+               case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
                case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
                case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
                case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
@@ -367,6 +448,11 @@ ccl_device bool bsdf_merge(ShaderClosure *a, ShaderClosure *b)
                case CLOSURE_BSDF_HAIR_REFLECTION_ID:
                case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
                        return bsdf_hair_merge(a, b);
+#ifdef __PRINCIPLED__
+               case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
+               case CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID:
+                       return bsdf_principled_diffuse_merge(a, b);
+#endif
 #ifdef __VOLUME__
                case CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID:
                        return volume_henyey_greenstein_merge(a, b);