From 4711a3927dfcadaa1c36de0ba78fc304fac1dc8a Mon Sep 17 00:00:00 2001 From: Pascal Schoen Date: Mon, 18 Apr 2016 08:41:53 +0200 Subject: [PATCH 01/10] added vessel for disney diffuse shader --- intern/cycles/app/cycles_xml.cpp | 3 + intern/cycles/blender/blender_shader.cpp | 3 + intern/cycles/kernel/CMakeLists.txt | 1 + intern/cycles/kernel/closure/bsdf.h | 1 + .../kernel/closure/bsdf_disney_diffuse.h | 89 +++++++++++++++ intern/cycles/kernel/osl/CMakeLists.txt | 1 + .../cycles/kernel/osl/bsdf_disney_diffuse.cpp | 101 ++++++++++++++++++ intern/cycles/kernel/osl/osl_closures.cpp | 2 + intern/cycles/kernel/osl/osl_closures.h | 2 + intern/cycles/kernel/shaders/CMakeLists.txt | 1 + .../kernel/shaders/node_disney_bsdf.osl | 38 +++++++ intern/cycles/kernel/shaders/stdosl.h | 1 + intern/cycles/kernel/svm/svm_types.h | 1 + intern/cycles/render/nodes.cpp | 6 ++ intern/cycles/render/nodes.h | 5 + release/scripts/startup/nodeitems_builtins.py | 1 + source/blender/blenkernel/BKE_node.h | 1 + source/blender/blenkernel/intern/node.c | 1 + .../gpu/shaders/gpu_shader_material.glsl | 7 ++ source/blender/nodes/CMakeLists.txt | 1 + source/blender/nodes/NOD_shader.h | 1 + source/blender/nodes/NOD_static_types.h | 1 + .../shader/nodes/node_shader_bsdf_disney.c | 78 ++++++++++++++ 23 files changed, 346 insertions(+) create mode 100644 intern/cycles/kernel/closure/bsdf_disney_diffuse.h create mode 100644 intern/cycles/kernel/osl/bsdf_disney_diffuse.cpp create mode 100644 intern/cycles/kernel/shaders/node_disney_bsdf.osl create mode 100644 source/blender/nodes/shader/nodes/node_shader_bsdf_disney.c diff --git a/intern/cycles/app/cycles_xml.cpp b/intern/cycles/app/cycles_xml.cpp index 262e8c063a9..8fd9a81c8d5 100644 --- a/intern/cycles/app/cycles_xml.cpp +++ b/intern/cycles/app/cycles_xml.cpp @@ -539,6 +539,9 @@ static void xml_read_shader_graph(const XMLReadState& state, Shader *shader, pug else if(string_iequals(node.name(), "diffuse_bsdf")) { snode = new DiffuseBsdfNode(); } + /*else if(string_iequals(node.name(), "disney_bsdf")) { + snode = new DisneyBsdfNode(); + }*/ else if(string_iequals(node.name(), "translucent_bsdf")) { snode = new TranslucentBsdfNode(); } diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 6e4ca6627a1..01a6476fccd 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -527,6 +527,9 @@ static ShaderNode *add_node(Scene *scene, } node = hair; } + /*else if(b_node.is_a(&RNA_ShaderNodeBsdfDisney)) { + node = new DisneyBsdfNode(); + }*/ else if(b_node.is_a(&RNA_ShaderNodeBsdfTranslucent)) { node = new TranslucentBsdfNode(); } diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index 7080e83f715..bf99b5c9a33 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -87,6 +87,7 @@ set(SRC_CLOSURE_HEADERS closure/bssrdf.h closure/emissive.h closure/volume.h + closure/bsdf_disney_diffuse.h ) set(SRC_SVM_HEADERS diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h index f0add804c32..f40ed381ebb 100644 --- a/intern/cycles/kernel/closure/bsdf.h +++ b/intern/cycles/kernel/closure/bsdf.h @@ -26,6 +26,7 @@ #include "../closure/bsdf_ashikhmin_shirley.h" #include "../closure/bsdf_toon.h" #include "../closure/bsdf_hair.h" +#include "../closure/bsdf_disney_diffuse.h" #ifdef __SUBSURFACE__ # include "../closure/bssrdf.h" #endif diff --git a/intern/cycles/kernel/closure/bsdf_disney_diffuse.h b/intern/cycles/kernel/closure/bsdf_disney_diffuse.h new file mode 100644 index 00000000000..2b927c53858 --- /dev/null +++ b/intern/cycles/kernel/closure/bsdf_disney_diffuse.h @@ -0,0 +1,89 @@ +/* + * 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_DIFFUSE_ +#define __BSDF_DISNEY_DIFFUSE_H__ + +CCL_NAMESPACE_BEGIN + +/* DIFFUSE */ + +ccl_device int bsdf_disney_diffuse_setup(ShaderClosure *sc) +{ + sc->type = CLOSURE_BSDF_DISNEY_DIFFUSE_ID; + return SD_BSDF|SD_BSDF_HAS_EVAL; +} + +ccl_device float3 bsdf_disney_diffuse_eval_reflect(const ShaderClosure *sc, + float3 color, const float3 I, const float3 omega_in, float *pdf) +{ + float3 N = sc->N; + + float cos_pi = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F; + *pdf = cos_pi; + return make_float3(cos_pi * color[0], cos_pi * color[1], cos_pi * color[2]); +} + +ccl_device float3 bsdf_disney_diffuse_eval_transmit(const ShaderClosure *sc, + float3 color, const float3 I, const float3 omega_in, float *pdf) +{ + return make_float3(0.0f, 0.0f, 0.0f); +} + +ccl_device int bsdf_disney_diffuse_sample(const ShaderClosure *sc, float3 color, + 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) +{ + float3 N = sc->N; + + // distribution over the hemisphere + sample_cos_hemisphere(N, randu, randv, omega_in, pdf); + + if(dot(Ng, *omega_in) > 0.0f) { + *eval = make_float3(*pdf * color[0], *pdf * color[1], *pdf * color[2]); +#ifdef __RAY_DIFFERENTIALS__ + // TODO: find a better approximation for the diffuse bounce + *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx; + *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy; +#endif + } + else + *pdf = 0.0f; + + return LABEL_REFLECT|LABEL_DIFFUSE; +} + +CCL_NAMESPACE_END + +#endif /* __BSDF_DISNEY_DIFFUSE_H__ */ + diff --git a/intern/cycles/kernel/osl/CMakeLists.txt b/intern/cycles/kernel/osl/CMakeLists.txt index b10ec588757..d48aeef3bb2 100644 --- a/intern/cycles/kernel/osl/CMakeLists.txt +++ b/intern/cycles/kernel/osl/CMakeLists.txt @@ -21,6 +21,7 @@ set(SRC osl_closures.cpp osl_services.cpp osl_shader.cpp + bsdf_disney_diffuse.cpp ) set(HEADER_SRC diff --git a/intern/cycles/kernel/osl/bsdf_disney_diffuse.cpp b/intern/cycles/kernel/osl/bsdf_disney_diffuse.cpp new file mode 100644 index 00000000000..ba7d233759b --- /dev/null +++ b/intern/cycles/kernel/osl/bsdf_disney_diffuse.cpp @@ -0,0 +1,101 @@ +/* + * 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. + */ + +#include + +#include + +#include "kernel_compat_cpu.h" +#include "osl_closures.h" + +#include "kernel_types.h" +#include "kernel_montecarlo.h" +#include "closure/bsdf_disney_diffuse.h" + +CCL_NAMESPACE_BEGIN + +using namespace OSL; + +class DisneyDiffuseClosure : public CBSDFClosure { +public: + float3 color; + + DisneyDiffuseClosure() : CBSDFClosure(LABEL_DIFFUSE) + {} + + void setup() + { + sc.prim = this; + m_shaderdata_flag = bsdf_disney_diffuse_setup(&sc); + } + + void blur(float roughness) + { + //bsdf_disney_diffuse_blur(&sc, roughness); + } + + float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float& pdf) const + { + return bsdf_disney_diffuse_eval_reflect(&sc, color, omega_out, omega_in, &pdf); + } + + float3 eval_transmit(const float3 &omega_out, const float3 &omega_in, float& pdf) const + { + return bsdf_disney_diffuse_eval_transmit(&sc, color, omega_out, omega_in, &pdf); + } + + int sample(const float3 &Ng, + const float3 &omega_out, const float3 &domega_out_dx, const float3 &domega_out_dy, + float randu, float randv, + float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy, + float &pdf, float3 &eval) const + { + return bsdf_disney_diffuse_sample(&sc, color, Ng, omega_out, domega_out_dx, domega_out_dy, + randu, randv, &eval, &omega_in, &domega_in_dx, &domega_in_dy, &pdf); + } +}; + +ClosureParam *closure_bsdf_disney_diffuse_params() +{ + static ClosureParam params[] = { + CLOSURE_FLOAT3_PARAM(DisneyDiffuseClosure, sc.N), + CLOSURE_FLOAT3_PARAM(DisneyDiffuseClosure, color), + CLOSURE_STRING_KEYPARAM(DisneyDiffuseClosure, label, "label"), + CLOSURE_FINISH_PARAM(DisneyDiffuseClosure) + }; + return params; +} + +CCLOSURE_PREPARE(closure_bsdf_disney_diffuse_prepare, DisneyDiffuseClosure) + +CCL_NAMESPACE_END + diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp index 95b8cea0922..5e311f7e4d6 100644 --- a/intern/cycles/kernel/osl/osl_closures.cpp +++ b/intern/cycles/kernel/osl/osl_closures.cpp @@ -238,6 +238,8 @@ void OSLShader::register_closures(OSLShadingSystem *ss_) closure_bssrdf_gaussian_params(), closure_bssrdf_gaussian_prepare); register_closure(ss, "bssrdf_burley", id++, closure_bssrdf_burley_params(), closure_bssrdf_burley_prepare); + register_closure(ss, "disney_diffuse", id++, + closure_bsdf_disney_diffuse_params(), closure_bsdf_disney_diffuse_prepare); register_closure(ss, "hair_reflection", id++, bsdf_hair_reflection_params(), bsdf_hair_reflection_prepare); diff --git a/intern/cycles/kernel/osl/osl_closures.h b/intern/cycles/kernel/osl/osl_closures.h index 1578d06cd56..45c0b51783e 100644 --- a/intern/cycles/kernel/osl/osl_closures.h +++ b/intern/cycles/kernel/osl/osl_closures.h @@ -52,6 +52,7 @@ OSL::ClosureParam *closure_bssrdf_cubic_params(); OSL::ClosureParam *closure_bssrdf_gaussian_params(); OSL::ClosureParam *closure_bssrdf_burley_params(); OSL::ClosureParam *closure_henyey_greenstein_volume_params(); +OSL::ClosureParam *closure_bsdf_disney_diffuse_params(); void closure_emission_prepare(OSL::RendererServices *, int id, void *data); void closure_background_prepare(OSL::RendererServices *, int id, void *data); @@ -63,6 +64,7 @@ void closure_bssrdf_cubic_prepare(OSL::RendererServices *, int id, void *data); void closure_bssrdf_gaussian_prepare(OSL::RendererServices *, int id, void *data); void closure_bssrdf_burley_prepare(OSL::RendererServices *, int id, void *data); void closure_henyey_greenstein_volume_prepare(OSL::RendererServices *, int id, void *data); +void closure_bsdf_disney_diffuse_prepare(OSL::RendererServices *, int id, void *data); #define CCLOSURE_PREPARE(name, classname) \ void name(RendererServices *, int id, void *data) \ diff --git a/intern/cycles/kernel/shaders/CMakeLists.txt b/intern/cycles/kernel/shaders/CMakeLists.txt index 49030f33c26..c6c9e6ed009 100644 --- a/intern/cycles/kernel/shaders/CMakeLists.txt +++ b/intern/cycles/kernel/shaders/CMakeLists.txt @@ -81,6 +81,7 @@ set(SRC_OSL node_wireframe.osl node_hair_bsdf.osl node_uv_map.osl + #node_disney_bsdf.osl ) set(SRC_OSL_HEADERS diff --git a/intern/cycles/kernel/shaders/node_disney_bsdf.osl b/intern/cycles/kernel/shaders/node_disney_bsdf.osl new file mode 100644 index 00000000000..9bd225dd391 --- /dev/null +++ b/intern/cycles/kernel/shaders/node_disney_bsdf.osl @@ -0,0 +1,38 @@ +/* + * Copyright 2011-2013 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "stdosl.h" + +shader node_disney_bsdf( + color BaseColor = color(0.64555527, 0.41514809, 0.01698805), + float Metallic = 0.0, + float Subsurface = 0.0, + float Specular = 0.5, + float Roughness = 0.5, + float SpecularTint = 0.0, + float Anisotropic = 0.0, + float Sheen = 0.0, + float SheenTint = 0.5, + float Clearcoat = 0.0, + float ClearcoatGloss = 1.0, + normal Normal = N, + normal Tangent = normalize(dPdu), + normal AnisotropicRotation = normal(0, 0, 0), + output closure color BSDF = 0) +{ + BSDF = disney_diffuse(Normal, BaseColor); +} + diff --git a/intern/cycles/kernel/shaders/stdosl.h b/intern/cycles/kernel/shaders/stdosl.h index 8d5d3746caf..83e8bc61c6c 100644 --- a/intern/cycles/kernel/shaders/stdosl.h +++ b/intern/cycles/kernel/shaders/stdosl.h @@ -536,6 +536,7 @@ closure color emission() BUILTIN; closure color background() BUILTIN; closure color holdout() BUILTIN; closure color ambient_occlusion() BUILTIN; +closure color disney_diffuse(normal N, color c) BUILTIN; // BSSRDF closure color bssrdf_cubic(normal N, vector radius, float texture_blur, float sharpness) BUILTIN; diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index 21b0cb15a4f..c3999eaff4e 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -377,6 +377,7 @@ typedef enum ClosureType { CLOSURE_BSDF_OREN_NAYAR_ID, CLOSURE_BSDF_DIFFUSE_RAMP_ID, CLOSURE_BSDF_DIFFUSE_TOON_ID, + CLOSURE_BSDF_DISNEY_DIFFUSE_ID, /* Glossy */ CLOSURE_BSDF_GLOSSY_ID, diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index e612a2d36d6..696548f3fda 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -2067,6 +2067,12 @@ void DiffuseBsdfNode::compile(OSLCompiler& compiler) compiler.add(this, "node_diffuse_bsdf"); } +/* Disney BSDF Closure */ +/*DisneyBsdfNode::DisneyBsdfNode() +{ + closure = CLOSURE_BSDF_DISNEY_DIFFUSE_ID; +}*/ + /* Translucent BSDF Closure */ TranslucentBsdfNode::TranslucentBsdfNode() diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index ccfea033c12..8e0b4636633 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -410,6 +410,11 @@ public: SHADER_NODE_CLASS(DiffuseBsdfNode) }; +/*class DisneyBsdfNode : public BsdfNode { +public: + SHADER_NODE_CLASS(DisneyBsdfNode) +};*/ + class TranslucentBsdfNode : public BsdfNode { public: SHADER_NODE_CLASS(TranslucentBsdfNode) diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index 092cd31330c..08a6092787e 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -218,6 +218,7 @@ shader_node_categories = [ NodeItem("ShaderNodeMixShader"), NodeItem("ShaderNodeAddShader"), NodeItem("ShaderNodeBsdfDiffuse", poll=object_shader_nodes_poll), + #NodeItem("ShaderNodeBsdfDisney", poll=object_shader_nodes_poll), NodeItem("ShaderNodeBsdfGlossy", poll=object_shader_nodes_poll), NodeItem("ShaderNodeBsdfTransparent", poll=object_shader_nodes_poll), NodeItem("ShaderNodeBsdfRefraction", poll=object_shader_nodes_poll), diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 76e49566d19..c0f68f51e6a 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -787,6 +787,7 @@ struct ShadeResult; #define SH_NODE_OUTPUT_LINESTYLE 190 #define SH_NODE_UVALONGSTROKE 191 #define SH_NODE_TEX_POINTDENSITY 192 +//#define SH_NODE_BSDF_DISNEY 193 /* custom defines options for Material node */ #define SH_NODE_MAT_DIFF 1 diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 75f899dd597..1a1e1c3740a 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -3672,6 +3672,7 @@ static void registerShaderNodes(void) register_node_type_sh_background(); register_node_type_sh_bsdf_anisotropic(); register_node_type_sh_bsdf_diffuse(); + //register_node_type_sh_bsdf_disney(); register_node_type_sh_bsdf_glossy(); register_node_type_sh_bsdf_glass(); register_node_type_sh_bsdf_translucent(); diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 72a59e6843d..c1d7cc61872 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -2369,6 +2369,13 @@ void node_bsdf_toon(vec4 color, float size, float tsmooth, vec3 N, out vec4 resu node_bsdf_diffuse(color, 0.0, N, result); } +/*void node_bsdf_disney(vec4 baseColor, float metallic, float subsurface, float specular, float roughness, + float specularTint, float anisotropic, float sheen, float sheenTint, float clearcoat, + float clearcoatGloss, vec3 N, vec3 T, vec3 anisotropicRotation, out vec4 result) +{ + node_bsdf_diffuse(baseColor, roughness, N, result); +}*/ + void node_bsdf_translucent(vec4 color, vec3 N, out vec4 result) { node_bsdf_diffuse(color, 0.0, N, result); diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index d20881df150..72f1eeba50a 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -163,6 +163,7 @@ set(SRC shader/nodes/node_shader_background.c shader/nodes/node_shader_bsdf_anisotropic.c shader/nodes/node_shader_bsdf_diffuse.c + #shader/nodes/node_shader_bsdf_disney.c shader/nodes/node_shader_bsdf_glass.c shader/nodes/node_shader_bsdf_glossy.c shader/nodes/node_shader_bsdf_toon.c diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h index 4c0047f1d58..1b330efa9c6 100644 --- a/source/blender/nodes/NOD_shader.h +++ b/source/blender/nodes/NOD_shader.h @@ -106,6 +106,7 @@ void register_node_type_sh_bsdf_transparent(void); void register_node_type_sh_bsdf_velvet(void); void register_node_type_sh_bsdf_toon(void); void register_node_type_sh_bsdf_anisotropic(void); +//void register_node_type_sh_bsdf_disney(void); void register_node_type_sh_emission(void); void register_node_type_sh_holdout(void); void register_node_type_sh_volume_absorption(void); diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index 9e1a0c926fa..86bc07cf7f4 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -80,6 +80,7 @@ DefNode( ShaderNode, SH_NODE_BACKGROUND, 0, "BA DefNode( ShaderNode, SH_NODE_HOLDOUT, 0, "HOLDOUT", Holdout, "Holdout", "" ) DefNode( ShaderNode, SH_NODE_BSDF_ANISOTROPIC, def_anisotropic, "BSDF_ANISOTROPIC", BsdfAnisotropic, "Anisotropic BSDF", "" ) DefNode( ShaderNode, SH_NODE_BSDF_DIFFUSE, 0, "BSDF_DIFFUSE", BsdfDiffuse, "Diffuse BSDF", "" ) +//DefNode( ShaderNode, SH_NODE_BSDF_DISNEY, 0, "BSDF_DISNEY", BsdfDisney, "Disney BSDF", "" ) DefNode( ShaderNode, SH_NODE_BSDF_GLOSSY, def_glossy, "BSDF_GLOSSY", BsdfGlossy, "Glossy BSDF", "" ) DefNode( ShaderNode, SH_NODE_BSDF_GLASS, def_glass, "BSDF_GLASS", BsdfGlass, "Glass BSDF", "" ) DefNode( ShaderNode, SH_NODE_BSDF_REFRACTION, def_glass, "BSDF_REFRACTION", BsdfRefraction, "Refraction BSDF", "" ) diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_disney.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_disney.c new file mode 100644 index 00000000000..bd4b5f9ff8f --- /dev/null +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_disney.c @@ -0,0 +1,78 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "../node_shader_util.h" + +/* **************** OUTPUT ******************** */ + +static bNodeSocketTemplate sh_node_bsdf_disney_in[] = { + { SOCK_RGBA, 1, N_("BaseColor"), 0.64555527f, 0.41514809f, 0.01698805f, 1.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 1, N_("Metallic"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("Subsurface"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("Specular"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("Roughness"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("SpecularTint"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("Anisotropic"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("Sheen"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("SheenTint"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("Clearcoat"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("ClearcoatGloss"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, + { SOCK_VECTOR, 1, N_("Tangent"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, + { SOCK_VECTOR, 1, N_("AnisotropicRotation"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, + { -1, 0, "" } +}; + +static bNodeSocketTemplate sh_node_bsdf_disney_out[] = { + { SOCK_SHADER, 0, N_("BSDF")}, + { -1, 0, "" } +}; + +static int node_shader_gpu_bsdf_disney(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) +{ + if (!in[11].link) + in[11].link = GPU_builtin(GPU_VIEW_NORMAL); + else + GPU_link(mat, "direction_transform_m4v3", in[11].link, GPU_builtin(GPU_VIEW_MATRIX), &in[11].link); + + return GPU_stack_link(mat, "node_bsdf_disney", in, out); +} + +/* node type definition */ +void register_node_type_sh_bsdf_disney(void) +{ + static bNodeType ntype; + + sh_node_type_base(&ntype, SH_NODE_BSDF_DISNEY, "Disney BSDF", NODE_CLASS_SHADER, 0); + node_type_compatibility(&ntype, NODE_NEW_SHADING); + node_type_socket_templates(&ntype, sh_node_bsdf_disney_in, sh_node_bsdf_disney_out); + node_type_init(&ntype, NULL); + node_type_storage(&ntype, "", NULL, NULL); + node_type_gpu(&ntype, node_shader_gpu_bsdf_disney); + + nodeRegisterType(&ntype); +} From 9b262063767d6b05a617891c967d887d21bfb177 Mon Sep 17 00:00:00 2001 From: Pascal Schoen Date: Mon, 18 Apr 2016 15:21:32 +0200 Subject: [PATCH 02/10] disney diffuse is working correctly --- .../kernel/closure/bsdf_disney_diffuse.h | 310 ++++++++++++++++-- .../cycles/kernel/osl/bsdf_disney_diffuse.cpp | 22 +- intern/cycles/kernel/shaders/stdosl.h | 3 +- 3 files changed, 305 insertions(+), 30 deletions(-) diff --git a/intern/cycles/kernel/closure/bsdf_disney_diffuse.h b/intern/cycles/kernel/closure/bsdf_disney_diffuse.h index 2b927c53858..ff69a7aa8ec 100644 --- a/intern/cycles/kernel/closure/bsdf_disney_diffuse.h +++ b/intern/cycles/kernel/closure/bsdf_disney_diffuse.h @@ -1,3 +1,4 @@ + /* * Adapted from Open Shading Language with this license: * @@ -30,12 +31,153 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __BSDF_DISNEY_DIFFUSE_ +#ifndef __BSDF_DISNEY_DIFFUSE_H__ #define __BSDF_DISNEY_DIFFUSE_H__ +#include + CCL_NAMESPACE_BEGIN -/* DIFFUSE */ +/* DISNEY DIFFUSE */ + +ccl_device float diff_sqr(float a) { + return a * a; +} + +ccl_device float3 diff_mon2lin(float3 x, float gamma) { + return make_float3(pow(x[0], gamma), pow(x[1], gamma), pow(x[2], gamma)); +} + +ccl_device float diff_GTR1(float NdotH, float a) { + if (a >= 1.0f) return 1.0f / M_PI_F; + float a2 = a*a; + float t = 1.0f + (a2 - 1.0f) * NdotH * NdotH; + return (a2 - 1.0f) / (M_PI_F * log(a2) * t); +} + +ccl_device float diff_GTR2(float NdotH, float a) { + float a2 = a * a; + float t = 1.0f + (a2 - 1.0f) * NdotH * NdotH; + return a2 / (M_PI_F * t * t); +} + +ccl_device float diff_GTR2_aniso( + float NdotH, + float HdotX, + float HdotY, + float ax, + float ay) +{ + return 1.0f / (M_PI_F * ax * ay * diff_sqr(diff_sqr(HdotX / ax) + diff_sqr(HdotY / ay) + + NdotH * NdotH)); +} + +ccl_device float diff_smithG_GGX(float Ndotv, float alphaG) { + float a = alphaG * alphaG; + float b = Ndotv * Ndotv; + return 1.0f / (Ndotv + sqrtf(a + b - a * b)); +} + +ccl_device float diff_SchlickFresnel(float u) { + float m = clamp(1.0f - u, 0.0f, 1.0f); + float m2 = m * m; + return m2 * m2 * m; // pow(m, 5) +} + +ccl_device float3 diff_transform_to_local(const float3& v, const float3& n, + const float3& x, const float3& y) +{ + return make_float3(dot(v, x), dot(v, n), dot(v, y)); +} + +ccl_device float3 diff_mix(float3 x, float3 y, float a) { + return x * (1.0f - a) + y * a; +} + +ccl_device float diff_mix(float x, float y, float a) { + return x * (1.0f - a) + y * a; +} + +/* structures */ +struct DisneyDiffuseBRDFParams { + // brdf parameters + float3 m_base_color; + float m_subsurface; + float m_roughness; + float m_sheen; + float m_sheen_tint; + + // color correction + float m_withNdotL; + float m_brightness; + float m_gamma; + float m_exposure; + float m_mon2lingamma; + + // precomputed values + float3 m_cdlin, m_ctint, m_csheen; + float m_cdlum; + float m_weights[4]; + bool m_withNdotL_b; + + void precompute_values() { + m_cdlin = diff_mon2lin(m_base_color, m_mon2lingamma); //make_float3(1.0f, 0.795f, 0.0f)); + m_cdlum = 0.3f * m_cdlin[0] + 0.6f * m_cdlin[1] + 0.1f * m_cdlin[2]; // luminance approx. + + m_ctint = m_cdlum > 0.0f ? m_cdlin / m_cdlum : make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat + m_csheen = diff_mix(make_float3(1.0f, 1.0f, 1.0f), m_ctint, m_sheen_tint); + + m_gamma = clamp(m_gamma, 0.0f, 5.0f); + m_exposure = clamp(m_exposure, -6.0f, 6.0f); + m_withNdotL_b = (m_withNdotL > 0.5f); + } +}; + +typedef struct DisneyDiffuseBRDFParams DisneyDiffuseBRDFParams; + +/* brdf */ +ccl_device float3 calculate_disney_diffuse_brdf(const ShaderClosure *sc, + const DisneyDiffuseBRDFParams *params, float3 N, float3 V, float3 L, + float3 H, float *pdf) +{ + float NdotL = dot(N, L); + float NdotV = dot(N, V); + + if (NdotL < 0 || NdotV < 0) { + *pdf = 0.0f; + return make_float3(0.0f, 0.0f, 0.0f); + } + + float LdotH = dot(L, H); + + float Fd = 0.0f; + float FL = diff_SchlickFresnel(NdotL), FV = diff_SchlickFresnel(NdotV); + + if (params->m_subsurface != 1.0f) { + const float Fd90 = 0.5f + 2.0f * LdotH*LdotH * params->m_roughness; + Fd = diff_mix(1.0f, Fd90, FL) * diff_mix(1.0f, Fd90, FV); + } + + if (params->m_subsurface > 0.0f) { + float Fss90 = LdotH*LdotH * params->m_roughness; + float Fss = diff_mix(1.0f, Fss90, FL) * diff_mix(1.0f, Fss90, FV); + float ss = 1.25f * (Fss * (1.0f / (NdotL + NdotV) - 0.5f) + 0.5f); + Fd = diff_mix(Fd, ss, params->m_subsurface); + } + + float3 value = M_1_PI_F * Fd * params->m_cdlin; + *pdf = NdotL * M_1_PI_F * params->m_cdlum; + + // sheen component + if (params->m_sheen != 0.0f) { + float FH = diff_SchlickFresnel(LdotH); + + value += FH * params->m_sheen * params->m_csheen; + *pdf += (1.0f / M_2PI_F) * params->m_sheen; + } + + return value; +} ccl_device int bsdf_disney_diffuse_setup(ShaderClosure *sc) { @@ -44,46 +186,168 @@ ccl_device int bsdf_disney_diffuse_setup(ShaderClosure *sc) } ccl_device float3 bsdf_disney_diffuse_eval_reflect(const ShaderClosure *sc, - float3 color, const float3 I, const float3 omega_in, float *pdf) + const DisneyDiffuseBRDFParams *params, const float3 I, + const float3 omega_in, float *pdf) { - float3 N = sc->N; + float3 N = normalize(sc->N); + float3 V = I; // outgoing + float3 L = omega_in; // incoming + float3 H = normalize(L + V); - float cos_pi = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F; - *pdf = cos_pi; - return make_float3(cos_pi * color[0], cos_pi * color[1], cos_pi * color[2]); + if (dot(sc->N, omega_in) > 0.0f) { + float3 value = calculate_disney_diffuse_brdf(sc, params, N, V, L, H, pdf); + + value *= dot(N, L); + + // brightness + value *= params->m_brightness; + + // exposure + value *= pow(2.0f, params->m_exposure); + + // gamma + value[0] = pow(value[0], 1.0f / params->m_gamma); + value[1] = pow(value[1], 1.0f / params->m_gamma); + value[2] = pow(value[2], 1.0f / params->m_gamma); + + return value; + } + else { + *pdf = 0.0f; + return make_float3(0.0f, 0.0f, 0.0f); + } } -ccl_device float3 bsdf_disney_diffuse_eval_transmit(const ShaderClosure *sc, - float3 color, const float3 I, const float3 omega_in, float *pdf) +ccl_device float3 bsdf_disney_diffuse_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_diffuse_sample(const ShaderClosure *sc, float3 color, - 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) +ccl_device int bsdf_disney_diffuse_sample(const ShaderClosure *sc, const DisneyDiffuseBRDFParams *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) { - float3 N = sc->N; + float3 N = normalize(sc->N); - // distribution over the hemisphere - sample_cos_hemisphere(N, randu, randv, omega_in, pdf); + sample_uniform_hemisphere(N, randu, randv, omega_in, pdf); + + if (dot(Ng, *omega_in) > 0) { + float3 V = I; // outgoing + float3 L = *omega_in; // incoming + float3 H = normalize(L + V); + + float3 value = calculate_disney_diffuse_brdf(sc, params, N, V, L, H, pdf); + + if (params->m_withNdotL_b) + value *= dot(N, L); + + // brightness + value *= params->m_brightness; + + // exposure + value *= pow(2.0f, params->m_exposure); + + // gamma + value[0] = pow(value[0], 1.0f / params->m_gamma); + value[1] = pow(value[1], 1.0f / params->m_gamma); + value[2] = pow(value[2], 1.0f / params->m_gamma); + + *eval = make_float3(value[0], value[1], value[2]); - if(dot(Ng, *omega_in) > 0.0f) { - *eval = make_float3(*pdf * color[0], *pdf * color[1], *pdf * color[2]); #ifdef __RAY_DIFFERENTIALS__ // TODO: find a better approximation for the diffuse bounce - *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx; - *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy; + *domega_in_dx = -((2 * dot(N, dIdx)) * N - dIdx); + *domega_in_dy = -((2 * dot(N, dIdy)) * N - dIdy); #endif } - else - *pdf = 0.0f; + else { + *pdf = 0; + } - return LABEL_REFLECT|LABEL_DIFFUSE; + /*// we are viewing the surface from the right side - send a ray out with cosine + // distribution over the hemisphere + sample_cos_hemisphere(-N, randu, randv, omega_in, pdf); + if(dot(Ng, *omega_in) < 0) { + float3 H = normalize(*omega_in - I); + *eval = calculate_disney_diffuse_brdf(sc, params, -N, -I, *omega_in, H, pdf); + + // multiply with NdotL + //if (params->m_withNdotL_b) + // *eval *= dot(N, L); + + // brightness + *eval *= params->m_brightness; + + // exposure + *eval *= pow(2.0f, params->m_exposure); + + // gamma + (*eval)[0] = pow((*eval)[0], 1.0f / params->m_gamma); + (*eval)[1] = pow((*eval)[1], 1.0f / params->m_gamma); + (*eval)[2] = pow((*eval)[2], 1.0f / params->m_gamma); + //*eval = make_float3(*pdf, *pdf, *pdf); + +#ifdef __RAY_DIFFERENTIALS__ + // TODO: find a better approximation for the diffuse bounce + *domega_in_dx = -((2 * dot(N, dIdx)) * N - dIdx); + *domega_in_dy = -((2 * dot(N, dIdy)) * N - dIdy); +#endif + } + else { + *pdf = 0; + }*/ + return LABEL_DIFFUSE; + + /*float3 N = normalize(sc->N); + float3 T = normalize(sc->T); + float3 X, Y; + + float cos_theta, phi, theta, sin_phi, cos_phi; + + make_orthonormals_tangent(N, T, &X, &Y); + + phi = 2.0f * M_PI_F * randu; + theta = 2.0f * M_PI_F * randv; + cos_theta = cosf(theta); + sin_phi = sinf(phi); + cos_phi = cosf(phi); + + float sin_theta = sqrtf(fmaxf(0.0f, 1.0f - cos_theta * cos_theta)); + float3 H = normalize(sin_theta * cos_phi * X + sin_theta * sin_phi * Y + cos_theta * N); + + *omega_in = 2.0f * dot(I, H) * H - I; + + float3 V = I; // outgoing + float3 L = *omega_in; // incoming + + *eval = calculate_disney_diffuse_brdf(sc, params, N, V, L, H, pdf); + + // multiply with NdotL + //if (params->m_withNdotL_b) + // *eval *= dot(N, L); + + // brightness + *eval *= params->m_brightness; + + // exposure + *eval *= pow(2.0f, params->m_exposure); + + // gamma + (*eval)[0] = pow((*eval)[0], 1.0f / params->m_gamma); + (*eval)[1] = pow((*eval)[1], 1.0f / params->m_gamma); + (*eval)[2] = pow((*eval)[2], 1.0f / params->m_gamma); + +#ifdef __RAY_DIFFERENTIALS__ + *domega_in_dx = 2 * dot(N, dIdx) * N - dIdx; + *domega_in_dy = 2 * dot(N, dIdy) * N - dIdy; +#endif + + return LABEL_REFLECT|LABEL_DIFFUSE;*/ } CCL_NAMESPACE_END #endif /* __BSDF_DISNEY_DIFFUSE_H__ */ + diff --git a/intern/cycles/kernel/osl/bsdf_disney_diffuse.cpp b/intern/cycles/kernel/osl/bsdf_disney_diffuse.cpp index ba7d233759b..9c4433e47a0 100644 --- a/intern/cycles/kernel/osl/bsdf_disney_diffuse.cpp +++ b/intern/cycles/kernel/osl/bsdf_disney_diffuse.cpp @@ -47,7 +47,7 @@ using namespace OSL; class DisneyDiffuseClosure : public CBSDFClosure { public: - float3 color; + DisneyDiffuseBRDFParams dp; DisneyDiffuseClosure() : CBSDFClosure(LABEL_DIFFUSE) {} @@ -56,21 +56,22 @@ public: { sc.prim = this; m_shaderdata_flag = bsdf_disney_diffuse_setup(&sc); + + dp.precompute_values(); } void blur(float roughness) { - //bsdf_disney_diffuse_blur(&sc, roughness); } float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float& pdf) const { - return bsdf_disney_diffuse_eval_reflect(&sc, color, omega_out, omega_in, &pdf); + return bsdf_disney_diffuse_eval_reflect(&sc, &dp, omega_out, omega_in, &pdf); } float3 eval_transmit(const float3 &omega_out, const float3 &omega_in, float& pdf) const { - return bsdf_disney_diffuse_eval_transmit(&sc, color, omega_out, omega_in, &pdf); + return bsdf_disney_diffuse_eval_transmit(&sc, omega_out, omega_in, &pdf); } int sample(const float3 &Ng, @@ -79,7 +80,7 @@ public: float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy, float &pdf, float3 &eval) const { - return bsdf_disney_diffuse_sample(&sc, color, Ng, omega_out, domega_out_dx, domega_out_dy, + return bsdf_disney_diffuse_sample(&sc, &dp, Ng, omega_out, domega_out_dx, domega_out_dy, randu, randv, &eval, &omega_in, &domega_in_dx, &domega_in_dy, &pdf); } }; @@ -88,7 +89,16 @@ ClosureParam *closure_bsdf_disney_diffuse_params() { static ClosureParam params[] = { CLOSURE_FLOAT3_PARAM(DisneyDiffuseClosure, sc.N), - CLOSURE_FLOAT3_PARAM(DisneyDiffuseClosure, color), + CLOSURE_FLOAT3_PARAM(DisneyDiffuseClosure, dp.m_base_color), + CLOSURE_FLOAT_PARAM(DisneyDiffuseClosure, dp.m_subsurface), + CLOSURE_FLOAT_PARAM(DisneyDiffuseClosure, dp.m_roughness), + CLOSURE_FLOAT_PARAM(DisneyDiffuseClosure, dp.m_sheen), + CLOSURE_FLOAT_PARAM(DisneyDiffuseClosure, dp.m_sheen_tint), + CLOSURE_FLOAT_PARAM(DisneyDiffuseClosure, dp.m_withNdotL), + CLOSURE_FLOAT_PARAM(DisneyDiffuseClosure, dp.m_brightness), + CLOSURE_FLOAT_PARAM(DisneyDiffuseClosure, dp.m_gamma), + CLOSURE_FLOAT_PARAM(DisneyDiffuseClosure, dp.m_exposure), + CLOSURE_FLOAT_PARAM(DisneyDiffuseClosure, dp.m_mon2lingamma), CLOSURE_STRING_KEYPARAM(DisneyDiffuseClosure, label, "label"), CLOSURE_FINISH_PARAM(DisneyDiffuseClosure) }; diff --git a/intern/cycles/kernel/shaders/stdosl.h b/intern/cycles/kernel/shaders/stdosl.h index 83e8bc61c6c..01f391d8e30 100644 --- a/intern/cycles/kernel/shaders/stdosl.h +++ b/intern/cycles/kernel/shaders/stdosl.h @@ -536,7 +536,8 @@ closure color emission() BUILTIN; closure color background() BUILTIN; closure color holdout() BUILTIN; closure color ambient_occlusion() BUILTIN; -closure color disney_diffuse(normal N, color c) BUILTIN; +closure color disney_diffuse(normal N, color baseColor, float subsurface, float roughness, float sheen, + float sheenTint, float withNdotL, float brightness, float gamma, float exposure, float mon2lingamma) BUILTIN; // BSSRDF closure color bssrdf_cubic(normal N, vector radius, float texture_blur, float sharpness) BUILTIN; From 9f3d39744b85619750c79c901f678b8c07fe0ee2 Mon Sep 17 00:00:00 2001 From: Pascal Schoen Date: Fri, 29 Apr 2016 22:56:49 +0200 Subject: [PATCH 03/10] disney diffuse und specular implemented --- intern/cycles/kernel/CMakeLists.txt | 1 + intern/cycles/kernel/closure/bsdf.h | 1 + .../kernel/closure/bsdf_disney_diffuse.h | 159 ++-- .../kernel/closure/bsdf_disney_specular.h | 679 ++++++++++++++++++ intern/cycles/kernel/osl/CMakeLists.txt | 1 + .../kernel/osl/bsdf_disney_specular.cpp | 113 +++ intern/cycles/kernel/osl/osl_closures.cpp | 2 + intern/cycles/kernel/osl/osl_closures.h | 2 + intern/cycles/kernel/shaders/stdosl.h | 3 + intern/cycles/kernel/svm/svm_types.h | 1 + 10 files changed, 846 insertions(+), 116 deletions(-) create mode 100644 intern/cycles/kernel/closure/bsdf_disney_specular.h create mode 100644 intern/cycles/kernel/osl/bsdf_disney_specular.cpp diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index bf99b5c9a33..35e6c4f498c 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -88,6 +88,7 @@ set(SRC_CLOSURE_HEADERS closure/emissive.h closure/volume.h closure/bsdf_disney_diffuse.h + closure/bsdf_disney_specular.h ) set(SRC_SVM_HEADERS diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h index f40ed381ebb..b92a86461d7 100644 --- a/intern/cycles/kernel/closure/bsdf.h +++ b/intern/cycles/kernel/closure/bsdf.h @@ -27,6 +27,7 @@ #include "../closure/bsdf_toon.h" #include "../closure/bsdf_hair.h" #include "../closure/bsdf_disney_diffuse.h" +#include "../closure/bsdf_disney_specular.h" #ifdef __SUBSURFACE__ # include "../closure/bssrdf.h" #endif diff --git a/intern/cycles/kernel/closure/bsdf_disney_diffuse.h b/intern/cycles/kernel/closure/bsdf_disney_diffuse.h index ff69a7aa8ec..a35585d64d0 100644 --- a/intern/cycles/kernel/closure/bsdf_disney_diffuse.h +++ b/intern/cycles/kernel/closure/bsdf_disney_diffuse.h @@ -127,8 +127,8 @@ struct DisneyDiffuseBRDFParams { m_ctint = m_cdlum > 0.0f ? m_cdlin / m_cdlum : make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat m_csheen = diff_mix(make_float3(1.0f, 1.0f, 1.0f), m_ctint, m_sheen_tint); - m_gamma = clamp(m_gamma, 0.0f, 5.0f); - m_exposure = clamp(m_exposure, -6.0f, 6.0f); + //m_gamma = clamp(m_gamma, 0.0f, 5.0f); + //m_exposure = clamp(m_exposure, -6.0f, 6.0f); m_withNdotL_b = (m_withNdotL > 0.5f); } }; @@ -138,7 +138,7 @@ typedef struct DisneyDiffuseBRDFParams DisneyDiffuseBRDFParams; /* brdf */ ccl_device float3 calculate_disney_diffuse_brdf(const ShaderClosure *sc, const DisneyDiffuseBRDFParams *params, float3 N, float3 V, float3 L, - float3 H, float *pdf) + float3 H, float *pdf, bool withNdotL = true) { float NdotL = dot(N, L); float NdotV = dot(N, V); @@ -166,16 +166,47 @@ ccl_device float3 calculate_disney_diffuse_brdf(const ShaderClosure *sc, } float3 value = M_1_PI_F * Fd * params->m_cdlin; - *pdf = NdotL * M_1_PI_F * params->m_cdlum; + + //if (params->m_gamma > 0.5f) + *pdf = M_1_PI_F; + + /*if (params->m_exposure > 0.95f) + *pdf *= params->m_cdlum; + else if (params->m_exposure > 0.85f) + *pdf *= params->m_cdlum * NdotL; + else if (params->m_exposure > 0.75f) + *pdf *= params->m_cdlum * 0.5f; + else if (params->m_exposure > 0.65f) + *pdf *= params->m_cdlum * NdotL * 0.5f; + else if (params->m_exposure > 0.55f) + *pdf *= NdotL; + else if (params->m_exposure > 0.45f) + *pdf *= NdotL * 0.5f; + else if (params->m_exposure > 0.35f)*/ + *pdf *= 0.5f; // sheen component if (params->m_sheen != 0.0f) { float FH = diff_SchlickFresnel(LdotH); value += FH * params->m_sheen * params->m_csheen; - *pdf += (1.0f / M_2PI_F) * params->m_sheen; + //*pdf += 0.5f * M_1_PI_F * params->m_sheen; } + if (withNdotL) + value *= NdotL; + + // brightness + //value *= params->m_brightness; + + // exposure + //value *= pow(2.0f, params->m_exposure); + + // gamma + /*value[0] = pow(value[0], 1.0f / params->m_gamma); + value[1] = pow(value[1], 1.0f / params->m_gamma); + value[2] = pow(value[2], 1.0f / params->m_gamma);*/ + return value; } @@ -197,19 +228,6 @@ ccl_device float3 bsdf_disney_diffuse_eval_reflect(const ShaderClosure *sc, if (dot(sc->N, omega_in) > 0.0f) { float3 value = calculate_disney_diffuse_brdf(sc, params, N, V, L, H, pdf); - value *= dot(N, L); - - // brightness - value *= params->m_brightness; - - // exposure - value *= pow(2.0f, params->m_exposure); - - // gamma - value[0] = pow(value[0], 1.0f / params->m_gamma); - value[1] = pow(value[1], 1.0f / params->m_gamma); - value[2] = pow(value[2], 1.0f / params->m_gamma); - return value; } else { @@ -230,30 +248,18 @@ ccl_device int bsdf_disney_diffuse_sample(const ShaderClosure *sc, const DisneyD { float3 N = normalize(sc->N); - sample_uniform_hemisphere(N, randu, randv, omega_in, pdf); + /*if (params->m_brightness > 0.5f) + sample_cos_hemisphere(N, randu, randv, omega_in, pdf); + else*/ + sample_uniform_hemisphere(N, randu, randv, omega_in, pdf); if (dot(Ng, *omega_in) > 0) { float3 V = I; // outgoing float3 L = *omega_in; // incoming float3 H = normalize(L + V); - float3 value = calculate_disney_diffuse_brdf(sc, params, N, V, L, H, pdf); - - if (params->m_withNdotL_b) - value *= dot(N, L); - - // brightness - value *= params->m_brightness; - - // exposure - value *= pow(2.0f, params->m_exposure); - - // gamma - value[0] = pow(value[0], 1.0f / params->m_gamma); - value[1] = pow(value[1], 1.0f / params->m_gamma); - value[2] = pow(value[2], 1.0f / params->m_gamma); - - *eval = make_float3(value[0], value[1], value[2]); + float pon; + *eval = calculate_disney_diffuse_brdf(sc, params, N, V, L, H, pdf, true); #ifdef __RAY_DIFFERENTIALS__ // TODO: find a better approximation for the diffuse bounce @@ -264,86 +270,7 @@ ccl_device int bsdf_disney_diffuse_sample(const ShaderClosure *sc, const DisneyD else { *pdf = 0; } - - /*// we are viewing the surface from the right side - send a ray out with cosine - // distribution over the hemisphere - sample_cos_hemisphere(-N, randu, randv, omega_in, pdf); - if(dot(Ng, *omega_in) < 0) { - float3 H = normalize(*omega_in - I); - *eval = calculate_disney_diffuse_brdf(sc, params, -N, -I, *omega_in, H, pdf); - - // multiply with NdotL - //if (params->m_withNdotL_b) - // *eval *= dot(N, L); - - // brightness - *eval *= params->m_brightness; - - // exposure - *eval *= pow(2.0f, params->m_exposure); - - // gamma - (*eval)[0] = pow((*eval)[0], 1.0f / params->m_gamma); - (*eval)[1] = pow((*eval)[1], 1.0f / params->m_gamma); - (*eval)[2] = pow((*eval)[2], 1.0f / params->m_gamma); - //*eval = make_float3(*pdf, *pdf, *pdf); - -#ifdef __RAY_DIFFERENTIALS__ - // TODO: find a better approximation for the diffuse bounce - *domega_in_dx = -((2 * dot(N, dIdx)) * N - dIdx); - *domega_in_dy = -((2 * dot(N, dIdy)) * N - dIdy); -#endif - } - else { - *pdf = 0; - }*/ - return LABEL_DIFFUSE; - - /*float3 N = normalize(sc->N); - float3 T = normalize(sc->T); - float3 X, Y; - - float cos_theta, phi, theta, sin_phi, cos_phi; - - make_orthonormals_tangent(N, T, &X, &Y); - - phi = 2.0f * M_PI_F * randu; - theta = 2.0f * M_PI_F * randv; - cos_theta = cosf(theta); - sin_phi = sinf(phi); - cos_phi = cosf(phi); - - float sin_theta = sqrtf(fmaxf(0.0f, 1.0f - cos_theta * cos_theta)); - float3 H = normalize(sin_theta * cos_phi * X + sin_theta * sin_phi * Y + cos_theta * N); - - *omega_in = 2.0f * dot(I, H) * H - I; - - float3 V = I; // outgoing - float3 L = *omega_in; // incoming - - *eval = calculate_disney_diffuse_brdf(sc, params, N, V, L, H, pdf); - - // multiply with NdotL - //if (params->m_withNdotL_b) - // *eval *= dot(N, L); - - // brightness - *eval *= params->m_brightness; - - // exposure - *eval *= pow(2.0f, params->m_exposure); - - // gamma - (*eval)[0] = pow((*eval)[0], 1.0f / params->m_gamma); - (*eval)[1] = pow((*eval)[1], 1.0f / params->m_gamma); - (*eval)[2] = pow((*eval)[2], 1.0f / params->m_gamma); - -#ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = 2 * dot(N, dIdx) * N - dIdx; - *domega_in_dy = 2 * dot(N, dIdy) * N - dIdy; -#endif - - return LABEL_REFLECT|LABEL_DIFFUSE;*/ + return LABEL_REFLECT|LABEL_DIFFUSE; } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/closure/bsdf_disney_specular.h b/intern/cycles/kernel/closure/bsdf_disney_specular.h new file mode 100644 index 00000000000..5185bd5bfdc --- /dev/null +++ b/intern/cycles/kernel/closure/bsdf_disney_specular.h @@ -0,0 +1,679 @@ +/* + * 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_SPECULAR_H__ +#define __BSDF_DISNEY_SPECULAR_H__ + +#include + +CCL_NAMESPACE_BEGIN + +/* DISNEY SPECULAR */ + +ccl_device float spec_sqr(float a) { + return a * a; +} + +ccl_device float3 spec_mon2lin(float3 x, float gamma) { + return make_float3(pow(x[0], gamma), pow(x[1], gamma), pow(x[2], gamma)); +} + +ccl_device float spec_GTR1(float NdotH, float a) { + if (a >= 1.0f) return 1.0f / M_PI_F; + float a2 = a*a; + float t = 1.0f + (a2 - 1.0f) * NdotH * NdotH; + return (a2 - 1.0f) / (M_PI_F * log(a2) * t); +} + +ccl_device float spec_GTR2(float NdotH, float a) { + float a2 = a * a; + float t = 1.0f + (a2 - 1.0f) * NdotH * NdotH; + return a2 / (M_PI_F * t * t); +} + +ccl_device float spec_GTR2_aniso( + float NdotH, + float HdotX, + float HdotY, + float ax, + float ay) +{ + return 1.0f / (M_PI_F * ax * ay * spec_sqr(spec_sqr(HdotX / ax) + spec_sqr(HdotY / ay) + + NdotH * NdotH)); +} + +ccl_device float spec_smithG_GGX(float Ndotv, float alphaG) { + float a = alphaG * alphaG; + float b = Ndotv * Ndotv; + return 1.0f / (Ndotv + sqrtf(a + b - a * b)); +} + +ccl_device float spec_SchlickFresnel(float u) { + float m = clamp(1.0f - u, 0.0f, 1.0f); + float m2 = m * m; + return m2 * m2 * m; // pow(m, 5) +} + +ccl_device float3 spec_transform_to_local(const float3& v, const float3& n, + const float3& x, const float3& y) +{ + return make_float3(dot(v, x), dot(v, n), dot(v, y)); +} + +ccl_device float3 spec_mix(float3 x, float3 y, float a) { + return x * (1.0f - a) + y * a; +} + +ccl_device float spec_mix(float x, float y, float a) { + return x * (1.0f - a) + y * a; +} + +ccl_device float spec_max(float a, float b) { + if (a > b) return a; + else return b; +} + +/* structures */ +struct DisneySpecularBRDFParams { + // brdf parameters + float3 m_base_color; + float m_metallic; + float m_specular; + float m_specular_tint; + float m_roughness; + float m_anisotropic; + + // color correction + float m_withNdotL; + float m_brightness; + float m_gamma; + float m_exposure; + float m_mon2lingamma; + + // precomputed values + float3 m_cdlin, m_ctint, m_cspec0; + float m_cdlum; + float m_ax, m_ay; + float m_roughg; + bool m_withNdotL_b; + + void precompute_values() { + m_cdlin = spec_mon2lin(m_base_color, m_mon2lingamma); //make_float3(1.0f, 0.795f, 0.0f)); + m_cdlum = 0.3f * m_cdlin[0] + 0.6f * m_cdlin[1] + 0.1f * m_cdlin[2]; // luminance approx. + + m_ctint = m_cdlum > 0.0f ? m_cdlin / m_cdlum : make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat + + m_cspec0 = spec_mix(m_specular * 0.08f * spec_mix(make_float3(1.0f, 1.0f, 1.0f), + m_ctint, m_specular_tint), m_cdlin, m_metallic); + + float aspect = sqrt(1.0f - m_anisotropic * 0.9f); + m_ax = spec_max(0.001f, spec_sqr(m_roughness) / aspect); + m_ay = spec_max(0.001f, spec_sqr(m_roughness) * aspect); + + m_roughg = spec_sqr(m_roughness * 0.5f + 0.5f); + + //m_gamma = clamp(m_gamma, 0.0f, 5.0f); + //m_exposure = clamp(m_exposure, -6.0f, 6.0f); + m_withNdotL_b = (m_withNdotL != 0.0f); + } +}; + +typedef struct DisneySpecularBRDFParams DisneySpecularBRDFParams; + +/*brdf*/ +ccl_device float3 calculate_disney_specular_brdf(const ShaderClosure *sc, + const DisneySpecularBRDFParams *params, float3 N, float3 X, float3 Y, + float3 V, float3 L, float3 H, float *pdf, bool withNdotL = false) +{ + float NdotL = dot(N, L); + float NdotV = dot(N, V); + + if (NdotL < 0.0f || NdotV < 0.0f) { + *pdf = 0.0f; + return make_float3(0.0f, 0.0f, 0.0f); + } + + float NdotH = dot(N, H); + float LdotH = dot(L, H); + float FH = spec_SchlickFresnel(LdotH); + + float Ds; + if (params->m_anisotropic > 0.0f) + Ds = spec_GTR2_aniso(NdotH, dot(H, X), dot(H, Y), params->m_ax, params->m_ay); + else + Ds = spec_GTR2(NdotH, params->m_ax); + float3 Fs = spec_mix(params->m_cspec0, make_float3(1.0f, 1.0f, 1.0f), FH); + float Go = spec_smithG_GGX(NdotV, params->m_roughg); + float Gi = spec_smithG_GGX(NdotL, params->m_roughg); + float Gs = Go * Gi; + + float common = Go * Ds; + if (params->m_exposure > 0.5f) + common *= std::fabs(dot(V, H)) / spec_max(1e-6, NdotV); + else + common *= 0.25f / spec_max(1e-6, NdotV); + + *pdf = common; + /*if (params->m_withNdotL > 0.75f) + *pdf = spec_mix(*pdf, params->m_exposure, spec_SchlickFresnel(NdotV)); + else if (params->m_withNdotL > 0.5f) + *pdf = spec_mix(*pdf, params->m_exposure, spec_sqr(params->m_roughness)); + else if (params->m_withNdotL > 0.25f) + *pdf = spec_mix(spec_mix(*pdf, params->m_exposure, spec_sqr(params->m_roughness)), params->m_exposure, spec_SchlickFresnel(NdotV));*/ + + float3 value = Gs * Ds * Fs; + + if (withNdotL) + value *= NdotL; + + // brightness + //value *= params->m_brightness; + + // exposure + //value *= pow(2.f, params->m_exposure); + + // gamma + /*value[0] = pow(value[0], 1.f / params->m_gamma); + value[1] = pow(value[1], 1.f / params->m_gamma); + value[2] = pow(value[2], 1.f / params->m_gamma);*/ + + return value; +} + +ccl_device_inline void spec_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 = 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 spec_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; + + spec_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_specular_setup(ShaderClosure *sc) +{ + sc->type = CLOSURE_BSDF_DISNEY_SPECULAR_ID; + return SD_BSDF|SD_BSDF_HAS_EVAL; +} + +ccl_device float3 bsdf_disney_specular_eval_reflect(const ShaderClosure *sc, + const DisneySpecularBRDFParams *params, const float3 I, + const float3 omega_in, float *pdf) +{ + /*float3 N = normalize(sc->N); + float3 V = normalize(I); // outgoing + float3 L = normalize(omega_in); // incoming + float3 H = normalize(L + V); + + float3 T = normalize(sc->T); + float3 X, Y; + if (params->m_anisotropic > 0.0f) { + make_orthonormals_tangent(N, T, &X, &Y); + } + else { + make_orthonormals(N, &X, &Y); + } + + float3 value = calculate_disney_specular_brdf(sc, params, N, X, Y, V, L, H, pdf, params->m_withNdotL_b); + + return value;*/ + + float alpha_x = params->m_ax; + float alpha_y = params->m_ay; + float3 N = sc->N; + + if (fmaxf(alpha_x, alpha_y) <= 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_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) */ + //if (params->m_brightness > 0.5f) { + 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)); + /*} + else { + D = spec_GTR2(dot(N, m), params->m_ax); + }*/ + + /* eq. 34: now calculate G1(i,m) and G1(o,m) */ + //if (params->m_exposure > 0.5f) { + 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 { + G1o = spec_smithG_GGX(cosNO, params->m_roughg); + G1i = spec_smithG_GGX(cosNI, params->m_roughg); + }*/ + } + else { + /* anisotropic */ + float3 X, Y, Z = N; + make_orthonormals_tangent(Z, sc->T, &X, &Y); + + // distribution + //if (params->m_brightness > 0.5f) { + 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; + + float cosThetaM = local_m.z; + float cosThetaM2 = cosThetaM * cosThetaM; + float cosThetaM4 = cosThetaM2 * cosThetaM2; + + D = 1 / ((slope_len * slope_len) * M_PI_F * alpha2 * cosThetaM4); + /*} + else { + D = spec_GTR2_aniso(dot(N, m), dot(X, m), dot(Y, m), params->m_ax, params->m_ay); + }*/ + + /* G1(i,m) and G1(o,m) */ + //if (params->m_exposure > 0.5f) { + float tanThetaO2 = (1 - cosNO * cosNO) / (cosNO * cosNO); + float cosPhiO = dot(I, X); + float sinPhiO = dot(I, Y); + + float alphaO2 = (cosPhiO*cosPhiO)*(alpha_x*alpha_x) + (sinPhiO*sinPhiO)*(alpha_y*alpha_y); + alphaO2 /= cosPhiO*cosPhiO + sinPhiO*sinPhiO; + + G1o = 2 / (1 + safe_sqrtf(1 + alphaO2 * tanThetaO2)); + + float tanThetaI2 = (1 - cosNI * cosNI) / (cosNI * cosNI); + float cosPhiI = dot(omega_in, X); + float sinPhiI = dot(omega_in, Y); + + float alphaI2 = (cosPhiI*cosPhiI)*(alpha_x*alpha_x) + (sinPhiI*sinPhiI)*(alpha_y*alpha_y); + alphaI2 /= cosPhiI*cosPhiI + sinPhiI*sinPhiI; + + G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2)); + /*} + else { + G1o = spec_smithG_GGX(cosNO, params->m_roughg); + G1i = spec_smithG_GGX(cosNI, params->m_roughg); + }*/ + } + + float G = G1o * G1i; + + /* eq. 20 */ + float common = D * 0.25f / cosNO; + + float FH = spec_SchlickFresnel(dot(omega_in, m)); + float3 F = spec_mix(params->m_cspec0, make_float3(1.0f, 1.0f, 1.0f), FH); + + float3 out = F * G * common; + + /* 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_specular_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 void importance_sample_ggx_aniso(float3 N, float u, float v, float3 *omega_in, + float ax, float ay, float3 TangentX, float3 TangentY, float *pdf) +{ + float a = sqrt(v) / sqrt(1 - v); + + float Phi = 2.0f * M_PI_F * u; + + float3 H; + H.x = ax * a * cos(Phi); + H.y = ay * a * sin(Phi); + H.z = 1.0f; + + *omega_in = normalize(TangentX * H.x + TangentY * H.y + N * H.z); + + float CosTheta = sqrt(1.0f - (ax * a) * (ax * a) - (ay * a) * (ay * a)); + *pdf = CosTheta * M_1_PI_F; +} + +ccl_device void importance_sample_ggx(float3 N, float u, float v, float3 *omega_in, + float Roughness, float3 TangentX, float3 TangentY, float *pdf) +{ + float a = Roughness * Roughness; + + float Phi = 2.0f * M_PI_F * u; + float CosTheta = sqrt((1.0f - v) / (1.0f + (a*a - 1.0f) * v)); + float SinTheta = sqrt(1.0f - CosTheta * CosTheta); + + float3 H; + H.x = SinTheta * cos(Phi); + H.y = SinTheta * sin(Phi); + H.z = CosTheta; + + // Tangent to world space + *omega_in = normalize(TangentX * H.x + TangentY * H.y + N * H.z); + *pdf = CosTheta * M_1_PI_F; +} + +ccl_device int bsdf_disney_specular_sample(const ShaderClosure *sc, const DisneySpecularBRDFParams *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) +{ + /*float3 N = normalize(sc->N); + float3 T = normalize(sc->T); + float3 X, Y; + if (params->m_anisotropic > 0.0f) + make_orthonormals_tangent(N, T, &X, &Y); + else + make_orthonormals(N, &X, &Y); + + float3 R = -I - 2.0f * dot(-I, N) * N; + + float3 H; + if (params->m_brightness <= 0.5f) { + if (params->m_anisotropic > 0.0f) + importance_sample_ggx_aniso(R, randu, randv, omega_in, params->m_ax, params->m_ay, X, Y, pdf); + else + importance_sample_ggx(R, randu, randv, omega_in, params->m_roughness, X, Y, pdf); + H = normalize(I + *omega_in); + } + else { + if (params->m_anisotropic > 0.0f) + importance_sample_ggx_aniso(N, randu, randv, &H, params->m_ax, params->m_ay, X, Y, pdf); + else + importance_sample_ggx(N, randu, randv, &H, params->m_roughness, X, Y, pdf); + *omega_in = -I - 2.0f * dot(-I, H) * H; + } + + if (params->m_brightness > 0.2f && params->m_brightness < 0.8f) { + if (dot(Ng, *omega_in) < 0.0f) { + *omega_in = -(*omega_in) - 2.0f * dot(-(*omega_in), R) * R; + H = normalize(*omega_in + I); + } + } + + if (dot(Ng, *omega_in) > 0.0f) { + float3 V = I; // outgoing + float3 L = *omega_in; // incoming + + *eval = calculate_disney_specular_brdf(sc, params, N, X, Y, V, L, H, pdf, params->m_withNdotL > 0.75f); + +#ifdef __RAY_DIFFERENTIALS__ + *domega_in_dx = 2 * dot(H, dIdx) * H - dIdx; + *domega_in_dy = 2 * dot(H, dIdy) * H - dIdy; +#endif + } + else { + *pdf = 0.0f; + *eval = make_float3(0.0f, 0.0f, 0.0f); + } + + return LABEL_REFLECT|LABEL_GLOSSY;*/ + + float alpha_x = params->m_ax; + float alpha_y = params->m_ay; + float3 N = sc->N; + + float cosNO = dot(N, I); + if(cosNO > 0) { + float3 X, Y, Z = N; + + if(alpha_x == alpha_y) + make_orthonormals(Z, &X, &Y); + else + make_orthonormals_tangent(Z, sc->T, &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; + + //if (params->m_exposure > 0.5f) { + local_m = spec_microfacet_sample_stretched(local_I, alpha_x, alpha_y, + randu, randv, false, &G1o); + + m = X*local_m.x + Y*local_m.y + Z*local_m.z; + /*} + else { + importance_sample_ggx_aniso(N, randu, randv, &m, alpha_x, alpha_y, X, Y, pdf); + local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m)); + }*/ + 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(fmaxf(alpha_x, alpha_y) <= 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_x * alpha_y; + float D, G1i; + + if(alpha_x == alpha_y) { + /* isotropic */ + //if (params->m_brightness > 0.5f) { + float cosThetaM2 = cosThetaM * cosThetaM; + float cosThetaM4 = cosThetaM2 * cosThetaM2; + float tanThetaM2 = 1/(cosThetaM2) - 1; + D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); + /*} + else { + D = spec_GTR2(dot(N, m), params->m_ax); + }*/ + + /* eval BRDF*cosNI */ + float cosNI = dot(N, *omega_in); + + /* eq. 34: now calculate G1(i,m) */ + //if (params->m_exposure > 0.5f) { + G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); + /*} + else { + G1i = spec_smithG_GGX(cosNI, params->m_roughg); + G1o = spec_smithG_GGX(cosNO, params->m_roughg); + }*/ + } + else { + /* anisotropic distribution */ + //if (params->m_brightness > 0.5f) { + //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; + + float cosThetaM = local_m.z; + float cosThetaM2 = cosThetaM * cosThetaM; + float cosThetaM4 = cosThetaM2 * cosThetaM2; + + D = 1 / ((slope_len * slope_len) * M_PI_F * alpha2 * cosThetaM4); + /*} + else { + D = spec_GTR2_aniso(dot(N, m), dot(X, m), dot(Y, m), params->m_ax, params->m_ay); + }*/ + + /* calculate G1(i,m) */ + float cosNI = dot(N, *omega_in); + + //if (params->m_exposure > 0.5f) { + float tanThetaI2 = (1 - cosNI * cosNI) / (cosNI * cosNI); + float cosPhiI = dot(*omega_in, X); + float sinPhiI = dot(*omega_in, Y); + + float alphaI2 = (cosPhiI*cosPhiI)*(alpha_x*alpha_x) + (sinPhiI*sinPhiI)*(alpha_y*alpha_y); + alphaI2 /= cosPhiI*cosPhiI + sinPhiI*sinPhiI; + + G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2)); + /*} + else { + G1i = spec_smithG_GGX(cosNI, params->m_roughg); + G1o = spec_smithG_GGX(cosNO, params->m_roughg); + }*/ + } + + /* see eval function for derivation */ + float common = (G1o * D) * 0.25f / cosNO; + *pdf = common; + + float FH = spec_SchlickFresnel(dot(*omega_in, m)); + float3 F = spec_mix(params->m_cspec0, make_float3(1.0f, 1.0f, 1.0f), FH); + + *eval = G1i * common * F; + } + +#ifdef __RAY_DIFFERENTIALS__ + *domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx; + *domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy; +#endif + } + } + } + + return LABEL_REFLECT|LABEL_GLOSSY; +} + +CCL_NAMESPACE_END + +#endif /* __BSDF_DISNEY_SPECULAR_H__ */ + diff --git a/intern/cycles/kernel/osl/CMakeLists.txt b/intern/cycles/kernel/osl/CMakeLists.txt index d48aeef3bb2..492e06a3398 100644 --- a/intern/cycles/kernel/osl/CMakeLists.txt +++ b/intern/cycles/kernel/osl/CMakeLists.txt @@ -22,6 +22,7 @@ set(SRC osl_services.cpp osl_shader.cpp bsdf_disney_diffuse.cpp + bsdf_disney_specular.cpp ) set(HEADER_SRC diff --git a/intern/cycles/kernel/osl/bsdf_disney_specular.cpp b/intern/cycles/kernel/osl/bsdf_disney_specular.cpp new file mode 100644 index 00000000000..b19c52b5c1d --- /dev/null +++ b/intern/cycles/kernel/osl/bsdf_disney_specular.cpp @@ -0,0 +1,113 @@ +/* + * 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. + */ + +#include + +#include + +#include "kernel_compat_cpu.h" +#include "osl_closures.h" + +#include "kernel_types.h" +#include "kernel_montecarlo.h" +#include "closure/bsdf_disney_specular.h" + +CCL_NAMESPACE_BEGIN + +using namespace OSL; + +class DisneySpecularClosure : public CBSDFClosure { +public: + DisneySpecularBRDFParams dp; + + DisneySpecularClosure() : CBSDFClosure(LABEL_REFLECT|LABEL_GLOSSY) + {} + + void setup() + { + sc.prim = this; + m_shaderdata_flag = bsdf_disney_specular_setup(&sc); + + dp.precompute_values(); + } + + void blur(float roughness) + { + } + + float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float& pdf) const + { + return bsdf_disney_specular_eval_reflect(&sc, &dp, omega_out, omega_in, &pdf); + } + + float3 eval_transmit(const float3 &omega_out, const float3 &omega_in, float& pdf) const + { + return bsdf_disney_specular_eval_transmit(&sc, omega_out, omega_in, &pdf); + } + + int sample(const float3 &Ng, + const float3 &omega_out, const float3 &domega_out_dx, const float3 &domega_out_dy, + float randu, float randv, + float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy, + float &pdf, float3 &eval) const + { + return bsdf_disney_specular_sample(&sc, &dp, Ng, omega_out, domega_out_dx, domega_out_dy, + randu, randv, &eval, &omega_in, &domega_in_dx, &domega_in_dy, &pdf); + } +}; + +ClosureParam *closure_bsdf_disney_specular_params() +{ + static ClosureParam params[] = { + CLOSURE_FLOAT3_PARAM(DisneySpecularClosure, sc.N), + CLOSURE_FLOAT3_PARAM(DisneySpecularClosure, sc.T), + CLOSURE_FLOAT3_PARAM(DisneySpecularClosure, dp.m_base_color), + CLOSURE_FLOAT_PARAM(DisneySpecularClosure, dp.m_metallic), + CLOSURE_FLOAT_PARAM(DisneySpecularClosure, dp.m_specular), + CLOSURE_FLOAT_PARAM(DisneySpecularClosure, dp.m_specular_tint), + CLOSURE_FLOAT_PARAM(DisneySpecularClosure, dp.m_roughness), + CLOSURE_FLOAT_PARAM(DisneySpecularClosure, dp.m_anisotropic), + CLOSURE_FLOAT_PARAM(DisneySpecularClosure, dp.m_withNdotL), + CLOSURE_FLOAT_PARAM(DisneySpecularClosure, dp.m_brightness), + CLOSURE_FLOAT_PARAM(DisneySpecularClosure, dp.m_gamma), + CLOSURE_FLOAT_PARAM(DisneySpecularClosure, dp.m_exposure), + CLOSURE_FLOAT_PARAM(DisneySpecularClosure, dp.m_mon2lingamma), + CLOSURE_STRING_KEYPARAM(DisneySpecularClosure, label, "label"), + CLOSURE_FINISH_PARAM(DisneySpecularClosure) + }; + return params; +} + +CCLOSURE_PREPARE(closure_bsdf_disney_specular_prepare, DisneySpecularClosure) + +CCL_NAMESPACE_END + diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp index 5e311f7e4d6..c8f82b527bb 100644 --- a/intern/cycles/kernel/osl/osl_closures.cpp +++ b/intern/cycles/kernel/osl/osl_closures.cpp @@ -240,6 +240,8 @@ void OSLShader::register_closures(OSLShadingSystem *ss_) closure_bssrdf_burley_params(), closure_bssrdf_burley_prepare); register_closure(ss, "disney_diffuse", id++, closure_bsdf_disney_diffuse_params(), closure_bsdf_disney_diffuse_prepare); + register_closure(ss, "disney_specular", id++, + closure_bsdf_disney_specular_params(), closure_bsdf_disney_specular_prepare); register_closure(ss, "hair_reflection", id++, bsdf_hair_reflection_params(), bsdf_hair_reflection_prepare); diff --git a/intern/cycles/kernel/osl/osl_closures.h b/intern/cycles/kernel/osl/osl_closures.h index 45c0b51783e..e580663d305 100644 --- a/intern/cycles/kernel/osl/osl_closures.h +++ b/intern/cycles/kernel/osl/osl_closures.h @@ -53,6 +53,7 @@ OSL::ClosureParam *closure_bssrdf_gaussian_params(); OSL::ClosureParam *closure_bssrdf_burley_params(); OSL::ClosureParam *closure_henyey_greenstein_volume_params(); OSL::ClosureParam *closure_bsdf_disney_diffuse_params(); +OSL::ClosureParam *closure_bsdf_disney_specular_params(); void closure_emission_prepare(OSL::RendererServices *, int id, void *data); void closure_background_prepare(OSL::RendererServices *, int id, void *data); @@ -65,6 +66,7 @@ void closure_bssrdf_gaussian_prepare(OSL::RendererServices *, int id, void *data void closure_bssrdf_burley_prepare(OSL::RendererServices *, int id, void *data); void closure_henyey_greenstein_volume_prepare(OSL::RendererServices *, int id, void *data); void closure_bsdf_disney_diffuse_prepare(OSL::RendererServices *, int id, void *data); +void closure_bsdf_disney_specular_prepare(OSL::RendererServices *, int id, void *data); #define CCLOSURE_PREPARE(name, classname) \ void name(RendererServices *, int id, void *data) \ diff --git a/intern/cycles/kernel/shaders/stdosl.h b/intern/cycles/kernel/shaders/stdosl.h index 01f391d8e30..af9ecdd7126 100644 --- a/intern/cycles/kernel/shaders/stdosl.h +++ b/intern/cycles/kernel/shaders/stdosl.h @@ -538,6 +538,9 @@ closure color holdout() BUILTIN; closure color ambient_occlusion() BUILTIN; closure color disney_diffuse(normal N, color baseColor, float subsurface, float roughness, float sheen, float sheenTint, float withNdotL, float brightness, float gamma, float exposure, float mon2lingamma) BUILTIN; +closure color disney_specular(normal N, normal T, color baseColor, float metallic, float specular, float specularTint, + float roughness, float anisotropic, float withNdotL, float brightness, float gamma, float exposure, + float mon2lingamma) BUILTIN; // BSSRDF closure color bssrdf_cubic(normal N, vector radius, float texture_blur, float sharpness) BUILTIN; diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index c3999eaff4e..04a4eaf8ec5 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -392,6 +392,7 @@ typedef enum ClosureType { CLOSURE_BSDF_PHONG_RAMP_ID, CLOSURE_BSDF_GLOSSY_TOON_ID, CLOSURE_BSDF_HAIR_REFLECTION_ID, + CLOSURE_BSDF_DISNEY_SPECULAR_ID, /* Transmission */ CLOSURE_BSDF_TRANSMISSION_ID, From 0630b742d71c658915575a4a71a325094a0fc313 Mon Sep 17 00:00:00 2001 From: Pascal Schoen Date: Tue, 3 May 2016 16:54:49 +0200 Subject: [PATCH 04/10] added clearcoat implementation --- intern/cycles/kernel/CMakeLists.txt | 1 + intern/cycles/kernel/closure/bsdf.h | 1 + .../kernel/closure/bsdf_disney_clearcoat.h | 312 +++++++++++++++++ .../kernel/closure/bsdf_disney_diffuse.h | 15 +- .../kernel/closure/bsdf_disney_specular.h | 327 +++--------------- intern/cycles/kernel/osl/CMakeLists.txt | 1 + .../kernel/osl/bsdf_disney_clearcoat.cpp | 103 ++++++ .../cycles/kernel/osl/bsdf_disney_diffuse.cpp | 5 - .../kernel/osl/bsdf_disney_specular.cpp | 5 - intern/cycles/kernel/osl/osl_closures.cpp | 2 + intern/cycles/kernel/osl/osl_closures.h | 2 + intern/cycles/kernel/shaders/stdosl.h | 6 +- intern/cycles/kernel/svm/svm_types.h | 1 + 13 files changed, 476 insertions(+), 305 deletions(-) create mode 100644 intern/cycles/kernel/closure/bsdf_disney_clearcoat.h create mode 100644 intern/cycles/kernel/osl/bsdf_disney_clearcoat.cpp diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index 35e6c4f498c..6695b2fb9d6 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -89,6 +89,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 b92a86461d7..7d4b8bd6316 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 00000000000..6d09cb0d140 --- /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 cosNI = dot(N, *omega_in); + + /* eq. 34: now calculate G1(i,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))); + + /* see eval function for derivation */ + float common = (G1o * D) * 0.25f / cosNO; + *pdf = common; + + 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); + + *eval = G1i * common * F * 0.25f * params->m_clearcoat; + } + +#ifdef __RAY_DIFFERENTIALS__ + *domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx; + *domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy; +#endif + } + } + } + } + + return LABEL_REFLECT|LABEL_GLOSSY; +} + +CCL_NAMESPACE_END + +#endif /* __BSDF_DISNEY_CLEARCOAT_H__ */ + diff --git a/intern/cycles/kernel/closure/bsdf_disney_diffuse.h b/intern/cycles/kernel/closure/bsdf_disney_diffuse.h index a35585d64d0..fa4b17ce011 100644 --- a/intern/cycles/kernel/closure/bsdf_disney_diffuse.h +++ b/intern/cycles/kernel/closure/bsdf_disney_diffuse.h @@ -107,29 +107,17 @@ struct DisneyDiffuseBRDFParams { float m_sheen; float m_sheen_tint; - // color correction - float m_withNdotL; - float m_brightness; - float m_gamma; - float m_exposure; - float m_mon2lingamma; - // precomputed values float3 m_cdlin, m_ctint, m_csheen; float m_cdlum; float m_weights[4]; - bool m_withNdotL_b; void precompute_values() { - m_cdlin = diff_mon2lin(m_base_color, m_mon2lingamma); //make_float3(1.0f, 0.795f, 0.0f)); + m_cdlin = m_base_color; m_cdlum = 0.3f * m_cdlin[0] + 0.6f * m_cdlin[1] + 0.1f * m_cdlin[2]; // luminance approx. m_ctint = m_cdlum > 0.0f ? m_cdlin / m_cdlum : make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat m_csheen = diff_mix(make_float3(1.0f, 1.0f, 1.0f), m_ctint, m_sheen_tint); - - //m_gamma = clamp(m_gamma, 0.0f, 5.0f); - //m_exposure = clamp(m_exposure, -6.0f, 6.0f); - m_withNdotL_b = (m_withNdotL > 0.5f); } }; @@ -258,7 +246,6 @@ ccl_device int bsdf_disney_diffuse_sample(const ShaderClosure *sc, const DisneyD float3 L = *omega_in; // incoming float3 H = normalize(L + V); - float pon; *eval = calculate_disney_diffuse_brdf(sc, params, N, V, L, H, pdf, true); #ifdef __RAY_DIFFERENTIALS__ diff --git a/intern/cycles/kernel/closure/bsdf_disney_specular.h b/intern/cycles/kernel/closure/bsdf_disney_specular.h index 5185bd5bfdc..c5c6c2e72b5 100644 --- a/intern/cycles/kernel/closure/bsdf_disney_specular.h +++ b/intern/cycles/kernel/closure/bsdf_disney_specular.h @@ -112,22 +112,14 @@ struct DisneySpecularBRDFParams { float m_roughness; float m_anisotropic; - // color correction - float m_withNdotL; - float m_brightness; - float m_gamma; - float m_exposure; - float m_mon2lingamma; - // precomputed values float3 m_cdlin, m_ctint, m_cspec0; float m_cdlum; float m_ax, m_ay; float m_roughg; - bool m_withNdotL_b; void precompute_values() { - m_cdlin = spec_mon2lin(m_base_color, m_mon2lingamma); //make_float3(1.0f, 0.795f, 0.0f)); + m_cdlin = m_base_color; m_cdlum = 0.3f * m_cdlin[0] + 0.6f * m_cdlin[1] + 0.1f * m_cdlin[2]; // luminance approx. m_ctint = m_cdlum > 0.0f ? m_cdlin / m_cdlum : make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat @@ -140,74 +132,11 @@ struct DisneySpecularBRDFParams { m_ay = spec_max(0.001f, spec_sqr(m_roughness) * aspect); m_roughg = spec_sqr(m_roughness * 0.5f + 0.5f); - - //m_gamma = clamp(m_gamma, 0.0f, 5.0f); - //m_exposure = clamp(m_exposure, -6.0f, 6.0f); - m_withNdotL_b = (m_withNdotL != 0.0f); } }; typedef struct DisneySpecularBRDFParams DisneySpecularBRDFParams; -/*brdf*/ -ccl_device float3 calculate_disney_specular_brdf(const ShaderClosure *sc, - const DisneySpecularBRDFParams *params, float3 N, float3 X, float3 Y, - float3 V, float3 L, float3 H, float *pdf, bool withNdotL = false) -{ - float NdotL = dot(N, L); - float NdotV = dot(N, V); - - if (NdotL < 0.0f || NdotV < 0.0f) { - *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); - } - - float NdotH = dot(N, H); - float LdotH = dot(L, H); - float FH = spec_SchlickFresnel(LdotH); - - float Ds; - if (params->m_anisotropic > 0.0f) - Ds = spec_GTR2_aniso(NdotH, dot(H, X), dot(H, Y), params->m_ax, params->m_ay); - else - Ds = spec_GTR2(NdotH, params->m_ax); - float3 Fs = spec_mix(params->m_cspec0, make_float3(1.0f, 1.0f, 1.0f), FH); - float Go = spec_smithG_GGX(NdotV, params->m_roughg); - float Gi = spec_smithG_GGX(NdotL, params->m_roughg); - float Gs = Go * Gi; - - float common = Go * Ds; - if (params->m_exposure > 0.5f) - common *= std::fabs(dot(V, H)) / spec_max(1e-6, NdotV); - else - common *= 0.25f / spec_max(1e-6, NdotV); - - *pdf = common; - /*if (params->m_withNdotL > 0.75f) - *pdf = spec_mix(*pdf, params->m_exposure, spec_SchlickFresnel(NdotV)); - else if (params->m_withNdotL > 0.5f) - *pdf = spec_mix(*pdf, params->m_exposure, spec_sqr(params->m_roughness)); - else if (params->m_withNdotL > 0.25f) - *pdf = spec_mix(spec_mix(*pdf, params->m_exposure, spec_sqr(params->m_roughness)), params->m_exposure, spec_SchlickFresnel(NdotV));*/ - - float3 value = Gs * Ds * Fs; - - if (withNdotL) - value *= NdotL; - - // brightness - //value *= params->m_brightness; - - // exposure - //value *= pow(2.f, params->m_exposure); - - // gamma - /*value[0] = pow(value[0], 1.f / params->m_gamma); - value[1] = pow(value[1], 1.f / params->m_gamma); - value[2] = pow(value[2], 1.f / params->m_gamma);*/ - - return value; -} ccl_device_inline void spec_microfacet_ggx_sample_slopes( const float cos_theta_i, const float sin_theta_i, @@ -311,24 +240,6 @@ ccl_device float3 bsdf_disney_specular_eval_reflect(const ShaderClosure *sc, const DisneySpecularBRDFParams *params, const float3 I, const float3 omega_in, float *pdf) { - /*float3 N = normalize(sc->N); - float3 V = normalize(I); // outgoing - float3 L = normalize(omega_in); // incoming - float3 H = normalize(L + V); - - float3 T = normalize(sc->T); - float3 X, Y; - if (params->m_anisotropic > 0.0f) { - make_orthonormals_tangent(N, T, &X, &Y); - } - else { - make_orthonormals(N, &X, &Y); - } - - float3 value = calculate_disney_specular_brdf(sc, params, N, X, Y, V, L, H, pdf, params->m_withNdotL_b); - - return value;*/ - float alpha_x = params->m_ax; float alpha_y = params->m_ay; float3 N = sc->N; @@ -349,26 +260,15 @@ ccl_device float3 bsdf_disney_specular_eval_reflect(const ShaderClosure *sc, /* isotropic * eq. 20: (F*G*D)/(4*in*on) * eq. 33: first we calculate D(m) */ - //if (params->m_brightness > 0.5f) { - 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)); - /*} - else { - D = spec_GTR2(dot(N, m), params->m_ax); - }*/ + 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)); /* eq. 34: now calculate G1(i,m) and G1(o,m) */ - //if (params->m_exposure > 0.5f) { - 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 { - G1o = spec_smithG_GGX(cosNO, params->m_roughg); - G1i = spec_smithG_GGX(cosNI, params->m_roughg); - }*/ + 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 */ @@ -376,46 +276,35 @@ ccl_device float3 bsdf_disney_specular_eval_reflect(const ShaderClosure *sc, make_orthonormals_tangent(Z, sc->T, &X, &Y); // distribution - //if (params->m_brightness > 0.5f) { - 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; + 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; - float cosThetaM = local_m.z; - float cosThetaM2 = cosThetaM * cosThetaM; - float cosThetaM4 = cosThetaM2 * cosThetaM2; + float cosThetaM = local_m.z; + float cosThetaM2 = cosThetaM * cosThetaM; + float cosThetaM4 = cosThetaM2 * cosThetaM2; - D = 1 / ((slope_len * slope_len) * M_PI_F * alpha2 * cosThetaM4); - /*} - else { - D = spec_GTR2_aniso(dot(N, m), dot(X, m), dot(Y, m), params->m_ax, params->m_ay); - }*/ + D = 1 / ((slope_len * slope_len) * M_PI_F * alpha2 * cosThetaM4); /* G1(i,m) and G1(o,m) */ - //if (params->m_exposure > 0.5f) { - float tanThetaO2 = (1 - cosNO * cosNO) / (cosNO * cosNO); - float cosPhiO = dot(I, X); - float sinPhiO = dot(I, Y); + float tanThetaO2 = (1 - cosNO * cosNO) / (cosNO * cosNO); + float cosPhiO = dot(I, X); + float sinPhiO = dot(I, Y); - float alphaO2 = (cosPhiO*cosPhiO)*(alpha_x*alpha_x) + (sinPhiO*sinPhiO)*(alpha_y*alpha_y); - alphaO2 /= cosPhiO*cosPhiO + sinPhiO*sinPhiO; + float alphaO2 = (cosPhiO*cosPhiO)*(alpha_x*alpha_x) + (sinPhiO*sinPhiO)*(alpha_y*alpha_y); + alphaO2 /= cosPhiO*cosPhiO + sinPhiO*sinPhiO; - G1o = 2 / (1 + safe_sqrtf(1 + alphaO2 * tanThetaO2)); + G1o = 2 / (1 + safe_sqrtf(1 + alphaO2 * tanThetaO2)); - float tanThetaI2 = (1 - cosNI * cosNI) / (cosNI * cosNI); - float cosPhiI = dot(omega_in, X); - float sinPhiI = dot(omega_in, Y); + float tanThetaI2 = (1 - cosNI * cosNI) / (cosNI * cosNI); + float cosPhiI = dot(omega_in, X); + float sinPhiI = dot(omega_in, Y); - float alphaI2 = (cosPhiI*cosPhiI)*(alpha_x*alpha_x) + (sinPhiI*sinPhiI)*(alpha_y*alpha_y); - alphaI2 /= cosPhiI*cosPhiI + sinPhiI*sinPhiI; + float alphaI2 = (cosPhiI*cosPhiI)*(alpha_x*alpha_x) + (sinPhiI*sinPhiI)*(alpha_y*alpha_y); + alphaI2 /= cosPhiI*cosPhiI + sinPhiI*sinPhiI; - G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2)); - /*} - else { - G1o = spec_smithG_GGX(cosNO, params->m_roughg); - G1i = spec_smithG_GGX(cosNI, params->m_roughg); - }*/ + G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2)); } float G = G1o * G1i; @@ -447,99 +336,11 @@ ccl_device float3 bsdf_disney_specular_eval_transmit(const ShaderClosure *sc, co return make_float3(0.0f, 0.0f, 0.0f); } -ccl_device void importance_sample_ggx_aniso(float3 N, float u, float v, float3 *omega_in, - float ax, float ay, float3 TangentX, float3 TangentY, float *pdf) -{ - float a = sqrt(v) / sqrt(1 - v); - - float Phi = 2.0f * M_PI_F * u; - - float3 H; - H.x = ax * a * cos(Phi); - H.y = ay * a * sin(Phi); - H.z = 1.0f; - - *omega_in = normalize(TangentX * H.x + TangentY * H.y + N * H.z); - - float CosTheta = sqrt(1.0f - (ax * a) * (ax * a) - (ay * a) * (ay * a)); - *pdf = CosTheta * M_1_PI_F; -} - -ccl_device void importance_sample_ggx(float3 N, float u, float v, float3 *omega_in, - float Roughness, float3 TangentX, float3 TangentY, float *pdf) -{ - float a = Roughness * Roughness; - - float Phi = 2.0f * M_PI_F * u; - float CosTheta = sqrt((1.0f - v) / (1.0f + (a*a - 1.0f) * v)); - float SinTheta = sqrt(1.0f - CosTheta * CosTheta); - - float3 H; - H.x = SinTheta * cos(Phi); - H.y = SinTheta * sin(Phi); - H.z = CosTheta; - - // Tangent to world space - *omega_in = normalize(TangentX * H.x + TangentY * H.y + N * H.z); - *pdf = CosTheta * M_1_PI_F; -} - ccl_device int bsdf_disney_specular_sample(const ShaderClosure *sc, const DisneySpecularBRDFParams *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) { - /*float3 N = normalize(sc->N); - float3 T = normalize(sc->T); - float3 X, Y; - if (params->m_anisotropic > 0.0f) - make_orthonormals_tangent(N, T, &X, &Y); - else - make_orthonormals(N, &X, &Y); - - float3 R = -I - 2.0f * dot(-I, N) * N; - - float3 H; - if (params->m_brightness <= 0.5f) { - if (params->m_anisotropic > 0.0f) - importance_sample_ggx_aniso(R, randu, randv, omega_in, params->m_ax, params->m_ay, X, Y, pdf); - else - importance_sample_ggx(R, randu, randv, omega_in, params->m_roughness, X, Y, pdf); - H = normalize(I + *omega_in); - } - else { - if (params->m_anisotropic > 0.0f) - importance_sample_ggx_aniso(N, randu, randv, &H, params->m_ax, params->m_ay, X, Y, pdf); - else - importance_sample_ggx(N, randu, randv, &H, params->m_roughness, X, Y, pdf); - *omega_in = -I - 2.0f * dot(-I, H) * H; - } - - if (params->m_brightness > 0.2f && params->m_brightness < 0.8f) { - if (dot(Ng, *omega_in) < 0.0f) { - *omega_in = -(*omega_in) - 2.0f * dot(-(*omega_in), R) * R; - H = normalize(*omega_in + I); - } - } - - if (dot(Ng, *omega_in) > 0.0f) { - float3 V = I; // outgoing - float3 L = *omega_in; // incoming - - *eval = calculate_disney_specular_brdf(sc, params, N, X, Y, V, L, H, pdf, params->m_withNdotL > 0.75f); - -#ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = 2 * dot(H, dIdx) * H - dIdx; - *domega_in_dy = 2 * dot(H, dIdy) * H - dIdy; -#endif - } - else { - *pdf = 0.0f; - *eval = make_float3(0.0f, 0.0f, 0.0f); - } - - return LABEL_REFLECT|LABEL_GLOSSY;*/ - float alpha_x = params->m_ax; float alpha_y = params->m_ay; float3 N = sc->N; @@ -560,16 +361,10 @@ ccl_device int bsdf_disney_specular_sample(const ShaderClosure *sc, const Disney float3 m; float G1o; - //if (params->m_exposure > 0.5f) { - local_m = spec_microfacet_sample_stretched(local_I, alpha_x, alpha_y, - randu, randv, false, &G1o); + local_m = spec_microfacet_sample_stretched(local_I, alpha_x, alpha_y, + randu, randv, false, &G1o); - m = X*local_m.x + Y*local_m.y + Z*local_m.z; - /*} - else { - importance_sample_ggx_aniso(N, randu, randv, &m, alpha_x, alpha_y, X, Y, pdf); - local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m)); - }*/ + m = X*local_m.x + Y*local_m.y + Z*local_m.z; float cosThetaM = local_m.z; /* reflection or refraction? */ @@ -592,64 +387,40 @@ ccl_device int bsdf_disney_specular_sample(const ShaderClosure *sc, const Disney float D, G1i; if(alpha_x == alpha_y) { - /* isotropic */ - //if (params->m_brightness > 0.5f) { - float cosThetaM2 = cosThetaM * cosThetaM; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float tanThetaM2 = 1/(cosThetaM2) - 1; - D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); - /*} - else { - D = spec_GTR2(dot(N, m), params->m_ax); - }*/ + float cosThetaM2 = cosThetaM * cosThetaM; + float cosThetaM4 = cosThetaM2 * cosThetaM2; + float tanThetaM2 = 1/(cosThetaM2) - 1; + D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); /* eval BRDF*cosNI */ float cosNI = dot(N, *omega_in); /* eq. 34: now calculate G1(i,m) */ - //if (params->m_exposure > 0.5f) { - G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); - /*} - else { - G1i = spec_smithG_GGX(cosNI, params->m_roughg); - G1o = spec_smithG_GGX(cosNO, params->m_roughg); - }*/ + G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); } else { /* anisotropic distribution */ - //if (params->m_brightness > 0.5f) { - //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; + 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; - float cosThetaM = local_m.z; - float cosThetaM2 = cosThetaM * cosThetaM; - float cosThetaM4 = cosThetaM2 * cosThetaM2; + float cosThetaM = local_m.z; + float cosThetaM2 = cosThetaM * cosThetaM; + float cosThetaM4 = cosThetaM2 * cosThetaM2; - D = 1 / ((slope_len * slope_len) * M_PI_F * alpha2 * cosThetaM4); - /*} - else { - D = spec_GTR2_aniso(dot(N, m), dot(X, m), dot(Y, m), params->m_ax, params->m_ay); - }*/ + D = 1 / ((slope_len * slope_len) * M_PI_F * alpha2 * cosThetaM4); /* calculate G1(i,m) */ float cosNI = dot(N, *omega_in); - //if (params->m_exposure > 0.5f) { - float tanThetaI2 = (1 - cosNI * cosNI) / (cosNI * cosNI); - float cosPhiI = dot(*omega_in, X); - float sinPhiI = dot(*omega_in, Y); + float tanThetaI2 = (1 - cosNI * cosNI) / (cosNI * cosNI); + float cosPhiI = dot(*omega_in, X); + float sinPhiI = dot(*omega_in, Y); - float alphaI2 = (cosPhiI*cosPhiI)*(alpha_x*alpha_x) + (sinPhiI*sinPhiI)*(alpha_y*alpha_y); - alphaI2 /= cosPhiI*cosPhiI + sinPhiI*sinPhiI; + float alphaI2 = (cosPhiI*cosPhiI)*(alpha_x*alpha_x) + (sinPhiI*sinPhiI)*(alpha_y*alpha_y); + alphaI2 /= cosPhiI*cosPhiI + sinPhiI*sinPhiI; - G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2)); - /*} - else { - G1i = spec_smithG_GGX(cosNI, params->m_roughg); - G1o = spec_smithG_GGX(cosNO, params->m_roughg); - }*/ + G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2)); } /* see eval function for derivation */ diff --git a/intern/cycles/kernel/osl/CMakeLists.txt b/intern/cycles/kernel/osl/CMakeLists.txt index 492e06a3398..bc0e43e9c6a 100644 --- a/intern/cycles/kernel/osl/CMakeLists.txt +++ b/intern/cycles/kernel/osl/CMakeLists.txt @@ -23,6 +23,7 @@ set(SRC osl_shader.cpp bsdf_disney_diffuse.cpp bsdf_disney_specular.cpp + bsdf_disney_clearcoat.cpp ) set(HEADER_SRC diff --git a/intern/cycles/kernel/osl/bsdf_disney_clearcoat.cpp b/intern/cycles/kernel/osl/bsdf_disney_clearcoat.cpp new file mode 100644 index 00000000000..864e42584e1 --- /dev/null +++ b/intern/cycles/kernel/osl/bsdf_disney_clearcoat.cpp @@ -0,0 +1,103 @@ +/* + * 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. + */ + +#include + +#include + +#include "kernel_compat_cpu.h" +#include "osl_closures.h" + +#include "kernel_types.h" +#include "kernel_montecarlo.h" +#include "closure/bsdf_disney_clearcoat.h" + +CCL_NAMESPACE_BEGIN + +using namespace OSL; + +class DisneyClearcoatClosure : public CBSDFClosure { +public: + DisneyClearcoatBRDFParams dp; + + DisneyClearcoatClosure() : CBSDFClosure(LABEL_REFLECT|LABEL_GLOSSY) + {} + + void setup() + { + sc.prim = this; + m_shaderdata_flag = bsdf_disney_clearcoat_setup(&sc); + + dp.precompute_values(); + } + + void blur(float roughness) + { + } + + float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float& pdf) const + { + return bsdf_disney_clearcoat_eval_reflect(&sc, &dp, omega_out, omega_in, &pdf); + } + + float3 eval_transmit(const float3 &omega_out, const float3 &omega_in, float& pdf) const + { + return bsdf_disney_clearcoat_eval_transmit(&sc, omega_out, omega_in, &pdf); + } + + int sample(const float3 &Ng, + const float3 &omega_out, const float3 &domega_out_dx, const float3 &domega_out_dy, + float randu, float randv, + float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy, + float &pdf, float3 &eval) const + { + return bsdf_disney_clearcoat_sample(&sc, &dp, Ng, omega_out, domega_out_dx, domega_out_dy, + randu, randv, &eval, &omega_in, &domega_in_dx, &domega_in_dy, &pdf); + } +}; + +ClosureParam *closure_bsdf_disney_clearcoat_params() +{ + static ClosureParam params[] = { + CLOSURE_FLOAT3_PARAM(DisneyClearcoatClosure, sc.N), + CLOSURE_FLOAT_PARAM(DisneyClearcoatClosure, dp.m_clearcoat), + CLOSURE_FLOAT_PARAM(DisneyClearcoatClosure, dp.m_clearcoatGloss), + CLOSURE_STRING_KEYPARAM(DisneyClearcoatClosure, label, "label"), + CLOSURE_FINISH_PARAM(DisneyClearcoatClosure) + }; + return params; +} + +CCLOSURE_PREPARE(closure_bsdf_disney_clearcoat_prepare, DisneyClearcoatClosure) + +CCL_NAMESPACE_END + diff --git a/intern/cycles/kernel/osl/bsdf_disney_diffuse.cpp b/intern/cycles/kernel/osl/bsdf_disney_diffuse.cpp index 9c4433e47a0..b5b5eaf86e5 100644 --- a/intern/cycles/kernel/osl/bsdf_disney_diffuse.cpp +++ b/intern/cycles/kernel/osl/bsdf_disney_diffuse.cpp @@ -94,11 +94,6 @@ ClosureParam *closure_bsdf_disney_diffuse_params() CLOSURE_FLOAT_PARAM(DisneyDiffuseClosure, dp.m_roughness), CLOSURE_FLOAT_PARAM(DisneyDiffuseClosure, dp.m_sheen), CLOSURE_FLOAT_PARAM(DisneyDiffuseClosure, dp.m_sheen_tint), - CLOSURE_FLOAT_PARAM(DisneyDiffuseClosure, dp.m_withNdotL), - CLOSURE_FLOAT_PARAM(DisneyDiffuseClosure, dp.m_brightness), - CLOSURE_FLOAT_PARAM(DisneyDiffuseClosure, dp.m_gamma), - CLOSURE_FLOAT_PARAM(DisneyDiffuseClosure, dp.m_exposure), - CLOSURE_FLOAT_PARAM(DisneyDiffuseClosure, dp.m_mon2lingamma), CLOSURE_STRING_KEYPARAM(DisneyDiffuseClosure, label, "label"), CLOSURE_FINISH_PARAM(DisneyDiffuseClosure) }; diff --git a/intern/cycles/kernel/osl/bsdf_disney_specular.cpp b/intern/cycles/kernel/osl/bsdf_disney_specular.cpp index b19c52b5c1d..1e586cb609f 100644 --- a/intern/cycles/kernel/osl/bsdf_disney_specular.cpp +++ b/intern/cycles/kernel/osl/bsdf_disney_specular.cpp @@ -96,11 +96,6 @@ ClosureParam *closure_bsdf_disney_specular_params() CLOSURE_FLOAT_PARAM(DisneySpecularClosure, dp.m_specular_tint), CLOSURE_FLOAT_PARAM(DisneySpecularClosure, dp.m_roughness), CLOSURE_FLOAT_PARAM(DisneySpecularClosure, dp.m_anisotropic), - CLOSURE_FLOAT_PARAM(DisneySpecularClosure, dp.m_withNdotL), - CLOSURE_FLOAT_PARAM(DisneySpecularClosure, dp.m_brightness), - CLOSURE_FLOAT_PARAM(DisneySpecularClosure, dp.m_gamma), - CLOSURE_FLOAT_PARAM(DisneySpecularClosure, dp.m_exposure), - CLOSURE_FLOAT_PARAM(DisneySpecularClosure, dp.m_mon2lingamma), CLOSURE_STRING_KEYPARAM(DisneySpecularClosure, label, "label"), CLOSURE_FINISH_PARAM(DisneySpecularClosure) }; diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp index c8f82b527bb..009eefdf1c7 100644 --- a/intern/cycles/kernel/osl/osl_closures.cpp +++ b/intern/cycles/kernel/osl/osl_closures.cpp @@ -242,6 +242,8 @@ void OSLShader::register_closures(OSLShadingSystem *ss_) closure_bsdf_disney_diffuse_params(), closure_bsdf_disney_diffuse_prepare); register_closure(ss, "disney_specular", id++, closure_bsdf_disney_specular_params(), closure_bsdf_disney_specular_prepare); + register_closure(ss, "disney_clearcoat", id++, + closure_bsdf_disney_clearcoat_params(), closure_bsdf_disney_clearcoat_prepare); register_closure(ss, "hair_reflection", id++, bsdf_hair_reflection_params(), bsdf_hair_reflection_prepare); diff --git a/intern/cycles/kernel/osl/osl_closures.h b/intern/cycles/kernel/osl/osl_closures.h index e580663d305..6c9d77c45d0 100644 --- a/intern/cycles/kernel/osl/osl_closures.h +++ b/intern/cycles/kernel/osl/osl_closures.h @@ -54,6 +54,7 @@ OSL::ClosureParam *closure_bssrdf_burley_params(); OSL::ClosureParam *closure_henyey_greenstein_volume_params(); OSL::ClosureParam *closure_bsdf_disney_diffuse_params(); OSL::ClosureParam *closure_bsdf_disney_specular_params(); +OSL::ClosureParam *closure_bsdf_disney_clearcoat_params(); void closure_emission_prepare(OSL::RendererServices *, int id, void *data); void closure_background_prepare(OSL::RendererServices *, int id, void *data); @@ -67,6 +68,7 @@ void closure_bssrdf_burley_prepare(OSL::RendererServices *, int id, void *data); void closure_henyey_greenstein_volume_prepare(OSL::RendererServices *, int id, void *data); void closure_bsdf_disney_diffuse_prepare(OSL::RendererServices *, int id, void *data); void closure_bsdf_disney_specular_prepare(OSL::RendererServices *, int id, void *data); +void closure_bsdf_disney_clearcoat_prepare(OSL::RendererServices *, int id, void *data); #define CCLOSURE_PREPARE(name, classname) \ void name(RendererServices *, int id, void *data) \ diff --git a/intern/cycles/kernel/shaders/stdosl.h b/intern/cycles/kernel/shaders/stdosl.h index af9ecdd7126..c799e2f3ae3 100644 --- a/intern/cycles/kernel/shaders/stdosl.h +++ b/intern/cycles/kernel/shaders/stdosl.h @@ -537,10 +537,10 @@ closure color background() BUILTIN; closure color holdout() BUILTIN; closure color ambient_occlusion() BUILTIN; closure color disney_diffuse(normal N, color baseColor, float subsurface, float roughness, float sheen, - float sheenTint, float withNdotL, float brightness, float gamma, float exposure, float mon2lingamma) BUILTIN; + float sheenTint) BUILTIN; closure color disney_specular(normal N, normal T, color baseColor, float metallic, float specular, float specularTint, - float roughness, float anisotropic, float withNdotL, float brightness, float gamma, float exposure, - float mon2lingamma) BUILTIN; + float roughness, float anisotropic) BUILTIN; +closure color disney_clearcoat(normal N, float clearcoat, float clearcoatGloss) BUILTIN; // BSSRDF closure color bssrdf_cubic(normal N, vector radius, float texture_blur, float sharpness) BUILTIN; diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index 04a4eaf8ec5..b5cbf9669bc 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -393,6 +393,7 @@ typedef enum ClosureType { CLOSURE_BSDF_GLOSSY_TOON_ID, CLOSURE_BSDF_HAIR_REFLECTION_ID, CLOSURE_BSDF_DISNEY_SPECULAR_ID, + CLOSURE_BSDF_DISNEY_CLEARCOAT_ID, /* Transmission */ CLOSURE_BSDF_TRANSMISSION_ID, From 0ed08959141fc7c5f8c6e37c6552ecb9fcc5749c Mon Sep 17 00:00:00 2001 From: Pascal Schoen Date: Wed, 4 May 2016 13:23:07 +0200 Subject: [PATCH 05/10] added the disney brdf as a shader node --- intern/cycles/blender/blender_shader.cpp | 4 +-- .../cycles/kernel/osl/bsdf_disney_diffuse.cpp | 8 +++--- .../kernel/osl/bsdf_disney_specular.cpp | 8 +++--- intern/cycles/kernel/shaders/CMakeLists.txt | 2 +- .../kernel/shaders/node_disney_bsdf.osl | 18 +++++++++++-- intern/cycles/render/nodes.cpp | 26 +++++++++++++++++-- intern/cycles/render/nodes.h | 5 ++-- release/scripts/startup/nodeitems_builtins.py | 2 +- source/blender/blenkernel/BKE_node.h | 2 +- source/blender/blenkernel/intern/node.c | 2 +- source/blender/nodes/CMakeLists.txt | 2 +- source/blender/nodes/NOD_shader.h | 2 +- source/blender/nodes/NOD_static_types.h | 2 +- .../shader/nodes/node_shader_bsdf_disney.c | 22 ++++++++-------- 14 files changed, 69 insertions(+), 36 deletions(-) diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 01a6476fccd..6120c025a58 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -527,9 +527,9 @@ static ShaderNode *add_node(Scene *scene, } node = hair; } - /*else if(b_node.is_a(&RNA_ShaderNodeBsdfDisney)) { + else if(b_node.is_a(&RNA_ShaderNodeBsdfDisney)) { node = new DisneyBsdfNode(); - }*/ + } else if(b_node.is_a(&RNA_ShaderNodeBsdfTranslucent)) { node = new TranslucentBsdfNode(); } diff --git a/intern/cycles/kernel/osl/bsdf_disney_diffuse.cpp b/intern/cycles/kernel/osl/bsdf_disney_diffuse.cpp index b5b5eaf86e5..04a5b7940e4 100644 --- a/intern/cycles/kernel/osl/bsdf_disney_diffuse.cpp +++ b/intern/cycles/kernel/osl/bsdf_disney_diffuse.cpp @@ -74,11 +74,9 @@ public: return bsdf_disney_diffuse_eval_transmit(&sc, omega_out, omega_in, &pdf); } - int sample(const float3 &Ng, - const float3 &omega_out, const float3 &domega_out_dx, const float3 &domega_out_dy, - float randu, float randv, - float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy, - float &pdf, float3 &eval) const + int sample(const float3 &Ng, const float3 &omega_out, const float3 &domega_out_dx, + const float3 &domega_out_dy, float randu, float randv, float3 &omega_in, + float3 &domega_in_dx, float3 &domega_in_dy, float &pdf, float3 &eval) const { return bsdf_disney_diffuse_sample(&sc, &dp, Ng, omega_out, domega_out_dx, domega_out_dy, randu, randv, &eval, &omega_in, &domega_in_dx, &domega_in_dy, &pdf); diff --git a/intern/cycles/kernel/osl/bsdf_disney_specular.cpp b/intern/cycles/kernel/osl/bsdf_disney_specular.cpp index 1e586cb609f..df55a7e5876 100644 --- a/intern/cycles/kernel/osl/bsdf_disney_specular.cpp +++ b/intern/cycles/kernel/osl/bsdf_disney_specular.cpp @@ -74,11 +74,9 @@ public: return bsdf_disney_specular_eval_transmit(&sc, omega_out, omega_in, &pdf); } - int sample(const float3 &Ng, - const float3 &omega_out, const float3 &domega_out_dx, const float3 &domega_out_dy, - float randu, float randv, - float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy, - float &pdf, float3 &eval) const + int sample(const float3 &Ng, const float3 &omega_out, const float3 &domega_out_dx, + const float3 &domega_out_dy, float randu, float randv, float3 &omega_in, + float3 &domega_in_dx, float3 &domega_in_dy, float &pdf, float3 &eval) const { return bsdf_disney_specular_sample(&sc, &dp, Ng, omega_out, domega_out_dx, domega_out_dy, randu, randv, &eval, &omega_in, &domega_in_dx, &domega_in_dy, &pdf); diff --git a/intern/cycles/kernel/shaders/CMakeLists.txt b/intern/cycles/kernel/shaders/CMakeLists.txt index c6c9e6ed009..5dab03bcb16 100644 --- a/intern/cycles/kernel/shaders/CMakeLists.txt +++ b/intern/cycles/kernel/shaders/CMakeLists.txt @@ -81,7 +81,7 @@ set(SRC_OSL node_wireframe.osl node_hair_bsdf.osl node_uv_map.osl - #node_disney_bsdf.osl + node_disney_bsdf.osl ) set(SRC_OSL_HEADERS diff --git a/intern/cycles/kernel/shaders/node_disney_bsdf.osl b/intern/cycles/kernel/shaders/node_disney_bsdf.osl index 9bd225dd391..a9ee16e95cd 100644 --- a/intern/cycles/kernel/shaders/node_disney_bsdf.osl +++ b/intern/cycles/kernel/shaders/node_disney_bsdf.osl @@ -30,9 +30,23 @@ shader node_disney_bsdf( float ClearcoatGloss = 1.0, normal Normal = N, normal Tangent = normalize(dPdu), - normal AnisotropicRotation = normal(0, 0, 0), + //normal AnisotropicRotation = normal(0, 0, 0), output closure color BSDF = 0) { - BSDF = disney_diffuse(Normal, BaseColor); + if (Metallic == 1.0) { + BSDF = disney_specular(Normal, Tangent, BaseColor, Metallic, Specular, + SpecularTint, Roughness, Anisotropic) + + disney_clearcoat(Normal, Clearcoat, ClearcoatGloss); + } else if (Specular == 0.0) { + BSDF = disney_diffuse(Normal, BaseColor, Subsurface, Roughness, + Sheen, SheenTint) * (1.0 - Metallic) + + disney_clearcoat(Normal, Clearcoat, ClearcoatGloss); + } else { + BSDF = disney_diffuse(Normal, BaseColor, Subsurface, Roughness, + Sheen, SheenTint) * (1.0 - Metallic) + + disney_specular(Normal, Tangent, BaseColor, Metallic, Specular, + SpecularTint, Roughness, Anisotropic) + + disney_clearcoat(Normal, Clearcoat, ClearcoatGloss); + } } diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 696548f3fda..bcf4e6709fd 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -2068,10 +2068,32 @@ void DiffuseBsdfNode::compile(OSLCompiler& compiler) } /* Disney BSDF Closure */ -/*DisneyBsdfNode::DisneyBsdfNode() +DisneyBsdfNode::DisneyBsdfNode() { closure = CLOSURE_BSDF_DISNEY_DIFFUSE_ID; -}*/ + + add_input("BaseColor", SHADER_SOCKET_COLOR, make_float3(0.646f, 0.415f, 0.017f)); + add_input("Metallic", SHADER_SOCKET_FLOAT, 0.0f); + add_input("Subsurface", SHADER_SOCKET_FLOAT, 0.0f); + add_input("Specular", SHADER_SOCKET_FLOAT, 0.5f); + add_input("Roughness", SHADER_SOCKET_FLOAT, 0.5f); + add_input("SpecularTint", SHADER_SOCKET_FLOAT, 0.0f); + add_input("Anisotropic", SHADER_SOCKET_FLOAT, 0.0f); + add_input("Sheen", SHADER_SOCKET_FLOAT, 0.0f); + add_input("SheenTint", SHADER_SOCKET_FLOAT, 0.5f); + add_input("Clearcoat", SHADER_SOCKET_FLOAT, 0.0f); + add_input("ClearcoatGloss", SHADER_SOCKET_FLOAT, 1.0f); + add_input("Tangent", SHADER_SOCKET_VECTOR, ShaderInput::TANGENT); +} + +void DisneyBsdfNode::compile(SVMCompiler& compiler) +{ +} + +void DisneyBsdfNode::compile(OSLCompiler& compiler) +{ + compiler.add(this, "node_disney_bsdf"); +} /* Translucent BSDF Closure */ diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 8e0b4636633..c44bf207afe 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -410,10 +410,11 @@ public: SHADER_NODE_CLASS(DiffuseBsdfNode) }; -/*class DisneyBsdfNode : public BsdfNode { +/* Disney BRDF */ +class DisneyBsdfNode : public BsdfNode { public: SHADER_NODE_CLASS(DisneyBsdfNode) -};*/ +}; class TranslucentBsdfNode : public BsdfNode { public: diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index 08a6092787e..d6cf66bbb63 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -218,7 +218,7 @@ shader_node_categories = [ NodeItem("ShaderNodeMixShader"), NodeItem("ShaderNodeAddShader"), NodeItem("ShaderNodeBsdfDiffuse", poll=object_shader_nodes_poll), - #NodeItem("ShaderNodeBsdfDisney", poll=object_shader_nodes_poll), + NodeItem("ShaderNodeBsdfDisney", poll=object_shader_nodes_poll), NodeItem("ShaderNodeBsdfGlossy", poll=object_shader_nodes_poll), NodeItem("ShaderNodeBsdfTransparent", poll=object_shader_nodes_poll), NodeItem("ShaderNodeBsdfRefraction", poll=object_shader_nodes_poll), diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index c0f68f51e6a..7a1e6e9c917 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -787,7 +787,7 @@ struct ShadeResult; #define SH_NODE_OUTPUT_LINESTYLE 190 #define SH_NODE_UVALONGSTROKE 191 #define SH_NODE_TEX_POINTDENSITY 192 -//#define SH_NODE_BSDF_DISNEY 193 +#define SH_NODE_BSDF_DISNEY 193 /* custom defines options for Material node */ #define SH_NODE_MAT_DIFF 1 diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 1a1e1c3740a..b31a5ef2212 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -3672,7 +3672,7 @@ static void registerShaderNodes(void) register_node_type_sh_background(); register_node_type_sh_bsdf_anisotropic(); register_node_type_sh_bsdf_diffuse(); - //register_node_type_sh_bsdf_disney(); + register_node_type_sh_bsdf_disney(); register_node_type_sh_bsdf_glossy(); register_node_type_sh_bsdf_glass(); register_node_type_sh_bsdf_translucent(); diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 72f1eeba50a..f7ad0b8ee52 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -163,7 +163,7 @@ set(SRC shader/nodes/node_shader_background.c shader/nodes/node_shader_bsdf_anisotropic.c shader/nodes/node_shader_bsdf_diffuse.c - #shader/nodes/node_shader_bsdf_disney.c + shader/nodes/node_shader_bsdf_disney.c shader/nodes/node_shader_bsdf_glass.c shader/nodes/node_shader_bsdf_glossy.c shader/nodes/node_shader_bsdf_toon.c diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h index 1b330efa9c6..92b7790f521 100644 --- a/source/blender/nodes/NOD_shader.h +++ b/source/blender/nodes/NOD_shader.h @@ -106,7 +106,7 @@ void register_node_type_sh_bsdf_transparent(void); void register_node_type_sh_bsdf_velvet(void); void register_node_type_sh_bsdf_toon(void); void register_node_type_sh_bsdf_anisotropic(void); -//void register_node_type_sh_bsdf_disney(void); +void register_node_type_sh_bsdf_disney(void); void register_node_type_sh_emission(void); void register_node_type_sh_holdout(void); void register_node_type_sh_volume_absorption(void); diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index 86bc07cf7f4..0b43d25023f 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -80,7 +80,7 @@ DefNode( ShaderNode, SH_NODE_BACKGROUND, 0, "BA DefNode( ShaderNode, SH_NODE_HOLDOUT, 0, "HOLDOUT", Holdout, "Holdout", "" ) DefNode( ShaderNode, SH_NODE_BSDF_ANISOTROPIC, def_anisotropic, "BSDF_ANISOTROPIC", BsdfAnisotropic, "Anisotropic BSDF", "" ) DefNode( ShaderNode, SH_NODE_BSDF_DIFFUSE, 0, "BSDF_DIFFUSE", BsdfDiffuse, "Diffuse BSDF", "" ) -//DefNode( ShaderNode, SH_NODE_BSDF_DISNEY, 0, "BSDF_DISNEY", BsdfDisney, "Disney BSDF", "" ) +DefNode( ShaderNode, SH_NODE_BSDF_DISNEY, 0, "BSDF_DISNEY", BsdfDisney, "Disney BSDF", "" ) DefNode( ShaderNode, SH_NODE_BSDF_GLOSSY, def_glossy, "BSDF_GLOSSY", BsdfGlossy, "Glossy BSDF", "" ) DefNode( ShaderNode, SH_NODE_BSDF_GLASS, def_glass, "BSDF_GLASS", BsdfGlass, "Glass BSDF", "" ) DefNode( ShaderNode, SH_NODE_BSDF_REFRACTION, def_glass, "BSDF_REFRACTION", BsdfRefraction, "Refraction BSDF", "" ) diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_disney.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_disney.c index bd4b5f9ff8f..d2db4d9bec7 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_disney.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_disney.c @@ -31,19 +31,19 @@ static bNodeSocketTemplate sh_node_bsdf_disney_in[] = { { SOCK_RGBA, 1, N_("BaseColor"), 0.64555527f, 0.41514809f, 0.01698805f, 1.0f, 0.0f, 1.0f}, - { SOCK_FLOAT, 1, N_("Metallic"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, - { SOCK_FLOAT, 1, N_("Subsurface"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, - { SOCK_FLOAT, 1, N_("Specular"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, - { SOCK_FLOAT, 1, N_("Roughness"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, - { SOCK_FLOAT, 1, N_("SpecularTint"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, - { SOCK_FLOAT, 1, N_("Anisotropic"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, - { SOCK_FLOAT, 1, N_("Sheen"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, - { SOCK_FLOAT, 1, N_("SheenTint"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, - { SOCK_FLOAT, 1, N_("Clearcoat"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, - { SOCK_FLOAT, 1, N_("ClearcoatGloss"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("Metallic"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("Subsurface"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("Specular"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("Roughness"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("SpecularTint"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("Anisotropic"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("Sheen"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("SheenTint"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("Clearcoat"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("ClearcoatGloss"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, { SOCK_VECTOR, 1, N_("Tangent"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, - { SOCK_VECTOR, 1, N_("AnisotropicRotation"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, + //{ SOCK_VECTOR, 1, N_("AnisotropicRotation"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, { -1, 0, "" } }; From 6006f91e8730f78df5874f808690d3908db103ab Mon Sep 17 00:00:00 2001 From: Pascal Schoen Date: Wed, 4 May 2016 16:08:10 +0200 Subject: [PATCH 06/10] disney implementation cleaned --- .../kernel/closure/bsdf_disney_clearcoat.h | 114 +---------- .../kernel/closure/bsdf_disney_diffuse.h | 124 ++---------- .../kernel/closure/bsdf_disney_specular.h | 179 +----------------- intern/cycles/kernel/closure/bsdf_util.h | 104 ++++++++++ .../kernel/osl/bsdf_disney_clearcoat.cpp | 1 + .../cycles/kernel/osl/bsdf_disney_diffuse.cpp | 1 + .../kernel/osl/bsdf_disney_specular.cpp | 1 + intern/cycles/util/util_math.h | 24 +++ 8 files changed, 160 insertions(+), 388 deletions(-) diff --git a/intern/cycles/kernel/closure/bsdf_disney_clearcoat.h b/intern/cycles/kernel/closure/bsdf_disney_clearcoat.h index 6d09cb0d140..0300c56da5a 100644 --- a/intern/cycles/kernel/closure/bsdf_disney_clearcoat.h +++ b/intern/cycles/kernel/closure/bsdf_disney_clearcoat.h @@ -35,16 +35,6 @@ 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 @@ -55,105 +45,13 @@ struct DisneyClearcoatBRDFParams { float m_clearcoatRoughness; void precompute_values() { - m_clearcoatRoughness = MIX(0.1f, 0.001f, m_clearcoatGloss); + 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; @@ -199,8 +97,8 @@ ccl_device float3 bsdf_disney_clearcoat_eval_reflect(const ShaderClosure *sc, /* 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); + float FH = schlick_fresnel(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; @@ -246,7 +144,7 @@ ccl_device int bsdf_disney_clearcoat_sample(const ShaderClosure *sc, const Disne float3 m; float G1o; - local_m = clear_microfacet_sample_stretched(local_I, alpha, alpha, + local_m = importance_sample_microfacet_stretched(local_I, alpha, alpha, randu, randv, false, &G1o); m = X*local_m.x + Y*local_m.y + Z*local_m.z; @@ -288,8 +186,8 @@ ccl_device int bsdf_disney_clearcoat_sample(const ShaderClosure *sc, const Disne float common = (G1o * D) * 0.25f / cosNO; *pdf = common; - 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); + float FH = schlick_fresnel(dot(*omega_in, m)); + float3 F = mix(make_float3(0.04f, 0.04f, 0.04f), make_float3(1.0f, 1.0f, 1.0f), FH); *eval = G1i * common * F * 0.25f * params->m_clearcoat; } diff --git a/intern/cycles/kernel/closure/bsdf_disney_diffuse.h b/intern/cycles/kernel/closure/bsdf_disney_diffuse.h index fa4b17ce011..3e44277a30f 100644 --- a/intern/cycles/kernel/closure/bsdf_disney_diffuse.h +++ b/intern/cycles/kernel/closure/bsdf_disney_diffuse.h @@ -34,71 +34,8 @@ #ifndef __BSDF_DISNEY_DIFFUSE_H__ #define __BSDF_DISNEY_DIFFUSE_H__ -#include - CCL_NAMESPACE_BEGIN -/* DISNEY DIFFUSE */ - -ccl_device float diff_sqr(float a) { - return a * a; -} - -ccl_device float3 diff_mon2lin(float3 x, float gamma) { - return make_float3(pow(x[0], gamma), pow(x[1], gamma), pow(x[2], gamma)); -} - -ccl_device float diff_GTR1(float NdotH, float a) { - if (a >= 1.0f) return 1.0f / M_PI_F; - float a2 = a*a; - float t = 1.0f + (a2 - 1.0f) * NdotH * NdotH; - return (a2 - 1.0f) / (M_PI_F * log(a2) * t); -} - -ccl_device float diff_GTR2(float NdotH, float a) { - float a2 = a * a; - float t = 1.0f + (a2 - 1.0f) * NdotH * NdotH; - return a2 / (M_PI_F * t * t); -} - -ccl_device float diff_GTR2_aniso( - float NdotH, - float HdotX, - float HdotY, - float ax, - float ay) -{ - return 1.0f / (M_PI_F * ax * ay * diff_sqr(diff_sqr(HdotX / ax) + diff_sqr(HdotY / ay) - + NdotH * NdotH)); -} - -ccl_device float diff_smithG_GGX(float Ndotv, float alphaG) { - float a = alphaG * alphaG; - float b = Ndotv * Ndotv; - return 1.0f / (Ndotv + sqrtf(a + b - a * b)); -} - -ccl_device float diff_SchlickFresnel(float u) { - float m = clamp(1.0f - u, 0.0f, 1.0f); - float m2 = m * m; - return m2 * m2 * m; // pow(m, 5) -} - -ccl_device float3 diff_transform_to_local(const float3& v, const float3& n, - const float3& x, const float3& y) -{ - return make_float3(dot(v, x), dot(v, n), dot(v, y)); -} - -ccl_device float3 diff_mix(float3 x, float3 y, float a) { - return x * (1.0f - a) + y * a; -} - -ccl_device float diff_mix(float x, float y, float a) { - return x * (1.0f - a) + y * a; -} - -/* structures */ struct DisneyDiffuseBRDFParams { // brdf parameters float3 m_base_color; @@ -110,23 +47,22 @@ struct DisneyDiffuseBRDFParams { // precomputed values float3 m_cdlin, m_ctint, m_csheen; float m_cdlum; - float m_weights[4]; void precompute_values() { m_cdlin = m_base_color; m_cdlum = 0.3f * m_cdlin[0] + 0.6f * m_cdlin[1] + 0.1f * m_cdlin[2]; // luminance approx. m_ctint = m_cdlum > 0.0f ? m_cdlin / m_cdlum : make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat - m_csheen = diff_mix(make_float3(1.0f, 1.0f, 1.0f), m_ctint, m_sheen_tint); + m_csheen = mix(make_float3(1.0f, 1.0f, 1.0f), m_ctint, m_sheen_tint); } }; typedef struct DisneyDiffuseBRDFParams DisneyDiffuseBRDFParams; -/* brdf */ + ccl_device float3 calculate_disney_diffuse_brdf(const ShaderClosure *sc, const DisneyDiffuseBRDFParams *params, float3 N, float3 V, float3 L, - float3 H, float *pdf, bool withNdotL = true) + float3 H, float *pdf) { float NdotL = dot(N, L); float NdotV = dot(N, V); @@ -139,61 +75,32 @@ ccl_device float3 calculate_disney_diffuse_brdf(const ShaderClosure *sc, float LdotH = dot(L, H); float Fd = 0.0f; - float FL = diff_SchlickFresnel(NdotL), FV = diff_SchlickFresnel(NdotV); + float FL = schlick_fresnel(NdotL), FV = schlick_fresnel(NdotV); if (params->m_subsurface != 1.0f) { const float Fd90 = 0.5f + 2.0f * LdotH*LdotH * params->m_roughness; - Fd = diff_mix(1.0f, Fd90, FL) * diff_mix(1.0f, Fd90, FV); + Fd = mix(1.0f, Fd90, FL) * mix(1.0f, Fd90, FV); } if (params->m_subsurface > 0.0f) { float Fss90 = LdotH*LdotH * params->m_roughness; - float Fss = diff_mix(1.0f, Fss90, FL) * diff_mix(1.0f, Fss90, FV); + float Fss = mix(1.0f, Fss90, FL) * mix(1.0f, Fss90, FV); float ss = 1.25f * (Fss * (1.0f / (NdotL + NdotV) - 0.5f) + 0.5f); - Fd = diff_mix(Fd, ss, params->m_subsurface); + Fd = mix(Fd, ss, params->m_subsurface); } float3 value = M_1_PI_F * Fd * params->m_cdlin; - //if (params->m_gamma > 0.5f) - *pdf = M_1_PI_F; - - /*if (params->m_exposure > 0.95f) - *pdf *= params->m_cdlum; - else if (params->m_exposure > 0.85f) - *pdf *= params->m_cdlum * NdotL; - else if (params->m_exposure > 0.75f) - *pdf *= params->m_cdlum * 0.5f; - else if (params->m_exposure > 0.65f) - *pdf *= params->m_cdlum * NdotL * 0.5f; - else if (params->m_exposure > 0.55f) - *pdf *= NdotL; - else if (params->m_exposure > 0.45f) - *pdf *= NdotL * 0.5f; - else if (params->m_exposure > 0.35f)*/ - *pdf *= 0.5f; + *pdf = M_1_PI_F * 0.5f; // sheen component if (params->m_sheen != 0.0f) { - float FH = diff_SchlickFresnel(LdotH); + float FH = schlick_fresnel(LdotH); value += FH * params->m_sheen * params->m_csheen; - //*pdf += 0.5f * M_1_PI_F * params->m_sheen; } - if (withNdotL) - value *= NdotL; - - // brightness - //value *= params->m_brightness; - - // exposure - //value *= pow(2.0f, params->m_exposure); - - // gamma - /*value[0] = pow(value[0], 1.0f / params->m_gamma); - value[1] = pow(value[1], 1.0f / params->m_gamma); - value[2] = pow(value[2], 1.0f / params->m_gamma);*/ + value *= NdotL; return value; } @@ -236,17 +143,12 @@ ccl_device int bsdf_disney_diffuse_sample(const ShaderClosure *sc, const DisneyD { float3 N = normalize(sc->N); - /*if (params->m_brightness > 0.5f) - sample_cos_hemisphere(N, randu, randv, omega_in, pdf); - else*/ - sample_uniform_hemisphere(N, randu, randv, omega_in, pdf); + sample_uniform_hemisphere(N, randu, randv, omega_in, pdf); if (dot(Ng, *omega_in) > 0) { - float3 V = I; // outgoing - float3 L = *omega_in; // incoming - float3 H = normalize(L + V); + float3 H = normalize(I + *omega_in); - *eval = calculate_disney_diffuse_brdf(sc, params, N, V, L, H, pdf, true); + *eval = calculate_disney_diffuse_brdf(sc, params, N, I, *omega_in, H, pdf); #ifdef __RAY_DIFFERENTIALS__ // TODO: find a better approximation for the diffuse bounce diff --git a/intern/cycles/kernel/closure/bsdf_disney_specular.h b/intern/cycles/kernel/closure/bsdf_disney_specular.h index c5c6c2e72b5..904d0f29663 100644 --- a/intern/cycles/kernel/closure/bsdf_disney_specular.h +++ b/intern/cycles/kernel/closure/bsdf_disney_specular.h @@ -33,76 +33,8 @@ #ifndef __BSDF_DISNEY_SPECULAR_H__ #define __BSDF_DISNEY_SPECULAR_H__ -#include - CCL_NAMESPACE_BEGIN -/* DISNEY SPECULAR */ - -ccl_device float spec_sqr(float a) { - return a * a; -} - -ccl_device float3 spec_mon2lin(float3 x, float gamma) { - return make_float3(pow(x[0], gamma), pow(x[1], gamma), pow(x[2], gamma)); -} - -ccl_device float spec_GTR1(float NdotH, float a) { - if (a >= 1.0f) return 1.0f / M_PI_F; - float a2 = a*a; - float t = 1.0f + (a2 - 1.0f) * NdotH * NdotH; - return (a2 - 1.0f) / (M_PI_F * log(a2) * t); -} - -ccl_device float spec_GTR2(float NdotH, float a) { - float a2 = a * a; - float t = 1.0f + (a2 - 1.0f) * NdotH * NdotH; - return a2 / (M_PI_F * t * t); -} - -ccl_device float spec_GTR2_aniso( - float NdotH, - float HdotX, - float HdotY, - float ax, - float ay) -{ - return 1.0f / (M_PI_F * ax * ay * spec_sqr(spec_sqr(HdotX / ax) + spec_sqr(HdotY / ay) - + NdotH * NdotH)); -} - -ccl_device float spec_smithG_GGX(float Ndotv, float alphaG) { - float a = alphaG * alphaG; - float b = Ndotv * Ndotv; - return 1.0f / (Ndotv + sqrtf(a + b - a * b)); -} - -ccl_device float spec_SchlickFresnel(float u) { - float m = clamp(1.0f - u, 0.0f, 1.0f); - float m2 = m * m; - return m2 * m2 * m; // pow(m, 5) -} - -ccl_device float3 spec_transform_to_local(const float3& v, const float3& n, - const float3& x, const float3& y) -{ - return make_float3(dot(v, x), dot(v, n), dot(v, y)); -} - -ccl_device float3 spec_mix(float3 x, float3 y, float a) { - return x * (1.0f - a) + y * a; -} - -ccl_device float spec_mix(float x, float y, float a) { - return x * (1.0f - a) + y * a; -} - -ccl_device float spec_max(float a, float b) { - if (a > b) return a; - else return b; -} - -/* structures */ struct DisneySpecularBRDFParams { // brdf parameters float3 m_base_color; @@ -124,112 +56,21 @@ struct DisneySpecularBRDFParams { m_ctint = m_cdlum > 0.0f ? m_cdlin / m_cdlum : make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat - m_cspec0 = spec_mix(m_specular * 0.08f * spec_mix(make_float3(1.0f, 1.0f, 1.0f), + m_cspec0 = mix(m_specular * 0.08f * mix(make_float3(1.0f, 1.0f, 1.0f), m_ctint, m_specular_tint), m_cdlin, m_metallic); float aspect = sqrt(1.0f - m_anisotropic * 0.9f); - m_ax = spec_max(0.001f, spec_sqr(m_roughness) / aspect); - m_ay = spec_max(0.001f, spec_sqr(m_roughness) * aspect); + float r2 = sqr(m_roughness); + m_ax = fmaxf(0.001f, r2 / aspect); + m_ay = fmaxf(0.001f, r2 * aspect); - m_roughg = spec_sqr(m_roughness * 0.5f + 0.5f); + m_roughg = sqr(m_roughness * 0.5f + 0.5f); } }; typedef struct DisneySpecularBRDFParams DisneySpecularBRDFParams; -ccl_device_inline void spec_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 = 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 spec_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; - - spec_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_specular_setup(ShaderClosure *sc) { sc->type = CLOSURE_BSDF_DISNEY_SPECULAR_ID; @@ -312,8 +153,8 @@ ccl_device float3 bsdf_disney_specular_eval_reflect(const ShaderClosure *sc, /* eq. 20 */ float common = D * 0.25f / cosNO; - float FH = spec_SchlickFresnel(dot(omega_in, m)); - float3 F = spec_mix(params->m_cspec0, make_float3(1.0f, 1.0f, 1.0f), FH); + float FH = schlick_fresnel(dot(omega_in, m)); + float3 F = mix(params->m_cspec0, make_float3(1.0f, 1.0f, 1.0f), FH); float3 out = F * G * common; @@ -361,7 +202,7 @@ ccl_device int bsdf_disney_specular_sample(const ShaderClosure *sc, const Disney float3 m; float G1o; - local_m = spec_microfacet_sample_stretched(local_I, alpha_x, alpha_y, + local_m = importance_sample_microfacet_stretched(local_I, alpha_x, alpha_y, randu, randv, false, &G1o); m = X*local_m.x + Y*local_m.y + Z*local_m.z; @@ -427,8 +268,8 @@ ccl_device int bsdf_disney_specular_sample(const ShaderClosure *sc, const Disney float common = (G1o * D) * 0.25f / cosNO; *pdf = common; - float FH = spec_SchlickFresnel(dot(*omega_in, m)); - float3 F = spec_mix(params->m_cspec0, make_float3(1.0f, 1.0f, 1.0f), FH); + float FH = schlick_fresnel(dot(*omega_in, m)); + float3 F = mix(params->m_cspec0, make_float3(1.0f, 1.0f, 1.0f), FH); *eval = G1i * common * F; } diff --git a/intern/cycles/kernel/closure/bsdf_util.h b/intern/cycles/kernel/closure/bsdf_util.h index 05816bac2c1..7888aaaaddf 100644 --- a/intern/cycles/kernel/closure/bsdf_util.h +++ b/intern/cycles/kernel/closure/bsdf_util.h @@ -126,6 +126,18 @@ ccl_device float3 fresnel_conductor(float cosi, const float3 eta, const float3 k } #endif +ccl_device_inline float schlick_fresnel(float u) +{ + float m = clamp(1.0f - u, 0.0f, 1.0f); + float m2 = m * m; + return m2 * m2 * m; // pow(m, 5) +} + +ccl_device_inline float sqr(float a) +{ + return a * a; +} + ccl_device float smooth_step(float edge0, float edge1, float x) { float result; @@ -138,6 +150,98 @@ ccl_device float smooth_step(float edge0, float edge1, float x) return result; } +ccl_device_inline void importance_sample_ggx_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 = 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 importance_sample_microfacet_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; + + importance_sample_ggx_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_NAMESPACE_END #endif /* __BSDF_UTIL_H__ */ diff --git a/intern/cycles/kernel/osl/bsdf_disney_clearcoat.cpp b/intern/cycles/kernel/osl/bsdf_disney_clearcoat.cpp index 864e42584e1..ee663ed4f33 100644 --- a/intern/cycles/kernel/osl/bsdf_disney_clearcoat.cpp +++ b/intern/cycles/kernel/osl/bsdf_disney_clearcoat.cpp @@ -36,6 +36,7 @@ #include "kernel_compat_cpu.h" #include "osl_closures.h" +#include "closure/bsdf_util.h" #include "kernel_types.h" #include "kernel_montecarlo.h" diff --git a/intern/cycles/kernel/osl/bsdf_disney_diffuse.cpp b/intern/cycles/kernel/osl/bsdf_disney_diffuse.cpp index 04a5b7940e4..fe2714dd899 100644 --- a/intern/cycles/kernel/osl/bsdf_disney_diffuse.cpp +++ b/intern/cycles/kernel/osl/bsdf_disney_diffuse.cpp @@ -36,6 +36,7 @@ #include "kernel_compat_cpu.h" #include "osl_closures.h" +#include "closure/bsdf_util.h" #include "kernel_types.h" #include "kernel_montecarlo.h" diff --git a/intern/cycles/kernel/osl/bsdf_disney_specular.cpp b/intern/cycles/kernel/osl/bsdf_disney_specular.cpp index df55a7e5876..f0e79e9e155 100644 --- a/intern/cycles/kernel/osl/bsdf_disney_specular.cpp +++ b/intern/cycles/kernel/osl/bsdf_disney_specular.cpp @@ -36,6 +36,7 @@ #include "kernel_compat_cpu.h" #include "osl_closures.h" +#include "closure/bsdf_util.h" #include "kernel_types.h" #include "kernel_montecarlo.h" diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h index 32924f9a8c2..c9a0233422f 100644 --- a/intern/cycles/util/util_math.h +++ b/intern/cycles/util/util_math.h @@ -77,6 +77,11 @@ CCL_NAMESPACE_BEGIN /* Scalar */ +ccl_device_inline float mix(float a, float b, float alpha) +{ + return a * (1.0f - alpha) + b * alpha; +} + #ifdef _WIN32 #ifndef __KERNEL_OPENCL__ @@ -221,6 +226,12 @@ ccl_device_inline float smoothstepf(float f) /* Float2 Vector */ +ccl_device_inline float2 mix(float2 a, float2 b, float alpha) +{ + float inv_alpha = 1.0f - alpha; + return make_float2(a[0] * inv_alpha + b[0] * alpha, a[1] * inv_alpha + b[1] * alpha); +} + #ifndef __KERNEL_OPENCL__ ccl_device_inline bool is_zero(const float2 a) @@ -412,6 +423,12 @@ ccl_device_inline float2 interp(float2 a, float2 b, float t) /* Float3 Vector */ +ccl_device_inline float3 mix(float3 a, float3 b, float alpha) +{ + float inv_alpha = 1.0f - alpha; + return make_float3(a[0] * inv_alpha + b[0] * alpha, a[1] * inv_alpha + b[1] * alpha, a[2] * inv_alpha + b[2] * alpha); +} + #ifndef __KERNEL_OPENCL__ ccl_device_inline float3 operator-(const float3 a) @@ -668,6 +685,13 @@ ccl_device_inline float average(const float3 a) /* Float4 Vector */ + +ccl_device_inline float4 mix(float4 a, float4 b, float alpha) +{ + float inv_alpha = 1.0f - alpha; + return make_float4(a[0] * inv_alpha + b[0] * alpha, a[1] * inv_alpha + b[1] * alpha, a[2] * inv_alpha + b[2] * alpha, a[3] * inv_alpha + b[3] * alpha); +} + #ifdef __KERNEL_SSE__ template __forceinline const float4 shuffle(const float4& b) From 419ee5441100a906b4b3fd8373cb768a71bfdfe6 Mon Sep 17 00:00:00 2001 From: Pascal Schoen Date: Tue, 17 May 2016 10:40:48 +0200 Subject: [PATCH 07/10] removed BsdfNode class inheritance for DisneyBsdfNode That's due to a naming difference. The Disney BSDF uses the name 'Base Color' while the BsdfNode had a 'Color' input. That caused a text message to be printed while rendering. --- intern/cycles/render/nodes.cpp | 4 ++++ intern/cycles/render/nodes.h | 12 +++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index bcf4e6709fd..965d51c39d1 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -2069,7 +2069,9 @@ void DiffuseBsdfNode::compile(OSLCompiler& compiler) /* Disney BSDF Closure */ DisneyBsdfNode::DisneyBsdfNode() + : ShaderNode("bsdf") { + special_type = SHADER_SPECIAL_TYPE_CLOSURE; closure = CLOSURE_BSDF_DISNEY_DIFFUSE_ID; add_input("BaseColor", SHADER_SOCKET_COLOR, make_float3(0.646f, 0.415f, 0.017f)); @@ -2083,7 +2085,9 @@ DisneyBsdfNode::DisneyBsdfNode() add_input("SheenTint", SHADER_SOCKET_FLOAT, 0.5f); add_input("Clearcoat", SHADER_SOCKET_FLOAT, 0.0f); add_input("ClearcoatGloss", SHADER_SOCKET_FLOAT, 1.0f); + add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL); add_input("Tangent", SHADER_SOCKET_VECTOR, ShaderInput::TANGENT); + add_input("SurfaceMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM); } void DisneyBsdfNode::compile(SVMCompiler& compiler) diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index c44bf207afe..5a256bf0a66 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -411,9 +411,19 @@ public: }; /* Disney BRDF */ -class DisneyBsdfNode : public BsdfNode { +class DisneyBsdfNode : public ShaderNode { public: SHADER_NODE_CLASS(DisneyBsdfNode) + + bool has_spatial_varying() { return true; } + + ClosureType closure; + + virtual bool equals(const ShaderNode * /*other*/) + { + /* TODO(sergey): With some care BSDF nodes can be de-duplicated. */ + return false; + } }; class TranslucentBsdfNode : public BsdfNode { From 7100640b65c2ff5447a18c01fc4e93594b4f486a Mon Sep 17 00:00:00 2001 From: Pascal Schoen Date: Tue, 17 May 2016 12:03:17 +0200 Subject: [PATCH 08/10] added output parameter to the DisneyBsdfNode That has been forgotten after removing the inheritance of BsdfNode --- intern/cycles/render/nodes.cpp | 30 ++++++++++++++++++++++++++++++ intern/cycles/render/nodes.h | 1 + 2 files changed, 31 insertions(+) diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 965d51c39d1..758c3451c65 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -2088,10 +2088,40 @@ DisneyBsdfNode::DisneyBsdfNode() add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL); add_input("Tangent", SHADER_SOCKET_VECTOR, ShaderInput::TANGENT); add_input("SurfaceMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM); + + add_output("BSDF", SHADER_SOCKET_CLOSURE); +} + +void DisneyBsdfNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2, ShaderInput *param3, ShaderInput *param4) +{ + ShaderInput *base_color_in = input("BaseColor"); + ShaderInput *normal_in = input("Normal"); + ShaderInput *tangent_in = input("Tangent"); + + if (base_color_in->link) + compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(base_color_in)); + else + compiler.add_node(NODE_CLOSURE_SET_WEIGHT, base_color_in->value); + + int normal_offset = compiler.stack_assign_if_linked(normal_in); + int tangent_offset = (tangent_in) ? compiler.stack_assign_if_linked(tangent_in) : SVM_STACK_INVALID; + int param3_offset = (param3) ? compiler.stack_assign(param3) : SVM_STACK_INVALID; + int param4_offset = (param4) ? compiler.stack_assign(param4) : SVM_STACK_INVALID; + + compiler.add_node(NODE_CLOSURE_BSDF, + compiler.encode_uchar4(closure, + (param1) ? compiler.stack_assign(param1) : SVM_STACK_INVALID, + (param2) ? compiler.stack_assign(param2) : SVM_STACK_INVALID, + compiler.closure_mix_weight_offset()), + __float_as_int((param1) ? param1->value.x : 0.0f), + __float_as_int((param2) ? param2->value.x : 0.0f)); + + compiler.add_node(normal_offset, tangent_offset, param3_offset, param4_offset); } void DisneyBsdfNode::compile(SVMCompiler& compiler) { + compile(compiler, NULL, NULL); } void DisneyBsdfNode::compile(OSLCompiler& compiler) diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 5a256bf0a66..479ba9dd8d8 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -416,6 +416,7 @@ public: SHADER_NODE_CLASS(DisneyBsdfNode) bool has_spatial_varying() { return true; } + void compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2, ShaderInput *param3 = NULL, ShaderInput *param4 = NULL); ClosureType closure; From f6499c2676e074a36033627ffc7540107777630d Mon Sep 17 00:00:00 2001 From: Pascal Schoen Date: Wed, 18 May 2016 10:19:57 +0200 Subject: [PATCH 09/10] Added additional variables for storing parameters in the ShaderClosure struct --- intern/cycles/kernel/kernel_types.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 02e69c7d75f..16d680d82db 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -648,11 +648,15 @@ typedef ccl_addr_space struct ShaderClosure { float3 N; float3 T; + float3 color0; + ClosureType type; float sample_weight; float data0; float data1; float data2; + float data3; + float data4; /* Following fields could be used to store pre-calculated * values by various BSDF closures for more effective sampling @@ -661,6 +665,7 @@ typedef ccl_addr_space struct ShaderClosure { float custom1; float custom2; float custom3; + float3 custom_color0; #ifdef __OSL__ void *prim, *pad4; From 6b5bab6cecde153122625cf8dc10e4209ed1eb0f Mon Sep 17 00:00:00 2001 From: Pascal Schoen Date: Wed, 18 May 2016 10:22:29 +0200 Subject: [PATCH 10/10] Switched from a parameter struct for Disney parameters to ShaderClosure params --- .../kernel/closure/bsdf_disney_clearcoat.h | 24 +++++----- .../kernel/closure/bsdf_disney_diffuse.h | 45 +++++++++-------- .../kernel/closure/bsdf_disney_specular.h | 48 +++++++++++++------ .../kernel/osl/bsdf_disney_clearcoat.cpp | 12 ++--- .../cycles/kernel/osl/bsdf_disney_diffuse.cpp | 18 +++---- .../kernel/osl/bsdf_disney_specular.cpp | 20 ++++---- intern/cycles/kernel/svm/svm_types.h | 4 +- 7 files changed, 98 insertions(+), 73 deletions(-) diff --git a/intern/cycles/kernel/closure/bsdf_disney_clearcoat.h b/intern/cycles/kernel/closure/bsdf_disney_clearcoat.h index 0300c56da5a..a96fc465b44 100644 --- a/intern/cycles/kernel/closure/bsdf_disney_clearcoat.h +++ b/intern/cycles/kernel/closure/bsdf_disney_clearcoat.h @@ -35,8 +35,7 @@ CCL_NAMESPACE_BEGIN -/* structures */ -struct DisneyClearcoatBRDFParams { +/*struct DisneyClearcoatBRDFParams { // brdf parameters float m_clearcoat; float m_clearcoatGloss; @@ -49,21 +48,24 @@ struct DisneyClearcoatBRDFParams { } }; -typedef struct DisneyClearcoatBRDFParams DisneyClearcoatBRDFParams; +typedef struct DisneyClearcoatBRDFParams DisneyClearcoatBRDFParams;*/ ccl_device int bsdf_disney_clearcoat_setup(ShaderClosure *sc) { + /* clearcoat roughness */ + sc->custom1 = mix(0.1f, 0.001f, sc->data1); + 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 DisneyClearcoatBRDFParams *params, */const float3 I, const float3 omega_in, float *pdf) { - if (params->m_clearcoat > 0.0f) { - float alpha = params->m_clearcoatRoughness; + if (sc->data0 > 0.0f) { + float alpha = sc->custom1; float3 N = sc->N; if (alpha <= 1e-4f) @@ -100,7 +102,7 @@ ccl_device float3 bsdf_disney_clearcoat_eval_reflect(const ShaderClosure *sc, float FH = schlick_fresnel(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; + float3 out = F * G * common * 0.25f * sc->data0; /* eq. 2 in distribution of visible normals sampling * pm = Dw = G1o * dot(m, I) * D / dot(N, I); */ @@ -122,13 +124,13 @@ ccl_device float3 bsdf_disney_clearcoat_eval_transmit(const ShaderClosure *sc, c return make_float3(0.0f, 0.0f, 0.0f); } -ccl_device int bsdf_disney_clearcoat_sample(const ShaderClosure *sc, const DisneyClearcoatBRDFParams *params, +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; + if (sc->data0 > 0.0f) { + float alpha = sc->custom1; float3 N = sc->N; float cosNO = dot(N, I); @@ -189,7 +191,7 @@ ccl_device int bsdf_disney_clearcoat_sample(const ShaderClosure *sc, const Disne float FH = schlick_fresnel(dot(*omega_in, m)); float3 F = mix(make_float3(0.04f, 0.04f, 0.04f), make_float3(1.0f, 1.0f, 1.0f), FH); - *eval = G1i * common * F * 0.25f * params->m_clearcoat; + *eval = G1i * common * F * 0.25f * sc->data0; } #ifdef __RAY_DIFFERENTIALS__ diff --git a/intern/cycles/kernel/closure/bsdf_disney_diffuse.h b/intern/cycles/kernel/closure/bsdf_disney_diffuse.h index 3e44277a30f..85a5db4a172 100644 --- a/intern/cycles/kernel/closure/bsdf_disney_diffuse.h +++ b/intern/cycles/kernel/closure/bsdf_disney_diffuse.h @@ -36,7 +36,7 @@ CCL_NAMESPACE_BEGIN -struct DisneyDiffuseBRDFParams { +/*struct DisneyDiffuseBRDFParams { // brdf parameters float3 m_base_color; float m_subsurface; @@ -45,23 +45,21 @@ struct DisneyDiffuseBRDFParams { float m_sheen_tint; // precomputed values - float3 m_cdlin, m_ctint, m_csheen; - float m_cdlum; + float3 m_csheen; void precompute_values() { - m_cdlin = m_base_color; - m_cdlum = 0.3f * m_cdlin[0] + 0.6f * m_cdlin[1] + 0.1f * m_cdlin[2]; // luminance approx. + float m_cdlum = 0.3f * m_base_color[0] + 0.6f * m_base_color[1] + 0.1f * m_base_color[2]; // luminance approx. - m_ctint = m_cdlum > 0.0f ? m_cdlin / m_cdlum : make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat + float3 m_ctint = m_cdlum > 0.0f ? m_base_color / m_cdlum : make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat m_csheen = mix(make_float3(1.0f, 1.0f, 1.0f), m_ctint, m_sheen_tint); } }; -typedef struct DisneyDiffuseBRDFParams DisneyDiffuseBRDFParams; +typedef struct DisneyDiffuseBRDFParams DisneyDiffuseBRDFParams;*/ ccl_device float3 calculate_disney_diffuse_brdf(const ShaderClosure *sc, - const DisneyDiffuseBRDFParams *params, float3 N, float3 V, float3 L, + /*const DisneyDiffuseBRDFParams *params, */float3 N, float3 V, float3 L, float3 H, float *pdf) { float NdotL = dot(N, L); @@ -77,27 +75,27 @@ ccl_device float3 calculate_disney_diffuse_brdf(const ShaderClosure *sc, float Fd = 0.0f; float FL = schlick_fresnel(NdotL), FV = schlick_fresnel(NdotV); - if (params->m_subsurface != 1.0f) { - const float Fd90 = 0.5f + 2.0f * LdotH*LdotH * params->m_roughness; + if (sc->data0 != 1.0f) { + const float Fd90 = 0.5f + 2.0f * LdotH*LdotH * sc->data1; Fd = mix(1.0f, Fd90, FL) * mix(1.0f, Fd90, FV); } - if (params->m_subsurface > 0.0f) { - float Fss90 = LdotH*LdotH * params->m_roughness; + if (sc->data0 > 0.0f) { + float Fss90 = LdotH*LdotH * sc->data1; float Fss = mix(1.0f, Fss90, FL) * mix(1.0f, Fss90, FV); float ss = 1.25f * (Fss * (1.0f / (NdotL + NdotV) - 0.5f) + 0.5f); - Fd = mix(Fd, ss, params->m_subsurface); + Fd = mix(Fd, ss, sc->data0); } - float3 value = M_1_PI_F * Fd * params->m_cdlin; + float3 value = M_1_PI_F * Fd * sc->color0; *pdf = M_1_PI_F * 0.5f; // sheen component - if (params->m_sheen != 0.0f) { + if (sc->data2 != 0.0f) { float FH = schlick_fresnel(LdotH); - value += FH * params->m_sheen * params->m_csheen; + value += FH * sc->data2 * sc->custom_color0; } value *= NdotL; @@ -107,12 +105,19 @@ ccl_device float3 calculate_disney_diffuse_brdf(const ShaderClosure *sc, ccl_device int bsdf_disney_diffuse_setup(ShaderClosure *sc) { + float m_cdlum = 0.3f * sc->color0[0] + 0.6f * sc->color0[1] + 0.1f * sc->color0[2]; // luminance approx. + + float3 m_ctint = m_cdlum > 0.0f ? sc->color0 / m_cdlum : make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat + + /* csheen0 */ + sc->custom_color0 = mix(make_float3(1.0f, 1.0f, 1.0f), m_ctint, sc->data3); + sc->type = CLOSURE_BSDF_DISNEY_DIFFUSE_ID; return SD_BSDF|SD_BSDF_HAS_EVAL; } ccl_device float3 bsdf_disney_diffuse_eval_reflect(const ShaderClosure *sc, - const DisneyDiffuseBRDFParams *params, const float3 I, + /*const DisneyDiffuseBRDFParams *params, */const float3 I, const float3 omega_in, float *pdf) { float3 N = normalize(sc->N); @@ -121,7 +126,7 @@ ccl_device float3 bsdf_disney_diffuse_eval_reflect(const ShaderClosure *sc, float3 H = normalize(L + V); if (dot(sc->N, omega_in) > 0.0f) { - float3 value = calculate_disney_diffuse_brdf(sc, params, N, V, L, H, pdf); + float3 value = calculate_disney_diffuse_brdf(sc, /*params, */N, V, L, H, pdf); return value; } @@ -136,7 +141,7 @@ ccl_device float3 bsdf_disney_diffuse_eval_transmit(const ShaderClosure *sc, con return make_float3(0.0f, 0.0f, 0.0f); } -ccl_device int bsdf_disney_diffuse_sample(const ShaderClosure *sc, const DisneyDiffuseBRDFParams *params, +ccl_device int bsdf_disney_diffuse_sample(const ShaderClosure *sc, /*const DisneyDiffuseBRDFParams *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) @@ -148,7 +153,7 @@ ccl_device int bsdf_disney_diffuse_sample(const ShaderClosure *sc, const DisneyD if (dot(Ng, *omega_in) > 0) { float3 H = normalize(I + *omega_in); - *eval = calculate_disney_diffuse_brdf(sc, params, N, I, *omega_in, H, pdf); + *eval = calculate_disney_diffuse_brdf(sc, /*params, */N, I, *omega_in, H, pdf); #ifdef __RAY_DIFFERENTIALS__ // TODO: find a better approximation for the diffuse bounce diff --git a/intern/cycles/kernel/closure/bsdf_disney_specular.h b/intern/cycles/kernel/closure/bsdf_disney_specular.h index 904d0f29663..44dd103f092 100644 --- a/intern/cycles/kernel/closure/bsdf_disney_specular.h +++ b/intern/cycles/kernel/closure/bsdf_disney_specular.h @@ -35,7 +35,7 @@ CCL_NAMESPACE_BEGIN -struct DisneySpecularBRDFParams { +/*struct DisneySpecularBRDFParams { // brdf parameters float3 m_base_color; float m_metallic; @@ -45,16 +45,15 @@ struct DisneySpecularBRDFParams { float m_anisotropic; // precomputed values - float3 m_cdlin, m_ctint, m_cspec0; - float m_cdlum; + float3 m_cspec0; float m_ax, m_ay; float m_roughg; void precompute_values() { - m_cdlin = m_base_color; - m_cdlum = 0.3f * m_cdlin[0] + 0.6f * m_cdlin[1] + 0.1f * m_cdlin[2]; // luminance approx. + float3 m_cdlin = m_base_color; + float m_cdlum = 0.3f * m_cdlin[0] + 0.6f * m_cdlin[1] + 0.1f * m_cdlin[2]; // luminance approx. - m_ctint = m_cdlum > 0.0f ? m_cdlin / m_cdlum : make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat + float3 m_ctint = m_cdlum > 0.0f ? m_cdlin / m_cdlum : make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat m_cspec0 = mix(m_specular * 0.08f * mix(make_float3(1.0f, 1.0f, 1.0f), m_ctint, m_specular_tint), m_cdlin, m_metallic); @@ -68,21 +67,40 @@ struct DisneySpecularBRDFParams { } }; -typedef struct DisneySpecularBRDFParams DisneySpecularBRDFParams; +typedef struct DisneySpecularBRDFParams DisneySpecularBRDFParams;*/ ccl_device int bsdf_disney_specular_setup(ShaderClosure *sc) { + float m_cdlum = 0.3f * sc->color0[0] + 0.6f * sc->color0[1] + 0.1f * sc->color0[2]; // luminance approx. + + float3 m_ctint = m_cdlum > 0.0f ? sc->color0 / m_cdlum : make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat + + sc->custom_color0 = mix(sc->data1 * 0.08f * mix(make_float3(1.0f, 1.0f, 1.0f), + m_ctint, sc->data2), sc->color0, sc->data0); + + float aspect = sqrt(1.0f - sc->data4 * 0.9f); + float r2 = sqr(sc->data3); + + /* ax */ + sc->custom1 = fmaxf(0.001f, r2 / aspect); + + /* ay */ + sc->custom2 = fmaxf(0.001f, r2 * aspect); + + /* rough_g */ + sc->custom3 = sqr(sc->data3 * 0.5f + 0.5f); + sc->type = CLOSURE_BSDF_DISNEY_SPECULAR_ID; return SD_BSDF|SD_BSDF_HAS_EVAL; } ccl_device float3 bsdf_disney_specular_eval_reflect(const ShaderClosure *sc, - const DisneySpecularBRDFParams *params, const float3 I, + /*const DisneySpecularBRDFParams *params, */const float3 I, const float3 omega_in, float *pdf) { - float alpha_x = params->m_ax; - float alpha_y = params->m_ay; + float alpha_x = sc->custom1; + float alpha_y = sc->custom2; float3 N = sc->N; if (fmaxf(alpha_x, alpha_y) <= 1e-4f) @@ -154,7 +172,7 @@ ccl_device float3 bsdf_disney_specular_eval_reflect(const ShaderClosure *sc, float common = D * 0.25f / cosNO; float FH = schlick_fresnel(dot(omega_in, m)); - float3 F = mix(params->m_cspec0, make_float3(1.0f, 1.0f, 1.0f), FH); + float3 F = mix(sc->custom_color0, make_float3(1.0f, 1.0f, 1.0f), FH); float3 out = F * G * common; @@ -177,13 +195,13 @@ ccl_device float3 bsdf_disney_specular_eval_transmit(const ShaderClosure *sc, co return make_float3(0.0f, 0.0f, 0.0f); } -ccl_device int bsdf_disney_specular_sample(const ShaderClosure *sc, const DisneySpecularBRDFParams *params, +ccl_device int bsdf_disney_specular_sample(const ShaderClosure *sc, /*const DisneySpecularBRDFParams *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) { - float alpha_x = params->m_ax; - float alpha_y = params->m_ay; + float alpha_x = sc->custom1; + float alpha_y = sc->custom2; float3 N = sc->N; float cosNO = dot(N, I); @@ -269,7 +287,7 @@ ccl_device int bsdf_disney_specular_sample(const ShaderClosure *sc, const Disney *pdf = common; float FH = schlick_fresnel(dot(*omega_in, m)); - float3 F = mix(params->m_cspec0, make_float3(1.0f, 1.0f, 1.0f), FH); + float3 F = mix(sc->custom_color0, make_float3(1.0f, 1.0f, 1.0f), FH); *eval = G1i * common * F; } diff --git a/intern/cycles/kernel/osl/bsdf_disney_clearcoat.cpp b/intern/cycles/kernel/osl/bsdf_disney_clearcoat.cpp index ee663ed4f33..d6202b5481c 100644 --- a/intern/cycles/kernel/osl/bsdf_disney_clearcoat.cpp +++ b/intern/cycles/kernel/osl/bsdf_disney_clearcoat.cpp @@ -48,7 +48,7 @@ using namespace OSL; class DisneyClearcoatClosure : public CBSDFClosure { public: - DisneyClearcoatBRDFParams dp; + //DisneyClearcoatBRDFParams dp; DisneyClearcoatClosure() : CBSDFClosure(LABEL_REFLECT|LABEL_GLOSSY) {} @@ -58,7 +58,7 @@ public: sc.prim = this; m_shaderdata_flag = bsdf_disney_clearcoat_setup(&sc); - dp.precompute_values(); + //dp.precompute_values(); } void blur(float roughness) @@ -67,7 +67,7 @@ public: float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float& pdf) const { - return bsdf_disney_clearcoat_eval_reflect(&sc, &dp, omega_out, omega_in, &pdf); + return bsdf_disney_clearcoat_eval_reflect(&sc, /*&dp, */omega_out, omega_in, &pdf); } float3 eval_transmit(const float3 &omega_out, const float3 &omega_in, float& pdf) const @@ -81,7 +81,7 @@ public: float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy, float &pdf, float3 &eval) const { - return bsdf_disney_clearcoat_sample(&sc, &dp, Ng, omega_out, domega_out_dx, domega_out_dy, + return bsdf_disney_clearcoat_sample(&sc, /*&dp, */Ng, omega_out, domega_out_dx, domega_out_dy, randu, randv, &eval, &omega_in, &domega_in_dx, &domega_in_dy, &pdf); } }; @@ -90,8 +90,8 @@ ClosureParam *closure_bsdf_disney_clearcoat_params() { static ClosureParam params[] = { CLOSURE_FLOAT3_PARAM(DisneyClearcoatClosure, sc.N), - CLOSURE_FLOAT_PARAM(DisneyClearcoatClosure, dp.m_clearcoat), - CLOSURE_FLOAT_PARAM(DisneyClearcoatClosure, dp.m_clearcoatGloss), + CLOSURE_FLOAT_PARAM(DisneyClearcoatClosure, sc.data0), /*clearcoat*/ + CLOSURE_FLOAT_PARAM(DisneyClearcoatClosure, sc.data1), /*clearcoat gloss*/ CLOSURE_STRING_KEYPARAM(DisneyClearcoatClosure, label, "label"), CLOSURE_FINISH_PARAM(DisneyClearcoatClosure) }; diff --git a/intern/cycles/kernel/osl/bsdf_disney_diffuse.cpp b/intern/cycles/kernel/osl/bsdf_disney_diffuse.cpp index fe2714dd899..b51cc80633a 100644 --- a/intern/cycles/kernel/osl/bsdf_disney_diffuse.cpp +++ b/intern/cycles/kernel/osl/bsdf_disney_diffuse.cpp @@ -48,7 +48,7 @@ using namespace OSL; class DisneyDiffuseClosure : public CBSDFClosure { public: - DisneyDiffuseBRDFParams dp; + //DisneyDiffuseBRDFParams dp; DisneyDiffuseClosure() : CBSDFClosure(LABEL_DIFFUSE) {} @@ -58,7 +58,7 @@ public: sc.prim = this; m_shaderdata_flag = bsdf_disney_diffuse_setup(&sc); - dp.precompute_values(); + //dp.precompute_values(); } void blur(float roughness) @@ -67,7 +67,7 @@ public: float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float& pdf) const { - return bsdf_disney_diffuse_eval_reflect(&sc, &dp, omega_out, omega_in, &pdf); + return bsdf_disney_diffuse_eval_reflect(&sc, /*&dp, */omega_out, omega_in, &pdf); } float3 eval_transmit(const float3 &omega_out, const float3 &omega_in, float& pdf) const @@ -79,7 +79,7 @@ public: const float3 &domega_out_dy, float randu, float randv, float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy, float &pdf, float3 &eval) const { - return bsdf_disney_diffuse_sample(&sc, &dp, Ng, omega_out, domega_out_dx, domega_out_dy, + return bsdf_disney_diffuse_sample(&sc, /*&dp, */Ng, omega_out, domega_out_dx, domega_out_dy, randu, randv, &eval, &omega_in, &domega_in_dx, &domega_in_dy, &pdf); } }; @@ -88,11 +88,11 @@ ClosureParam *closure_bsdf_disney_diffuse_params() { static ClosureParam params[] = { CLOSURE_FLOAT3_PARAM(DisneyDiffuseClosure, sc.N), - CLOSURE_FLOAT3_PARAM(DisneyDiffuseClosure, dp.m_base_color), - CLOSURE_FLOAT_PARAM(DisneyDiffuseClosure, dp.m_subsurface), - CLOSURE_FLOAT_PARAM(DisneyDiffuseClosure, dp.m_roughness), - CLOSURE_FLOAT_PARAM(DisneyDiffuseClosure, dp.m_sheen), - CLOSURE_FLOAT_PARAM(DisneyDiffuseClosure, dp.m_sheen_tint), + CLOSURE_FLOAT3_PARAM(DisneyDiffuseClosure, sc.color0), /*base color*/ + CLOSURE_FLOAT_PARAM(DisneyDiffuseClosure, sc.data0), /*subsurface*/ + CLOSURE_FLOAT_PARAM(DisneyDiffuseClosure, sc.data1), /*roughness*/ + CLOSURE_FLOAT_PARAM(DisneyDiffuseClosure, sc.data2), /*sheen*/ + CLOSURE_FLOAT_PARAM(DisneyDiffuseClosure, sc.data3), /*sheen tint*/ CLOSURE_STRING_KEYPARAM(DisneyDiffuseClosure, label, "label"), CLOSURE_FINISH_PARAM(DisneyDiffuseClosure) }; diff --git a/intern/cycles/kernel/osl/bsdf_disney_specular.cpp b/intern/cycles/kernel/osl/bsdf_disney_specular.cpp index f0e79e9e155..fad794fa497 100644 --- a/intern/cycles/kernel/osl/bsdf_disney_specular.cpp +++ b/intern/cycles/kernel/osl/bsdf_disney_specular.cpp @@ -48,7 +48,7 @@ using namespace OSL; class DisneySpecularClosure : public CBSDFClosure { public: - DisneySpecularBRDFParams dp; + //DisneySpecularBRDFParams dp; DisneySpecularClosure() : CBSDFClosure(LABEL_REFLECT|LABEL_GLOSSY) {} @@ -58,7 +58,7 @@ public: sc.prim = this; m_shaderdata_flag = bsdf_disney_specular_setup(&sc); - dp.precompute_values(); + //dp.precompute_values(); } void blur(float roughness) @@ -67,7 +67,7 @@ public: float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float& pdf) const { - return bsdf_disney_specular_eval_reflect(&sc, &dp, omega_out, omega_in, &pdf); + return bsdf_disney_specular_eval_reflect(&sc, /*&dp, */omega_out, omega_in, &pdf); } float3 eval_transmit(const float3 &omega_out, const float3 &omega_in, float& pdf) const @@ -79,7 +79,7 @@ public: const float3 &domega_out_dy, float randu, float randv, float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy, float &pdf, float3 &eval) const { - return bsdf_disney_specular_sample(&sc, &dp, Ng, omega_out, domega_out_dx, domega_out_dy, + return bsdf_disney_specular_sample(&sc, /*&dp, */Ng, omega_out, domega_out_dx, domega_out_dy, randu, randv, &eval, &omega_in, &domega_in_dx, &domega_in_dy, &pdf); } }; @@ -89,12 +89,12 @@ ClosureParam *closure_bsdf_disney_specular_params() static ClosureParam params[] = { CLOSURE_FLOAT3_PARAM(DisneySpecularClosure, sc.N), CLOSURE_FLOAT3_PARAM(DisneySpecularClosure, sc.T), - CLOSURE_FLOAT3_PARAM(DisneySpecularClosure, dp.m_base_color), - CLOSURE_FLOAT_PARAM(DisneySpecularClosure, dp.m_metallic), - CLOSURE_FLOAT_PARAM(DisneySpecularClosure, dp.m_specular), - CLOSURE_FLOAT_PARAM(DisneySpecularClosure, dp.m_specular_tint), - CLOSURE_FLOAT_PARAM(DisneySpecularClosure, dp.m_roughness), - CLOSURE_FLOAT_PARAM(DisneySpecularClosure, dp.m_anisotropic), + CLOSURE_FLOAT3_PARAM(DisneySpecularClosure, sc.color0), /*base color*/ + CLOSURE_FLOAT_PARAM(DisneySpecularClosure, sc.data0), /*metallic*/ + CLOSURE_FLOAT_PARAM(DisneySpecularClosure, sc.data1), /*specular*/ + CLOSURE_FLOAT_PARAM(DisneySpecularClosure, sc.data2), /*specular tint*/ + CLOSURE_FLOAT_PARAM(DisneySpecularClosure, sc.data3), /*roughness*/ + CLOSURE_FLOAT_PARAM(DisneySpecularClosure, sc.data4), /*anisotropic*/ CLOSURE_STRING_KEYPARAM(DisneySpecularClosure, label, "label"), CLOSURE_FINISH_PARAM(DisneySpecularClosure) }; diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index b5cbf9669bc..a67922494bb 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -376,8 +376,8 @@ typedef enum ClosureType { CLOSURE_BSDF_DIFFUSE_ID, CLOSURE_BSDF_OREN_NAYAR_ID, CLOSURE_BSDF_DIFFUSE_RAMP_ID, - CLOSURE_BSDF_DIFFUSE_TOON_ID, CLOSURE_BSDF_DISNEY_DIFFUSE_ID, + CLOSURE_BSDF_DIFFUSE_TOON_ID, /* Glossy */ CLOSURE_BSDF_GLOSSY_ID, @@ -391,9 +391,9 @@ typedef enum ClosureType { CLOSURE_BSDF_ASHIKHMIN_VELVET_ID, CLOSURE_BSDF_PHONG_RAMP_ID, CLOSURE_BSDF_GLOSSY_TOON_ID, - CLOSURE_BSDF_HAIR_REFLECTION_ID, CLOSURE_BSDF_DISNEY_SPECULAR_ID, CLOSURE_BSDF_DISNEY_CLEARCOAT_ID, + CLOSURE_BSDF_HAIR_REFLECTION_ID, /* Transmission */ CLOSURE_BSDF_TRANSMISSION_ID,