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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2014-06-08 14:46:12 +0400
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2014-06-14 15:49:57 +0400
commitb12151eceb76cab4a49f9df661ce6156bbeaaa21 (patch)
treec2815e24e4bc45e840efc6ff1069684c5c4a3049 /intern
parentceb68e809edf37ea3fd010692dc3f4367b78cf61 (diff)
Cycles: glossy and anisotropic BSDF changes
* Anisotropic BSDF now supports GGX and Beckmann distributions, Ward has been removed because other distributions are superior. * GGX is now the default distribution for all glossy and anisotropic nodes, since it looks good, has low noise and is fast to evaluate. * Ashikhmin-Shirley is now available in the Glossy BSDF.
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/blender/blender_shader.cpp16
-rw-r--r--intern/cycles/kernel/CMakeLists.txt1
-rw-r--r--intern/cycles/kernel/closure/bsdf.h26
-rw-r--r--intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h28
-rw-r--r--intern/cycles/kernel/closure/bsdf_microfacet.h4
-rw-r--r--intern/cycles/kernel/closure/bsdf_ward.h189
-rw-r--r--intern/cycles/kernel/osl/osl_closures.cpp34
-rw-r--r--intern/cycles/kernel/shaders/node_anisotropic_bsdf.osl12
-rw-r--r--intern/cycles/kernel/shaders/node_glossy_bsdf.osl4
-rw-r--r--intern/cycles/kernel/shaders/stdosl.h3
-rw-r--r--intern/cycles/kernel/svm/svm_closure.h20
-rw-r--r--intern/cycles/kernel/svm/svm_types.h6
-rw-r--r--intern/cycles/render/nodes.cpp15
13 files changed, 107 insertions, 251 deletions
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index 226e7a76dda..318ca10b81a 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -323,13 +323,18 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
switch (b_aniso_node.distribution())
{
+ case BL::ShaderNodeBsdfAnisotropic::distribution_SHARP:
+ aniso->distribution = ustring("Sharp");
+ break;
+ case BL::ShaderNodeBsdfAnisotropic::distribution_BECKMANN:
+ aniso->distribution = ustring("Beckmann");
+ break;
+ case BL::ShaderNodeBsdfAnisotropic::distribution_GGX:
+ aniso->distribution = ustring("GGX");
+ break;
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;
@@ -367,6 +372,9 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
case BL::ShaderNodeBsdfGlossy::distribution_GGX:
glossy->distribution = ustring("GGX");
break;
+ case BL::ShaderNodeBsdfGlossy::distribution_ASHIKHMIN_SHIRLEY:
+ glossy->distribution = ustring("Ashikhmin-Shirley");
+ break;
}
node = glossy;
}
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index 6b6fcb10ba8..58142eec556 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -60,7 +60,6 @@ set(SRC_CLOSURE_HEADERS
closure/bsdf_toon.h
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
diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h
index 371d0bfa8ea..8ddf4971909 100644
--- a/intern/cycles/kernel/closure/bsdf.h
+++ b/intern/cycles/kernel/closure/bsdf.h
@@ -24,7 +24,6 @@
#include "../closure/bsdf_refraction.h"
#include "../closure/bsdf_transparent.h"
#ifdef __ANISOTROPIC__
-#include "../closure/bsdf_ward.h"
#include "../closure/bsdf_ashikhmin_shirley.h"
#endif
#include "../closure/bsdf_westin.h"
@@ -84,21 +83,20 @@ ccl_device int bsdf_sample(KernelGlobals *kg, const ShaderData *sd, const Shader
eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
case CLOSURE_BSDF_MICROFACET_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
label = bsdf_microfacet_ggx_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
label = bsdf_microfacet_beckmann_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
#ifdef __ANISOTROPIC__
- case CLOSURE_BSDF_WARD_ID:
- 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:
+ case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_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;
@@ -183,18 +181,18 @@ ccl_device float3 bsdf_eval(KernelGlobals *kg, const ShaderData *sd, const Shade
eval = bsdf_transparent_eval_reflect(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_MICROFACET_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
eval = bsdf_microfacet_ggx_eval_reflect(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
eval = bsdf_microfacet_beckmann_eval_reflect(sc, sd->I, omega_in, pdf);
break;
#ifdef __ANISOTROPIC__
- case CLOSURE_BSDF_WARD_ID:
- eval = bsdf_ward_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
+ case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID:
eval = bsdf_ashikhmin_shirley_eval_reflect(sc, sd->I, omega_in, pdf);
break;
#endif
@@ -253,18 +251,18 @@ ccl_device float3 bsdf_eval(KernelGlobals *kg, const ShaderData *sd, const Shade
eval = bsdf_transparent_eval_transmit(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_MICROFACET_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
eval = bsdf_microfacet_ggx_eval_transmit(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
eval = bsdf_microfacet_beckmann_eval_transmit(sc, sd->I, omega_in, pdf);
break;
#ifdef __ANISOTROPIC__
- case CLOSURE_BSDF_WARD_ID:
- eval = bsdf_ward_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
+ case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID:
eval = bsdf_ashikhmin_shirley_eval_transmit(sc, sd->I, omega_in, pdf);
break;
#endif
@@ -341,18 +339,18 @@ ccl_device void bsdf_blur(KernelGlobals *kg, ShaderClosure *sc, float roughness)
bsdf_transparent_blur(sc, roughness);
break;
case CLOSURE_BSDF_MICROFACET_GGX_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
bsdf_microfacet_ggx_blur(sc, roughness);
break;
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
bsdf_microfacet_beckmann_blur(sc, roughness);
break;
#ifdef __ANISOTROPIC__
- case CLOSURE_BSDF_WARD_ID:
- bsdf_ward_blur(sc, roughness);
- break;
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
+ case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID:
bsdf_ashikhmin_shirley_blur(sc, roughness);
break;
#endif
diff --git a/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h b/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
index ea5b610ae56..6a5d0410e01 100644
--- a/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
+++ b/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
@@ -31,16 +31,28 @@ 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. */
+ /* store roughness. could already convert to exponent to save some cycles
+ * in eval, but this is more consistent with other bsdfs and shader_blur. */
+ sc->data0 = clamp(sc->data0, 1e-4f, 1.0f);
+ sc->data1 = sc->data0;
sc->type = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID;
return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_GLOSSY;
}
+ccl_device int bsdf_ashikhmin_shirley_aniso_setup(ShaderClosure *sc)
+{
+ /* store roughness. could already convert to exponent to save some cycles
+ * in eval, but this is more consistent with other bsdfs and shader_blur. */
+ sc->data0 = clamp(sc->data0, 1e-4f, 1.0f);
+ sc->data1 = clamp(sc->data1, 1e-4f, 1.0f);
+
+ sc->type = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_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 */
@@ -55,7 +67,6 @@ ccl_device_inline float bsdf_ashikhmin_shirley_roughness_to_exponent(float rough
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 ;) */
@@ -85,7 +96,7 @@ ccl_device float3 bsdf_ashikhmin_shirley_eval_reflect(const ShaderClosure *sc, c
}
else { /* => ANisotropic case */
float3 X, Y;
- make_orthonormals_tangent(N, T, &X, &Y);
+ make_orthonormals_tangent(N, sc->T, &X, &Y);
float HdotX = dot(H, X);
float HdotY = dot(H, Y);
@@ -117,7 +128,6 @@ ccl_device_inline void bsdf_ashikhmin_shirley_sample_first_quadrant(float n_x, f
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) {
@@ -127,7 +137,11 @@ ccl_device int bsdf_ashikhmin_shirley_sample(const ShaderClosure *sc, float3 Ng,
/* get x,y basis on the surface for anisotropy */
float3 X, Y;
- make_orthonormals_tangent(N, T, &X, &Y);
+
+ if(n_x == n_y)
+ make_orthonormals(N, &X, &Y);
+ else
+ make_orthonormals_tangent(N, sc->T, &X, &Y);
/* sample spherical coords for h in tangent space */
float phi;
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h
index b9b682c650f..4a3d223d765 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet.h
@@ -365,7 +365,7 @@ ccl_device int bsdf_microfacet_ggx_aniso_setup(ShaderClosure *sc)
sc->data0 = clamp(sc->data0, 0.0f, 1.0f); /* alpha_x */
sc->data1 = clamp(sc->data1, 0.0f, 1.0f); /* alpha_y */
- sc->type = CLOSURE_BSDF_MICROFACET_GGX_ID;
+ sc->type = CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID;
return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
}
@@ -713,7 +713,7 @@ ccl_device int bsdf_microfacet_beckmann_aniso_setup(ShaderClosure *sc)
sc->data0 = clamp(sc->data0, 0.0f, 1.0f); /* alpha_x */
sc->data1 = clamp(sc->data1, 0.0f, 1.0f); /* alpha_y */
- sc->type = CLOSURE_BSDF_MICROFACET_BECKMANN_ID;
+ sc->type = CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID;
return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
}
diff --git a/intern/cycles/kernel/closure/bsdf_ward.h b/intern/cycles/kernel/closure/bsdf_ward.h
deleted file mode 100644
index c9de615a011..00000000000
--- a/intern/cycles/kernel/closure/bsdf_ward.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * 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_WARD_H__
-#define __BSDF_WARD_H__
-
-CCL_NAMESPACE_BEGIN
-
-/* WARD */
-
-ccl_device int bsdf_ward_setup(ShaderClosure *sc)
-{
- sc->data0 = clamp(sc->data0, 1e-4f, 1.0f); /* m_ax */
- sc->data1 = clamp(sc->data1, 1e-4f, 1.0f); /* m_ay */
-
- sc->type = CLOSURE_BSDF_WARD_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
-}
-
-ccl_device void bsdf_ward_blur(ShaderClosure *sc, float roughness)
-{
- sc->data0 = fmaxf(roughness, sc->data0); /* m_ax */
- sc->data1 = fmaxf(roughness, sc->data1); /* m_ay */
-}
-
-ccl_device float3 bsdf_ward_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
-{
- float m_ax = sc->data0;
- float m_ay = sc->data1;
- float3 N = sc->N;
- float3 T = sc->T;
-
- float cosNO = dot(N, I);
- float cosNI = dot(N, omega_in);
-
- if(cosNI > 0.0f && cosNO > 0.0f) {
- cosNO = max(cosNO, 1e-4f);
- cosNI = max(cosNI, 1e-4f);
-
- // get half vector and get x,y basis on the surface for anisotropy
- float3 H = normalize(omega_in + I); // normalize needed for pdf
- float3 X, Y;
- make_orthonormals_tangent(N, T, &X, &Y);
- // eq. 4
- float dotx = dot(H, X) / m_ax;
- float doty = dot(H, Y) / m_ay;
- float dotn = dot(H, N);
- float exp_arg = (dotx * dotx + doty * doty) / (dotn * dotn);
- float denom = (M_4PI_F * m_ax * m_ay * sqrtf(cosNO * cosNI));
- float exp_val = expf(-exp_arg);
- float out = cosNI * exp_val / denom;
- float oh = dot(H, I);
- denom = M_4PI_F * m_ax * m_ay * oh * dotn * dotn * dotn;
- *pdf = exp_val / denom;
- return make_float3 (out, out, out);
- }
-
- return make_float3 (0, 0, 0);
-}
-
-ccl_device float3 bsdf_ward_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_ward_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)
-{
- float m_ax = sc->data0;
- float m_ay = sc->data1;
- float3 N = sc->N;
- float3 T = sc->T;
-
- float cosNO = dot(N, I);
- if(cosNO > 0.0f) {
- // get x,y basis on the surface for anisotropy
- float3 X, Y;
- make_orthonormals_tangent(N, T, &X, &Y);
- // generate random angles for the half vector
- // eq. 7 (taking care around discontinuities to keep
- //ttoutput angle in the right quadrant)
- // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2)
- //tttt and sin(atan(x)) == x/sqrt(1+x^2)
- float alphaRatio = m_ay / m_ax;
- float cosPhi, sinPhi;
- if(randu < 0.25f) {
- float val = 4 * randu;
- float tanPhi = alphaRatio * tanf(M_PI_2_F * val);
- cosPhi = 1 / sqrtf(1 + tanPhi * tanPhi);
- sinPhi = tanPhi * cosPhi;
- }
- else if(randu < 0.5f) {
- float val = 1 - 4 * (0.5f - randu);
- float tanPhi = alphaRatio * tanf(M_PI_2_F * val);
- // phi = M_PI_F - phi;
- cosPhi = -1 / sqrtf(1 + tanPhi * tanPhi);
- sinPhi = -tanPhi * cosPhi;
- }
- else if(randu < 0.75f) {
- float val = 4 * (randu - 0.5f);
- float tanPhi = alphaRatio * tanf(M_PI_2_F * val);
- //phi = M_PI_F + phi;
- cosPhi = -1 / sqrtf(1 + tanPhi * tanPhi);
- sinPhi = tanPhi * cosPhi;
- }
- else {
- float val = 1 - 4 * (1 - randu);
- float tanPhi = alphaRatio * tanf(M_PI_2_F * val);
- // phi = M_2PI_F - phi;
- cosPhi = 1 / sqrtf(1 + tanPhi * tanPhi);
- sinPhi = -tanPhi * cosPhi;
- }
- // eq. 6
- // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2)
- //tttt and sin(atan(x)) == x/sqrt(1+x^2)
- float thetaDenom = (cosPhi * cosPhi) / (m_ax * m_ax) + (sinPhi * sinPhi) / (m_ay * m_ay);
- float tanTheta2 = -logf(1 - randv) / thetaDenom;
- float cosTheta = 1 / sqrtf(1 + tanTheta2);
- float sinTheta = cosTheta * sqrtf(tanTheta2);
-
- float3 h; // already normalized becaused expressed from spherical coordinates
- h.x = sinTheta * cosPhi;
- h.y = sinTheta * sinPhi;
- h.z = cosTheta;
- // compute terms that are easier in local space
- float dotx = h.x / m_ax;
- float doty = h.y / m_ay;
- float dotn = h.z;
- // transform to world space
- h = h.x * X + h.y * Y + h.z * N;
- // generate the final sample
- float oh = dot(h, I);
- *omega_in = 2.0f * oh * h - I;
- if(dot(Ng, *omega_in) > 0) {
- float cosNI = dot(N, *omega_in);
- if(cosNI > 0) {
- cosNO = max(cosNO, 1e-4f);
- cosNI = max(cosNI, 1e-4f);
-
- // eq. 9
- float exp_arg = (dotx * dotx + doty * doty) / (dotn * dotn);
- float denom = M_4PI_F * m_ax * m_ay * oh * dotn * dotn * dotn;
- *pdf = expf(-exp_arg) / denom;
- // compiler will reuse expressions already computed
- denom = (M_4PI_F * m_ax * m_ay * sqrtf(cosNO * cosNI));
- float power = cosNI * expf(-exp_arg) / denom;
- *eval = make_float3(power, power, power);
-#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_GLOSSY;
-}
-
-CCL_NAMESPACE_END
-
-#endif /* __BSDF_WARD_H__ */
-
diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp
index c8324ec1f9a..c1560ea2d01 100644
--- a/intern/cycles/kernel/osl/osl_closures.cpp
+++ b/intern/cycles/kernel/osl/osl_closures.cpp
@@ -51,7 +51,6 @@
#include "closure/bsdf_reflection.h"
#include "closure/bsdf_refraction.h"
#include "closure/bsdf_transparent.h"
-#include "closure/bsdf_ward.h"
#include "closure/bsdf_ashikhmin_shirley.h"
#include "closure/bsdf_westin.h"
#include "closure/bsdf_toon.h"
@@ -104,19 +103,12 @@ BSDF_CLOSURE_CLASS_BEGIN(AshikhminVelvet, ashikhmin_velvet, ashikhmin_velvet, LA
CLOSURE_FLOAT_PARAM(AshikhminVelvetClosure, sc.data0),
BSDF_CLOSURE_CLASS_END(AshikhminVelvet, ashikhmin_velvet)
-BSDF_CLOSURE_CLASS_BEGIN(Ward, ward, ward, LABEL_GLOSSY)
- CLOSURE_FLOAT3_PARAM(WardClosure, sc.N),
- CLOSURE_FLOAT3_PARAM(WardClosure, sc.T),
- CLOSURE_FLOAT_PARAM(WardClosure, sc.data0),
- CLOSURE_FLOAT_PARAM(WardClosure, sc.data1),
-BSDF_CLOSURE_CLASS_END(Ward, ward)
-
-BSDF_CLOSURE_CLASS_BEGIN(AshikhminShirley, ashikhmin_shirley, ashikhmin_shirley, LABEL_GLOSSY)
+BSDF_CLOSURE_CLASS_BEGIN(AshikhminShirley, ashikhmin_shirley_aniso, ashikhmin_shirley, LABEL_GLOSSY)
CLOSURE_FLOAT3_PARAM(AshikhminShirleyClosure, sc.N),
CLOSURE_FLOAT3_PARAM(AshikhminShirleyClosure, sc.T),
CLOSURE_FLOAT_PARAM(AshikhminShirleyClosure, sc.data0),
CLOSURE_FLOAT_PARAM(AshikhminShirleyClosure, sc.data1),
-BSDF_CLOSURE_CLASS_END(AshikhminShirley, ashikhmin_shirley)
+BSDF_CLOSURE_CLASS_END(AshikhminShirley, ashikhmin_shirley_aniso)
BSDF_CLOSURE_CLASS_BEGIN(DiffuseToon, diffuse_toon, diffuse_toon, LABEL_DIFFUSE)
CLOSURE_FLOAT3_PARAM(DiffuseToonClosure, sc.N),
@@ -135,11 +127,25 @@ BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGX, microfacet_ggx, microfacet_ggx, LABEL_GL
CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure, sc.data0),
BSDF_CLOSURE_CLASS_END(MicrofacetGGX, microfacet_ggx)
+BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXAniso, microfacet_ggx_aniso, microfacet_ggx, LABEL_GLOSSY)
+ CLOSURE_FLOAT3_PARAM(MicrofacetGGXAnisoClosure, sc.N),
+ CLOSURE_FLOAT3_PARAM(MicrofacetGGXAnisoClosure, sc.T),
+ CLOSURE_FLOAT_PARAM(MicrofacetGGXAnisoClosure, sc.data0),
+ CLOSURE_FLOAT_PARAM(MicrofacetGGXAnisoClosure, sc.data1),
+BSDF_CLOSURE_CLASS_END(MicrofacetGGXAniso, microfacet_ggx_aniso)
+
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmann, microfacet_beckmann, microfacet_beckmann, LABEL_GLOSSY)
CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannClosure, sc.N),
CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure, sc.data0),
BSDF_CLOSURE_CLASS_END(MicrofacetBeckmann, microfacet_beckmann)
+BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannAniso, microfacet_beckmann_aniso, microfacet_beckmann, LABEL_GLOSSY)
+ CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannAnisoClosure, sc.N),
+ CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannAnisoClosure, sc.T),
+ CLOSURE_FLOAT_PARAM(MicrofacetBeckmannAnisoClosure, sc.data0),
+ CLOSURE_FLOAT_PARAM(MicrofacetBeckmannAnisoClosure, sc.data1),
+BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannAniso, microfacet_beckmann_aniso)
+
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXRefraction, microfacet_ggx_refraction, microfacet_ggx, LABEL_GLOSSY)
CLOSURE_FLOAT3_PARAM(MicrofacetGGXRefractionClosure, sc.N),
CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, sc.data0),
@@ -218,16 +224,18 @@ void OSLShader::register_closures(OSLShadingSystem *ss_)
bsdf_transparent_params(), bsdf_transparent_prepare);
register_closure(ss, "microfacet_ggx", id++,
bsdf_microfacet_ggx_params(), bsdf_microfacet_ggx_prepare);
+ register_closure(ss, "microfacet_ggx_aniso", id++,
+ bsdf_microfacet_ggx_aniso_params(), bsdf_microfacet_ggx_aniso_prepare);
register_closure(ss, "microfacet_ggx_refraction", id++,
bsdf_microfacet_ggx_refraction_params(), bsdf_microfacet_ggx_refraction_prepare);
register_closure(ss, "microfacet_beckmann", id++,
bsdf_microfacet_beckmann_params(), bsdf_microfacet_beckmann_prepare);
+ register_closure(ss, "microfacet_beckmann_aniso", id++,
+ bsdf_microfacet_beckmann_aniso_params(), bsdf_microfacet_beckmann_aniso_prepare);
register_closure(ss, "microfacet_beckmann_refraction", id++,
bsdf_microfacet_beckmann_refraction_params(), bsdf_microfacet_beckmann_refraction_prepare);
- register_closure(ss, "ward", id++,
- bsdf_ward_params(), bsdf_ward_prepare);
register_closure(ss, "ashikhmin_shirley", id++,
- bsdf_ashikhmin_shirley_params(), bsdf_ashikhmin_shirley_prepare);
+ bsdf_ashikhmin_shirley_aniso_params(), bsdf_ashikhmin_shirley_aniso_prepare);
register_closure(ss, "ashikhmin_velvet", id++,
bsdf_ashikhmin_velvet_params(), bsdf_ashikhmin_velvet_prepare);
register_closure(ss, "diffuse_toon", id++,
diff --git a/intern/cycles/kernel/shaders/node_anisotropic_bsdf.osl b/intern/cycles/kernel/shaders/node_anisotropic_bsdf.osl
index 3ecf5b46bef..da1e4f77107 100644
--- a/intern/cycles/kernel/shaders/node_anisotropic_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_anisotropic_bsdf.osl
@@ -18,7 +18,7 @@
shader node_anisotropic_bsdf(
color Color = 0.0,
- string distribution = "Ward",
+ string distribution = "GGX",
float Roughness = 0.0,
float Anisotropy = 0.0,
float Rotation = 0.0,
@@ -45,9 +45,13 @@ shader node_anisotropic_bsdf(
RoughnessV = Roughness / (1.0 - aniso);
}
- if (distribution == "Ashikhmin-Shirley")
- BSDF = Color * ashikhmin_shirley(Normal, T, RoughnessU, RoughnessV);
+ if (distribution == "Sharp")
+ BSDF = Color * reflection(Normal);
+ else if (distribution == "Beckmann")
+ BSDF = Color * microfacet_beckmann_aniso(Normal, T, RoughnessU, RoughnessV);
+ else if (distribution == "GGX")
+ BSDF = Color * microfacet_ggx_aniso(Normal, T, RoughnessU, RoughnessV);
else
- BSDF = Color * ward(Normal, T, RoughnessU, RoughnessV);
+ BSDF = Color * ashikhmin_shirley(Normal, T, RoughnessU, RoughnessV);
}
diff --git a/intern/cycles/kernel/shaders/node_glossy_bsdf.osl b/intern/cycles/kernel/shaders/node_glossy_bsdf.osl
index b4e0fe62223..5c727ca6917 100644
--- a/intern/cycles/kernel/shaders/node_glossy_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_glossy_bsdf.osl
@@ -19,7 +19,7 @@
shader node_glossy_bsdf(
color Color = 0.8,
- string distribution = "Beckmann",
+ string distribution = "GGX",
float Roughness = 0.2,
normal Normal = N,
output closure color BSDF = 0)
@@ -30,6 +30,8 @@ shader node_glossy_bsdf(
BSDF = Color * microfacet_beckmann(Normal, Roughness);
else if (distribution == "GGX")
BSDF = Color * microfacet_ggx(Normal, Roughness);
+ else
+ BSDF = Color * ashikhmin_shirley(Normal, vector(0, 0, 0), Roughness, Roughness);
}
diff --git a/intern/cycles/kernel/shaders/stdosl.h b/intern/cycles/kernel/shaders/stdosl.h
index 20ee4a3df32..e39db8097f2 100644
--- a/intern/cycles/kernel/shaders/stdosl.h
+++ b/intern/cycles/kernel/shaders/stdosl.h
@@ -483,11 +483,12 @@ closure color reflection(normal N) BUILTIN;
closure color refraction(normal N, float eta) BUILTIN;
closure color transparent() BUILTIN;
closure color microfacet_ggx(normal N, float ag) BUILTIN;
+closure color microfacet_ggx_aniso(normal N, vector T, float ax, float ay) BUILTIN;
closure color microfacet_ggx_refraction(normal N, float ag, float eta) BUILTIN;
closure color microfacet_beckmann(normal N, float ab) BUILTIN;
+closure color microfacet_beckmann_aniso(normal N, vector T, float ax, float ay) BUILTIN;
closure color microfacet_beckmann_refraction(normal N, float ab, float eta) BUILTIN;
closure color ashikhmin_shirley(normal N, vector T,float ax, float ay) BUILTIN;
-closure color ward(normal N, vector T,float ax, float ay) BUILTIN;
closure color ashikhmin_velvet(normal N, float sigma) BUILTIN;
closure color emission() BUILTIN;
closure color background() BUILTIN;
diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h
index 561fecb44c9..5fcc44e478b 100644
--- a/intern/cycles/kernel/svm/svm_closure.h
+++ b/intern/cycles/kernel/svm/svm_closure.h
@@ -176,7 +176,8 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
}
case CLOSURE_BSDF_REFLECTION_ID:
case CLOSURE_BSDF_MICROFACET_GGX_ID:
- case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: {
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
+ case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: {
#ifdef __CAUSTICS_TRICKS__
if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE))
break;
@@ -194,8 +195,10 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
sd->flag |= bsdf_reflection_setup(sc);
else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_ID)
sd->flag |= bsdf_microfacet_beckmann_setup(sc);
- else
+ else if(type == CLOSURE_BSDF_MICROFACET_GGX_ID)
sd->flag |= bsdf_microfacet_ggx_setup(sc);
+ else
+ sd->flag |= bsdf_ashikhmin_shirley_setup(sc);
}
break;
@@ -279,8 +282,9 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
break;
}
- case CLOSURE_BSDF_WARD_ID:
- case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: {
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
+ case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID: {
#ifdef __CAUSTICS_TRICKS__
if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE))
break;
@@ -314,10 +318,12 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
sc->data2 = 0.0f;
- if (type == CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID)
- sd->flag |= bsdf_ashikhmin_shirley_setup(sc);
+ if (type == CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID)
+ sd->flag |= bsdf_microfacet_beckmann_aniso_setup(sc);
+ else if (type == CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID)
+ sd->flag |= bsdf_microfacet_ggx_aniso_setup(sc);
else
- sd->flag |= bsdf_ward_setup(sc);
+ sd->flag |= bsdf_ashikhmin_shirley_aniso_setup(sc);
#else
sd->flag |= bsdf_diffuse_setup(sc);
#endif
diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h
index 87c56b3ea82..103f562ed60 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -357,8 +357,10 @@ typedef enum ClosureType {
CLOSURE_BSDF_REFLECTION_ID,
CLOSURE_BSDF_MICROFACET_GGX_ID,
CLOSURE_BSDF_MICROFACET_BECKMANN_ID,
- CLOSURE_BSDF_WARD_ID,
CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID,
+ CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID,
+ CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID,
+ CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID,
CLOSURE_BSDF_ASHIKHMIN_VELVET_ID,
CLOSURE_BSDF_WESTIN_BACKSCATTER_ID,
CLOSURE_BSDF_PHONG_RAMP_ID,
@@ -404,7 +406,7 @@ typedef enum ClosureType {
#define CLOSURE_IS_BSDF_GLOSSY(type) (type >= CLOSURE_BSDF_GLOSSY_ID && type <= CLOSURE_BSDF_HAIR_REFLECTION_ID)
#define CLOSURE_IS_BSDF_TRANSMISSION(type) (type >= CLOSURE_BSDF_TRANSMISSION_ID && type <= CLOSURE_BSDF_HAIR_TRANSMISSION_ID)
#define CLOSURE_IS_BSDF_BSSRDF(type) (type == CLOSURE_BSDF_BSSRDF_ID)
-#define CLOSURE_IS_BSDF_ANISOTROPIC(type) (type >= CLOSURE_BSDF_WARD_ID && type <= CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID)
+#define CLOSURE_IS_BSDF_ANISOTROPIC(type) (type >= CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID && type <= CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID)
#define CLOSURE_IS_BSDF_OR_BSSRDF(type) (type <= CLOSURE_BSSRDF_GAUSSIAN_ID)
#define CLOSURE_IS_BSSRDF(type) (type >= CLOSURE_BSSRDF_CUBIC_ID && type <= CLOSURE_BSSRDF_GAUSSIAN_ID)
#define CLOSURE_IS_VOLUME(type) (type >= CLOSURE_VOLUME_ID && type <= CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID)
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 8976f958b58..c3aef362428 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -1585,21 +1585,23 @@ void BsdfNode::compile(OSLCompiler& compiler)
/* Anisotropic BSDF Closure */
-static ShaderEnum anisotropic_distribution_init()
+static ShaderEnum aniso_distribution_init()
{
ShaderEnum enm;
- enm.insert("Ward", CLOSURE_BSDF_WARD_ID);
- enm.insert("Ashikhmin-Shirley", CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID);
+ enm.insert("Sharp", CLOSURE_BSDF_REFLECTION_ID);
+ enm.insert("Beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID);
+ enm.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID);
+ enm.insert("Ashikhmin-Shirley", CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID);
return enm;
}
-ShaderEnum AnisotropicBsdfNode::distribution_enum = anisotropic_distribution_init();
+ShaderEnum AnisotropicBsdfNode::distribution_enum = aniso_distribution_init();
AnisotropicBsdfNode::AnisotropicBsdfNode()
{
- distribution = ustring("Ward");
+ distribution = ustring("GGX");
add_input("Tangent", SHADER_SOCKET_VECTOR, ShaderInput::TANGENT);
@@ -1642,6 +1644,7 @@ static ShaderEnum glossy_distribution_init()
enm.insert("Sharp", CLOSURE_BSDF_REFLECTION_ID);
enm.insert("Beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_ID);
enm.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_ID);
+ enm.insert("Ashikhmin-Shirley", CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID);
return enm;
}
@@ -1650,7 +1653,7 @@ ShaderEnum GlossyBsdfNode::distribution_enum = glossy_distribution_init();
GlossyBsdfNode::GlossyBsdfNode()
{
- distribution = ustring("Beckmann");
+ distribution = ustring("GGX");
add_input("Roughness", SHADER_SOCKET_FLOAT, 0.2f);
}