Commit: 8ce1090d4e8160165281be4b0827dbc1ba28dc8a
Author: Karsten Schwenk
Date:   Sun Jun 8 12:16:28 2014 +0200
https://developer.blender.org/rB8ce1090d4e8160165281be4b0827dbc1ba28dc8a

Cycles: Ashikhmin-Shirley anisotropic BSDF

* Ashikhmin-Shirley anisotropic BSDF was added as closure
* Anisotropic BSDF node now has two distributions

Reviewers: brecht, dingto

Differential Revision: https://developer.blender.org/D549

===================================================================

M       intern/cycles/app/cycles_xml.cpp
M       intern/cycles/blender/blender_shader.cpp
M       intern/cycles/kernel/CMakeLists.txt
M       intern/cycles/kernel/closure/bsdf.h
A       intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
M       intern/cycles/kernel/osl/osl_closures.cpp
M       intern/cycles/kernel/shaders/CMakeLists.txt
A       intern/cycles/kernel/shaders/node_anisotropic_bsdf.osl
D       intern/cycles/kernel/shaders/node_ward_bsdf.osl
M       intern/cycles/kernel/shaders/stdosl.h
M       intern/cycles/kernel/svm/svm_closure.h
M       intern/cycles/kernel/svm/svm_types.h
M       intern/cycles/render/nodes.cpp
M       intern/cycles/render/nodes.h
M       source/blender/editors/space_node/drawnode.c
M       source/blender/makesdna/DNA_node_types.h
M       source/blender/makesrna/intern/rna_nodetree.c
M       source/blender/nodes/NOD_static_types.h

===================================================================

diff --git a/intern/cycles/app/cycles_xml.cpp b/intern/cycles/app/cycles_xml.cpp
index f50a952..915ef96 100644
--- a/intern/cycles/app/cycles_xml.cpp
+++ b/intern/cycles/app/cycles_xml.cpp
@@ -509,8 +509,10 @@ static void xml_read_shader_graph(const XMLReadState& 
state, Shader *shader, pug
                else if(string_iequals(node.name(), "mapping")) {
                        snode = new MappingNode();
                }
-               else if(string_iequals(node.name(), "ward_bsdf")) {
-                       snode = new WardBsdfNode();
+               else if(string_iequals(node.name(), "anisotropic_bsdf")) {
+                       AnisotropicBsdfNode *aniso = new AnisotropicBsdfNode();
+                       xml_read_enum(&aniso->distribution, 
AnisotropicBsdfNode::distribution_enum, node, "distribution");
+                       snode = aniso;
                }
                else if(string_iequals(node.name(), "diffuse_bsdf")) {
                        snode = new DiffuseBsdfNode();
diff --git a/intern/cycles/blender/blender_shader.cpp 
b/intern/cycles/blender/blender_shader.cpp
index 3b783d3..226e7a7 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -318,7 +318,21 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData 
b_data, BL::Scene b_scen
                node = new HoldoutNode();
        }
        else if (b_node.is_a(&RNA_ShaderNodeBsdfAnisotropic)) {
-               node = new WardBsdfNode();
+               BL::ShaderNodeBsdfAnisotropic b_aniso_node(b_node);
+               AnisotropicBsdfNode *aniso = new AnisotropicBsdfNode();
+
+               switch (b_aniso_node.distribution())
+               {
+               case 
BL::ShaderNodeBsdfAnisotropic::distribution_ASHIKHMIN_SHIRLEY:
+                       aniso->distribution = ustring("Ashikhmin-Shirley");
+                       break;
+               case BL::ShaderNodeBsdfAnisotropic::distribution_WARD:
+               default:
+                       aniso->distribution = ustring("Ward");
+                       break;
+               }
+
+               node = aniso;
        }
        else if (b_node.is_a(&RNA_ShaderNodeBsdfDiffuse)) {
                node = new DiffuseBsdfNode();
diff --git a/intern/cycles/kernel/CMakeLists.txt 
b/intern/cycles/kernel/CMakeLists.txt
index d34a045..6b6fcb1 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -61,6 +61,7 @@ set(SRC_CLOSURE_HEADERS
        closure/bsdf_transparent.h
        closure/bsdf_util.h
        closure/bsdf_ward.h
+       closure/bsdf_ashikhmin_shirley.h
        closure/bsdf_westin.h
        closure/bsdf_hair.h
        closure/bssrdf.h
diff --git a/intern/cycles/kernel/closure/bsdf.h 
b/intern/cycles/kernel/closure/bsdf.h
index 24b54cd..371d0bf 100644
--- a/intern/cycles/kernel/closure/bsdf.h
+++ b/intern/cycles/kernel/closure/bsdf.h
@@ -25,6 +25,7 @@
 #include "../closure/bsdf_transparent.h"
 #ifdef __ANISOTROPIC__
 #include "../closure/bsdf_ward.h"
+#include "../closure/bsdf_ashikhmin_shirley.h"
 #endif
 #include "../closure/bsdf_westin.h"
 #include "../closure/bsdf_toon.h"
@@ -97,6 +98,10 @@ ccl_device int bsdf_sample(KernelGlobals *kg, const 
ShaderData *sd, const Shader
                        label = bsdf_ward_sample(sc, sd->Ng, sd->I, sd->dI.dx, 
sd->dI.dy, randu, randv,
                                eval, omega_in, &domega_in->dx, &domega_in->dy, 
pdf);
                        break;
+               case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
+                       label = bsdf_ashikhmin_shirley_sample(sc, sd->Ng, 
sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
+                               eval, omega_in, &domega_in->dx, &domega_in->dy, 
pdf);
+                       break;
 #endif
                case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
                        label = bsdf_ashikhmin_velvet_sample(sc, sd->Ng, sd->I, 
sd->dI.dx, sd->dI.dy, randu, randv,
@@ -189,6 +194,9 @@ ccl_device float3 bsdf_eval(KernelGlobals *kg, const 
ShaderData *sd, const Shade
                        case CLOSURE_BSDF_WARD_ID:
                                eval = bsdf_ward_eval_reflect(sc, sd->I, 
omega_in, pdf);
                                break;
+                       case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
+                               eval = bsdf_ashikhmin_shirley_eval_reflect(sc, 
sd->I, omega_in, pdf);
+                               break;
 #endif
                        case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
                                eval = bsdf_ashikhmin_velvet_eval_reflect(sc, 
sd->I, omega_in, pdf);
@@ -256,6 +264,9 @@ ccl_device float3 bsdf_eval(KernelGlobals *kg, const 
ShaderData *sd, const Shade
                        case CLOSURE_BSDF_WARD_ID:
                                eval = bsdf_ward_eval_transmit(sc, sd->I, 
omega_in, pdf);
                                break;
+                       case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
+                               eval = bsdf_ashikhmin_shirley_eval_transmit(sc, 
sd->I, omega_in, pdf);
+                               break;
 #endif
                        case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
                                eval = bsdf_ashikhmin_velvet_eval_transmit(sc, 
sd->I, omega_in, pdf);
@@ -341,6 +352,9 @@ ccl_device void bsdf_blur(KernelGlobals *kg, ShaderClosure 
*sc, float roughness)
                case CLOSURE_BSDF_WARD_ID:
                        bsdf_ward_blur(sc, roughness);
                        break;
+               case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
+                       bsdf_ashikhmin_shirley_blur(sc, roughness);
+                       break;
 #endif
                case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
                        bsdf_ashikhmin_velvet_blur(sc, roughness);
diff --git a/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h 
b/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
new file mode 100644
index 0000000..ea5b610
--- /dev/null
+++ b/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
@@ -0,0 +1,196 @@
+/*
+ * 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
+ */
+
+#ifndef __BSDF_ASHIKHMIN_SHIRLEY_H__
+#define __BSDF_ASHIKHMIN_SHIRLEY_H__
+
+/*
+ASHIKHMIN SHIRLEY BSDF
+
+Implementation of
+Michael Ashikhmin and Peter Shirley: "An Anisotropic Phong BRDF Model" (2000)
+
+The Fresnel factor is missing to get a separable bsdf (intensity*color), as is
+the case with all other microfacet-based BSDF implementations in Cycles.
+
+Other than that, the implementation directly follows the paper.
+*/
+
+CCL_NAMESPACE_BEGIN
+
+
+ccl_device int bsdf_ashikhmin_shirley_setup(ShaderClosure *sc)
+{
+       sc->data0 = clamp(sc->data0, 1e-4f, 1.0f); /* store roughness. could 
already convert to exponent to save some cycles in eval, */
+       sc->data1 = clamp(sc->data1, 1e-4f, 1.0f); /* but this is more 
consistent with other bsdfs and shader_blur. */
+
+       sc->type = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID;
+       return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_GLOSSY;
+}
+
+ccl_device void bsdf_ashikhmin_shirley_blur(ShaderClosure *sc, float roughness)
+{
+       sc->data0 = fmaxf(roughness, sc->data0); /* clamp roughness */
+       sc->data1 = fmaxf(roughness, sc->data1);
+}
+
+ccl_device_inline float bsdf_ashikhmin_shirley_roughness_to_exponent(float 
roughness)
+{
+       return 2.0f / (roughness*roughness) - 2.0f;
+}
+
+ccl_device float3 bsdf_ashikhmin_shirley_eval_reflect(const ShaderClosure *sc, 
const float3 I, const float3 omega_in, float *pdf)
+{
+       float3 N = sc->N;
+       float3 T = sc->T;
+
+       float NdotI = dot(N, I);           /* in Cycles/OSL convention I is 
omega_out    */
+       float NdotO = dot(N, omega_in);    /* and consequently we use for O 
omaga_in ;)  */
+
+       float out = 0.0f;
+
+       if (NdotI > 0.0f && NdotO > 0.0f) {
+               NdotI = fmaxf(NdotI, 1e-6f);
+               NdotO = fmaxf(NdotO, 1e-6f);
+               float3 H = normalize(omega_in + I);
+               float HdotI = fmaxf(dot(H, I), 1e-6f);
+               float HdotN = fmaxf(dot(H, N), 1e-6f);
+
+               float pump = 1.0f / fmaxf(1e-6f, (HdotI*fmaxf(NdotO, NdotI))); 
/* pump from original paper (first derivative disc., but cancels the HdotI in 
the pdf nicely) */
+               /*float pump = 1.0f / fmaxf(1e-4f, ((NdotO + NdotI) * 
(NdotO*NdotI))); */ /* pump from d-brdf paper */
+
+               float n_x = 
bsdf_ashikhmin_shirley_roughness_to_exponent(sc->data0);
+               float n_y = 
bsdf_ashikhmin_shirley_roughness_to_exponent(sc->data1);
+
+               if (n_x == n_y) {  /* => isotropic case */
+                       float e = n_x;
+                       float lobe = powf(HdotN, e);
+                       float norm = (n_x + 1.0f) / (8.0f * M_PI_F);
+
+                       out = NdotO * norm * lobe * pump;
+                       *pdf = norm * lobe / HdotI; /* this is p_h / 4(H.I)  
(conversion from 'wh measure' to 'wi measure', eq. 8 in paper) */
+               }
+               else {             /* => ANisotropic case */
+                       float3 X, Y;
+                       make_orthonormals_tangent(N, T, &X, &Y);
+
+                       float HdotX = dot(H, X);
+                       float HdotY = dot(H, Y);
+                       float e = (n_x * HdotX*HdotX + n_y * HdotY*HdotY) / 
(1.0f - HdotN*HdotN);
+                       float lobe = powf(HdotN, e);
+                       float norm = sqrtf((n_x + 1.0f)*(n_y + 1.0f)) / (8.0f * 
M_PI_F);
+                       
+                       out = NdotO * norm * lobe * pump;
+                       *pdf = norm * lobe / HdotI;
+               }
+       }
+
+       return make_float3(out, out, out);
+}
+
+ccl_device float3 bsdf_ashikhmin_shirley_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_inline void bsdf_ashikhmin_shirley_sample_first_quadrant(float n_x, 
float n_y, float randu, float randv, float *phi, float *cos_theta)
+{
+       *phi = atanf(sqrtf((n_x + 1.0f) / (n_y + 1.0f)) * tanf(M_PI_2_F * 
randu));
+       float cos_phi = cosf(*phi);
+       float sin_phi = sinf(*phi);
+       *cos_theta = powf(randv, 1.0f / (n_x * cos_phi*cos_phi + n_y * 
sin_phi*sin_phi + 1.0f));
+}
+
+ccl_device int bsdf_ashikhmin_shirley_sample(const ShaderClosure *sc, 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 T = sc->T;
+
+       float NdotI = dot(N, I);
+       if (NdotI > 0.0f) {
+
+               float n_x = 
bsdf_ashikhmin_shirley_roughness_to_exponent(sc->data0);
+               float n_y = 
bsdf_ashikhmin_shirley_roughness_to_exponent(sc->data1);
+
+               /* get x,y basis on the surface for anisotropy */
+               float3 X, Y;
+               make_orthonormals_tangent(N, T, &X, &Y);
+
+               /* sample spherical coords for h in tangent space */
+               float phi;
+               float cos_theta;
+               if (n_x == n_y) {  /* => simple isotropic sampling */
+                       phi = M_2PI_F * randu;
+                       cos_theta = powf(randv, 1.0f / (n_x + 1.0f));
+               }
+               else {             /* => more complex anisotropic sampling */
+                       if (randu < 0.25f) {      /* first quadrant */
+                               float remapped_randu = 4.0f * randu;
+                               
bsdf_ashikhmin_shirley_sample_first_quadrant(n_x, n_y, remapped_randu, randv, 
&phi, &cos_theta);
+                       }
+                       else if (randu < 0.5f) {  /* second quadrant */
+                               float remapped_randu = 4.0f * (.5f - randu);
+                               bsdf_ashikhmi

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to