diff options
Diffstat (limited to 'intern/cycles/kernel/closure/bsdf.h')
-rw-r--r-- | intern/cycles/kernel/closure/bsdf.h | 379 |
1 files changed, 269 insertions, 110 deletions
diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h index cfb6321a918..f26aefe7fd3 100644 --- a/intern/cycles/kernel/closure/bsdf.h +++ b/intern/cycles/kernel/closure/bsdf.h @@ -1,137 +1,296 @@ /* - * Adapted from Open Shading Language with this license: + * Copyright 2011, Blender Foundation. * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. + * 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. * - * Modifications Copyright 2011, Blender Foundation. + * 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. * - * 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. + * 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. */ -#ifndef __OSL_BSDF_H__ -#define __OSL_BSDF_H__ +#include "../closure/bsdf_ashikhmin_velvet.h" +#include "../closure/bsdf_diffuse.h" +#include "../closure/bsdf_oren_nayar.h" +#include "../closure/bsdf_phong_ramp.h" +#include "../closure/bsdf_diffuse_ramp.h" +#include "../closure/bsdf_microfacet.h" +#include "../closure/bsdf_reflection.h" +#include "../closure/bsdf_refraction.h" +#include "../closure/bsdf_transparent.h" +#ifdef __ANISOTROPIC__ +#include "../closure/bsdf_ward.h" +#endif +#include "../closure/bsdf_westin.h" CCL_NAMESPACE_BEGIN -__device float fresnel_dielectric(float eta, const float3 N, - const float3 I, float3 *R, float3 *T, -#ifdef __RAY_DIFFERENTIALS__ - const float3 dIdx, const float3 dIdy, - float3 *dRdx, float3 *dRdy, - float3 *dTdx, float3 *dTdy, -#endif - bool *is_inside) +__device int bsdf_sample(KernelGlobals *kg, const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, differential3 *domega_in, float *pdf) { - float cos = dot(N, I), neta; - float3 Nn; - // compute reflection - *R = (2 * cos)* N - I; -#ifdef __RAY_DIFFERENTIALS__ - *dRdx = (2 * dot(N, dIdx)) * N - dIdx; - *dRdy = (2 * dot(N, dIdy)) * N - dIdy; + int label; + +#ifdef __OSL__ + if(kg->osl && sc->prim) + return OSLShader::bsdf_sample(sd, sc, randu, randv, *eval, *omega_in, *domega_in, *pdf); #endif - // check which side of the surface we are on - if(cos > 0) { - // we are on the outside of the surface, going in - neta = 1 / eta; - Nn = N; - *is_inside = false; - } - else { - // we are inside the surface, - cos = -cos; - neta = eta; - Nn = -N; - *is_inside = true; - } - *R = (2 * cos)* Nn - I; - float arg = 1 -(neta * neta *(1 -(cos * cos))); - if(arg < 0) { - *T = make_float3(0.0f, 0.0f, 0.0f); -#ifdef __RAY_DIFFERENTIALS__ - *dTdx = make_float3(0.0f, 0.0f, 0.0f); - *dTdy = make_float3(0.0f, 0.0f, 0.0f); + + switch(sc->type) { + case CLOSURE_BSDF_DIFFUSE_ID: + label = bsdf_diffuse_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + break; +#ifdef __SVM__ + case CLOSURE_BSDF_OREN_NAYAR_ID: + label = bsdf_oren_nayar_sample(sc, 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_PHONG_RAMP_ID: + label = bsdf_phong_ramp_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + break; + case CLOSURE_BSDF_DIFFUSE_RAMP_ID: + label = bsdf_diffuse_ramp_sample(sc, 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_TRANSLUCENT_ID: + label = bsdf_translucent_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + break; + case CLOSURE_BSDF_REFLECTION_ID: + label = bsdf_reflection_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + break; + case CLOSURE_BSDF_REFRACTION_ID: + label = bsdf_refraction_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + break; + case CLOSURE_BSDF_TRANSPARENT_ID: + label = bsdf_transparent_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + break; + case CLOSURE_BSDF_MICROFACET_GGX_ID: + case CLOSURE_BSDF_MICROFACET_GGX_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_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; #endif - return 1; // total internal reflection - } - else { - float dnp = sqrtf(arg); - float nK = (neta * cos)- dnp; - *T = -(neta * I)+(nK * Nn); -#ifdef __RAY_DIFFERENTIALS__ - *dTdx = -(neta * dIdx) + ((neta - neta * neta * cos / dnp) * dot(dIdx, Nn)) * Nn; - *dTdy = -(neta * dIdy) + ((neta - neta * neta * cos / dnp) * dot(dIdy, Nn)) * Nn; + case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: + label = bsdf_ashikhmin_velvet_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + break; + case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID: + label = bsdf_westin_backscatter_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_WESTIN_SHEEN_ID: + label = bsdf_westin_sheen_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + break; #endif - // compute Fresnel terms - float cosTheta1 = cos; // N.R - float cosTheta2 = -dot(Nn, *T); - float pPara = (cosTheta1 - eta * cosTheta2)/(cosTheta1 + eta * cosTheta2); - float pPerp = (eta * cosTheta1 - cosTheta2)/(eta * cosTheta1 + cosTheta2); - return 0.5f * (pPara * pPara + pPerp * pPerp); + default: + label = LABEL_NONE; + break; } + + return label; } -__device float fresnel_dielectric_cos(float cosi, float eta) +__device float3 bsdf_eval(KernelGlobals *kg, const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, float *pdf) { - // compute fresnel reflectance without explicitly computing - // the refracted direction - float c = fabsf(cosi); - float g = eta * eta - 1 + c * c; - if(g > 0) { - g = sqrtf(g); - float A = (g - c)/(g + c); - float B = (c *(g + c)- 1)/(c *(g - c)+ 1); - return 0.5f * A * A *(1 + B * B); + float3 eval; + +#ifdef __OSL__ + if(kg->osl && sc->prim) + return OSLShader::bsdf_eval(sd, sc, omega_in, *pdf); +#endif + + if(dot(sd->Ng, omega_in) >= 0.0f) { + switch(sc->type) { + case CLOSURE_BSDF_DIFFUSE_ID: + eval = bsdf_diffuse_eval_reflect(sc, sd->I, omega_in, pdf); + break; +#ifdef __SVM__ + case CLOSURE_BSDF_OREN_NAYAR_ID: + eval = bsdf_oren_nayar_eval_reflect(sc, sd->I, omega_in, pdf); + break; + /*case CLOSURE_BSDF_PHONG_RAMP_ID: + eval = bsdf_phong_ramp_eval_reflect(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_DIFFUSE_RAMP_ID: + eval = bsdf_diffuse_ramp_eval_reflect(sc, sd->I, omega_in, pdf); + break;*/ + case CLOSURE_BSDF_TRANSLUCENT_ID: + eval = bsdf_translucent_eval_reflect(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_REFLECTION_ID: + eval = bsdf_reflection_eval_reflect(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_REFRACTION_ID: + eval = bsdf_refraction_eval_reflect(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_TRANSPARENT_ID: + eval = bsdf_transparent_eval_reflect(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_MICROFACET_GGX_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_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; +#endif + case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: + eval = bsdf_ashikhmin_velvet_eval_reflect(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID: + eval = bsdf_westin_backscatter_eval_reflect(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_WESTIN_SHEEN_ID: + eval = bsdf_westin_sheen_eval_reflect(sc, sd->I, omega_in, pdf); + break; +#endif + default: + eval = make_float3(0.0f, 0.0f, 0.0f); + break; + } + } + else { + switch(sc->type) { + case CLOSURE_BSDF_DIFFUSE_ID: + eval = bsdf_diffuse_eval_transmit(sc, sd->I, omega_in, pdf); + break; +#ifdef __SVM__ + case CLOSURE_BSDF_OREN_NAYAR_ID: + eval = bsdf_oren_nayar_eval_transmit(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_TRANSLUCENT_ID: + eval = bsdf_translucent_eval_transmit(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_REFLECTION_ID: + eval = bsdf_reflection_eval_transmit(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_REFRACTION_ID: + eval = bsdf_refraction_eval_transmit(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_TRANSPARENT_ID: + eval = bsdf_transparent_eval_transmit(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_MICROFACET_GGX_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_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; +#endif + case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: + eval = bsdf_ashikhmin_velvet_eval_transmit(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID: + eval = bsdf_westin_backscatter_eval_transmit(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_WESTIN_SHEEN_ID: + eval = bsdf_westin_sheen_eval_transmit(sc, sd->I, omega_in, pdf); + break; +#endif + default: + eval = make_float3(0.0f, 0.0f, 0.0f); + break; + } } - return 1.0f; // TIR(no refracted component) -} -__device float fresnel_conductor(float cosi, float eta, float k) -{ - float tmp_f = eta * eta + k * k; - float tmp = tmp_f * cosi * cosi; - float Rparl2 = (tmp - (2.0f * eta * cosi) + 1)/ - (tmp + (2.0f * eta * cosi) + 1); - float Rperp2 = (tmp_f - (2.0f * eta * cosi) + cosi * cosi)/ - (tmp_f + (2.0f * eta * cosi) + cosi * cosi); - return(Rparl2 + Rperp2) * 0.5f; + return eval; } -__device float smooth_step(float edge0, float edge1, float x) +__device void bsdf_blur(KernelGlobals *kg, ShaderClosure *sc, float roughness) { - float result; - if(x < edge0) result = 0.0f; - else if(x >= edge1) result = 1.0f; - else { - float t = (x - edge0)/(edge1 - edge0); - result = (3.0f-2.0f*t)*(t*t); +#ifdef __OSL__ + if(kg->osl && sc->prim) { + OSLShader::bsdf_blur(sc, roughness); + return; + } +#endif + + switch(sc->type) { + case CLOSURE_BSDF_DIFFUSE_ID: + bsdf_diffuse_blur(sc, roughness); + break; +#ifdef __SVM__ + case CLOSURE_BSDF_OREN_NAYAR_ID: + bsdf_oren_nayar_blur(sc, roughness); + break; + /*case CLOSURE_BSDF_PHONG_RAMP_ID: + bsdf_phong_ramp_blur(sc, roughness); + break; + case CLOSURE_BSDF_DIFFUSE_RAMP_ID: + bsdf_diffuse_ramp_blur(sc, roughness); + break;*/ + case CLOSURE_BSDF_TRANSLUCENT_ID: + bsdf_translucent_blur(sc, roughness); + break; + case CLOSURE_BSDF_REFLECTION_ID: + bsdf_reflection_blur(sc, roughness); + break; + case CLOSURE_BSDF_REFRACTION_ID: + bsdf_refraction_blur(sc, roughness); + break; + case CLOSURE_BSDF_TRANSPARENT_ID: + bsdf_transparent_blur(sc, roughness); + break; + case CLOSURE_BSDF_MICROFACET_GGX_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_REFRACTION_ID: + bsdf_microfacet_beckmann_blur(sc, roughness); + break; +#ifdef __ANISOTROPIC__ + case CLOSURE_BSDF_WARD_ID: + bsdf_ward_blur(sc, roughness); + break; +#endif + case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: + bsdf_ashikhmin_velvet_blur(sc, roughness); + break; + case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID: + bsdf_westin_backscatter_blur(sc, roughness); + break; + case CLOSURE_BSDF_WESTIN_SHEEN_ID: + bsdf_westin_sheen_blur(sc, roughness); + break; +#endif + default: + break; } - return result; } CCL_NAMESPACE_END -#endif /* __OSL_BSDF_H__ */ - |