forked from bartvdbraak/blender
Cycles OSL minor optimizations: recycle shading context, don't do memory
allocations for trace data, avoid some virtual function calls. Only helps a few percentages.
This commit is contained in:
parent
35dd893c36
commit
06888b7beb
@ -56,6 +56,7 @@ set(SRC_CLOSURE_HEADERS
|
||||
closure/bsdf_reflection.h
|
||||
closure/bsdf_refraction.h
|
||||
closure/bsdf_transparent.h
|
||||
closure/bsdf_util.h
|
||||
closure/bsdf_ward.h
|
||||
closure/bsdf_westin.h
|
||||
closure/emissive.h
|
||||
@ -64,7 +65,6 @@ set(SRC_CLOSURE_HEADERS
|
||||
set(SRC_SVM_HEADERS
|
||||
svm/svm.h
|
||||
svm/svm_attribute.h
|
||||
svm/svm_bsdf.h
|
||||
svm/svm_camera.h
|
||||
svm/svm_closure.h
|
||||
svm/svm_convert.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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
__device float smooth_step(float edge0, float edge1, float x)
|
||||
{
|
||||
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);
|
||||
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 eval;
|
||||
}
|
||||
|
||||
__device void bsdf_blur(KernelGlobals *kg, ShaderClosure *sc, float roughness)
|
||||
{
|
||||
#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__ */
|
||||
|
||||
|
137
intern/cycles/kernel/closure/bsdf_util.h
Normal file
137
intern/cycles/kernel/closure/bsdf_util.h
Normal file
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* 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 __OSL_BSDF_H__
|
||||
#define __OSL_BSDF_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)
|
||||
{
|
||||
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;
|
||||
#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);
|
||||
#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;
|
||||
#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);
|
||||
}
|
||||
}
|
||||
|
||||
__device float fresnel_dielectric_cos(float cosi, float eta)
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
__device float smooth_step(float edge0, float edge1, float x)
|
||||
{
|
||||
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);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* __OSL_BSDF_H__ */
|
||||
|
@ -49,17 +49,12 @@ __device void emissive_sample(const float3 Ng, float randu, float randv,
|
||||
/* todo: not implemented and used yet */
|
||||
}
|
||||
|
||||
__device float3 emissive_eval(const float3 Ng, const float3 I)
|
||||
__device float3 emissive_simple_eval(const float3 Ng, const float3 I)
|
||||
{
|
||||
float res = emissive_pdf(Ng, I);
|
||||
|
||||
return make_float3(res, res, res);
|
||||
}
|
||||
|
||||
__device float3 svm_emissive_eval(ShaderData *sd, ShaderClosure *sc)
|
||||
{
|
||||
return emissive_eval(sd->Ng, sd->I);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
|
@ -53,8 +53,13 @@ __device float3 volume_transparent_eval_phase(const ShaderClosure *sc, const flo
|
||||
|
||||
/* VOLUME CLOSURE */
|
||||
|
||||
__device float3 volume_eval_phase(const ShaderClosure *sc, const float3 omega_in, const float3 omega_out)
|
||||
__device float3 volume_eval_phase(KernelGlobals *kg, const ShaderClosure *sc, const float3 omega_in, const float3 omega_out)
|
||||
{
|
||||
#ifdef __OSL__
|
||||
if(kg->osl && sc->prim)
|
||||
return OSLShader::volume_eval_phase(sc, omega_in, omega_out);
|
||||
#endif
|
||||
|
||||
float3 eval;
|
||||
|
||||
switch(sc->type) {
|
||||
|
@ -35,7 +35,7 @@ __device void kernel_shader_evaluate(KernelGlobals *kg, uint4 *input, float4 *ou
|
||||
|
||||
/* evaluate */
|
||||
float3 P = sd.P;
|
||||
shader_eval_displacement(kg, &sd);
|
||||
shader_eval_displacement(kg, &sd, SHADER_CONTEXT_MAIN);
|
||||
out = sd.P - P;
|
||||
}
|
||||
else { // SHADER_EVAL_BACKGROUND
|
||||
@ -63,7 +63,7 @@ __device void kernel_shader_evaluate(KernelGlobals *kg, uint4 *input, float4 *ou
|
||||
|
||||
/* evaluate */
|
||||
int flag = 0; /* we can't know which type of BSDF this is for */
|
||||
out = shader_eval_background(kg, &sd, flag);
|
||||
out = shader_eval_background(kg, &sd, flag, SHADER_CONTEXT_MAIN);
|
||||
}
|
||||
|
||||
shader_release(kg, &sd);
|
||||
|
@ -42,7 +42,7 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando,
|
||||
ray.time = time;
|
||||
#endif
|
||||
shader_setup_from_background(kg, &sd, &ray);
|
||||
eval = shader_eval_background(kg, &sd, 0);
|
||||
eval = shader_eval_background(kg, &sd, 0, SHADER_CONTEXT_EMISSION);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@ -52,7 +52,7 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando,
|
||||
|
||||
/* no path flag, we're evaluating this for all closures. that's weak but
|
||||
* we'd have to do multiple evaluations otherwise */
|
||||
shader_eval_surface(kg, &sd, rando, 0);
|
||||
shader_eval_surface(kg, &sd, rando, 0, SHADER_CONTEXT_EMISSION);
|
||||
|
||||
/* evaluate emissive closure */
|
||||
if(sd.flag & SD_EMISSION)
|
||||
@ -170,7 +170,7 @@ __device float3 indirect_background(KernelGlobals *kg, Ray *ray, int path_flag,
|
||||
/* evaluate background closure */
|
||||
ShaderData sd;
|
||||
shader_setup_from_background(kg, &sd, ray);
|
||||
float3 L = shader_eval_background(kg, &sd, path_flag);
|
||||
float3 L = shader_eval_background(kg, &sd, path_flag, SHADER_CONTEXT_EMISSION);
|
||||
shader_release(kg, &sd);
|
||||
|
||||
#ifdef __BACKGROUND_MIS__
|
||||
|
@ -207,7 +207,7 @@ __device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *ra
|
||||
|
||||
ShaderData sd;
|
||||
shader_setup_from_ray(kg, &sd, &isect, ray);
|
||||
shader_eval_surface(kg, &sd, 0.0f, PATH_RAY_SHADOW);
|
||||
shader_eval_surface(kg, &sd, 0.0f, PATH_RAY_SHADOW, SHADER_CONTEXT_SHADOW);
|
||||
|
||||
throughput *= shader_bsdf_transparency(kg, &sd);
|
||||
|
||||
@ -272,7 +272,7 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
|
||||
ShaderData sd;
|
||||
shader_setup_from_ray(kg, &sd, &isect, &ray);
|
||||
float rbsdf = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF);
|
||||
shader_eval_surface(kg, &sd, rbsdf, state.flag);
|
||||
shader_eval_surface(kg, &sd, rbsdf, state.flag, SHADER_CONTEXT_MAIN);
|
||||
|
||||
kernel_write_data_passes(kg, buffer, &L, &sd, sample, state.flag, throughput);
|
||||
|
||||
@ -478,7 +478,7 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray
|
||||
ShaderData sd;
|
||||
shader_setup_from_ray(kg, &sd, &isect, &ray);
|
||||
float rbsdf = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF);
|
||||
shader_eval_surface(kg, &sd, rbsdf, state.flag);
|
||||
shader_eval_surface(kg, &sd, rbsdf, state.flag, SHADER_CONTEXT_INDIRECT);
|
||||
shader_merge_closures(kg, &sd);
|
||||
|
||||
/* blurring of bsdf after bounces, for rays that have a small likelihood
|
||||
@ -666,7 +666,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
|
||||
ShaderData sd;
|
||||
shader_setup_from_ray(kg, &sd, &isect, &ray);
|
||||
float rbsdf = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF);
|
||||
shader_eval_surface(kg, &sd, rbsdf, state.flag);
|
||||
shader_eval_surface(kg, &sd, rbsdf, state.flag, SHADER_CONTEXT_MAIN);
|
||||
shader_merge_closures(kg, &sd);
|
||||
|
||||
kernel_write_data_passes(kg, buffer, &L, &sd, sample, state.flag, throughput);
|
||||
|
@ -26,11 +26,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "closure/bsdf_util.h"
|
||||
#include "closure/bsdf.h"
|
||||
#include "closure/emissive.h"
|
||||
#include "closure/volume.h"
|
||||
|
||||
#include "svm/svm_bsdf.h"
|
||||
#include "svm/svm.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
@ -56,11 +56,6 @@ __device_noinline void shader_setup_object_transforms(KernelGlobals *kg, ShaderD
|
||||
__device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
|
||||
const Intersection *isect, const Ray *ray)
|
||||
{
|
||||
#ifdef __OSL__
|
||||
if (kg->osl)
|
||||
OSLShader::init(kg, sd);
|
||||
#endif
|
||||
|
||||
/* fetch triangle data */
|
||||
int prim = kernel_tex_fetch(__prim_index, isect->prim);
|
||||
float4 Ns = kernel_tex_fetch(__tri_normal, prim);
|
||||
@ -142,11 +137,6 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
|
||||
const float3 P, const float3 Ng, const float3 I,
|
||||
int shader, int object, int prim, float u, float v, float t, float time)
|
||||
{
|
||||
#ifdef __OSL__
|
||||
if (kg->osl)
|
||||
OSLShader::init(kg, sd);
|
||||
#endif
|
||||
|
||||
/* vectors */
|
||||
sd->P = P;
|
||||
sd->N = Ng;
|
||||
@ -273,11 +263,6 @@ __device void shader_setup_from_displace(KernelGlobals *kg, ShaderData *sd,
|
||||
|
||||
__device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData *sd, const Ray *ray)
|
||||
{
|
||||
#ifdef __OSL__
|
||||
if (kg->osl)
|
||||
OSLShader::init(kg, sd);
|
||||
#endif
|
||||
|
||||
/* vectors */
|
||||
sd->P = ray->D;
|
||||
sd->N = -sd->P;
|
||||
@ -320,9 +305,8 @@ __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData
|
||||
|
||||
#ifdef __MULTI_CLOSURE__
|
||||
|
||||
#ifdef __OSL__
|
||||
__device_inline void _shader_bsdf_multi_eval_osl(const ShaderData *sd, const float3 omega_in, float *pdf,
|
||||
int skip_bsdf, BsdfEval *bsdf_eval, float sum_pdf, float sum_sample_weight)
|
||||
__device_inline void _shader_bsdf_multi_eval(KernelGlobals *kg, const ShaderData *sd, const float3 omega_in, float *pdf,
|
||||
int skip_bsdf, BsdfEval *result_eval, float sum_pdf, float sum_sample_weight)
|
||||
{
|
||||
for(int i = 0; i< sd->num_closure; i++) {
|
||||
if(i == skip_bsdf)
|
||||
@ -332,38 +316,10 @@ __device_inline void _shader_bsdf_multi_eval_osl(const ShaderData *sd, const flo
|
||||
|
||||
if(CLOSURE_IS_BSDF(sc->type)) {
|
||||
float bsdf_pdf = 0.0f;
|
||||
|
||||
float3 eval = OSLShader::bsdf_eval(sd, sc, omega_in, bsdf_pdf);
|
||||
float3 eval = bsdf_eval(kg, sd, sc, omega_in, &bsdf_pdf);
|
||||
|
||||
if(bsdf_pdf != 0.0f) {
|
||||
bsdf_eval_accum(bsdf_eval, sc->type, eval*sc->weight);
|
||||
sum_pdf += bsdf_pdf*sc->sample_weight;
|
||||
}
|
||||
|
||||
sum_sample_weight += sc->sample_weight;
|
||||
}
|
||||
}
|
||||
|
||||
*pdf = (sum_sample_weight > 0.0f)? sum_pdf/sum_sample_weight: 0.0f;
|
||||
}
|
||||
#endif
|
||||
|
||||
__device_inline void _shader_bsdf_multi_eval_svm(const ShaderData *sd, const float3 omega_in, float *pdf,
|
||||
int skip_bsdf, BsdfEval *bsdf_eval, float sum_pdf, float sum_sample_weight)
|
||||
{
|
||||
for(int i = 0; i< sd->num_closure; i++) {
|
||||
if(i == skip_bsdf)
|
||||
continue;
|
||||
|
||||
const ShaderClosure *sc = &sd->closure[i];
|
||||
|
||||
if(CLOSURE_IS_BSDF(sc->type)) {
|
||||
float bsdf_pdf = 0.0f;
|
||||
|
||||
float3 eval = svm_bsdf_eval(sd, sc, omega_in, &bsdf_pdf);
|
||||
|
||||
if(bsdf_pdf != 0.0f) {
|
||||
bsdf_eval_accum(bsdf_eval, sc->type, eval*sc->weight);
|
||||
bsdf_eval_accum(result_eval, sc->type, eval*sc->weight);
|
||||
sum_pdf += bsdf_pdf*sc->sample_weight;
|
||||
}
|
||||
|
||||
@ -382,17 +338,12 @@ __device void shader_bsdf_eval(KernelGlobals *kg, const ShaderData *sd,
|
||||
#ifdef __MULTI_CLOSURE__
|
||||
bsdf_eval_init(eval, NBUILTIN_CLOSURES, make_float3(0.0f, 0.0f, 0.0f), kernel_data.film.use_light_pass);
|
||||
|
||||
#ifdef __OSL__
|
||||
if (kg->osl)
|
||||
return _shader_bsdf_multi_eval_osl(sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
|
||||
else
|
||||
#endif
|
||||
return _shader_bsdf_multi_eval_svm(sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
|
||||
return _shader_bsdf_multi_eval(kg, sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
|
||||
#else
|
||||
const ShaderClosure *sc = &sd->closure;
|
||||
|
||||
*pdf = 0.0f;
|
||||
*eval = svm_bsdf_eval(sd, sc, omega_in, pdf)*sc->weight;
|
||||
*eval = bsdf_eval(kg, sd, sc, omega_in, pdf)*sc->weight;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -439,24 +390,14 @@ __device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd,
|
||||
float3 eval;
|
||||
|
||||
*pdf = 0.0f;
|
||||
#ifdef __OSL__
|
||||
if (kg->osl)
|
||||
label = OSLShader::bsdf_sample(sd, sc, randu, randv, eval, *omega_in, *domega_in, *pdf);
|
||||
else
|
||||
#endif
|
||||
label = svm_bsdf_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
|
||||
label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
|
||||
|
||||
if(*pdf != 0.0f) {
|
||||
bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass);
|
||||
|
||||
if(sd->num_closure > 1) {
|
||||
float sweight = sc->sample_weight;
|
||||
#ifdef __OSL__
|
||||
if (kg->osl)
|
||||
_shader_bsdf_multi_eval_osl(sd, *omega_in, pdf, sampled, bsdf_eval, *pdf*sweight, sweight);
|
||||
else
|
||||
#endif
|
||||
_shader_bsdf_multi_eval_svm(sd, *omega_in, pdf, sampled, bsdf_eval, *pdf*sweight, sweight);
|
||||
_shader_bsdf_multi_eval(kg, sd, *omega_in, pdf, sampled, bsdf_eval, *pdf*sweight, sweight);
|
||||
}
|
||||
}
|
||||
|
||||
@ -464,7 +405,7 @@ __device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd,
|
||||
#else
|
||||
/* sample the single closure that we picked */
|
||||
*pdf = 0.0f;
|
||||
int label = svm_bsdf_sample(sd, &sd->closure, randu, randv, bsdf_eval, omega_in, domega_in, pdf);
|
||||
int label = bsdf_sample(kg, sd, &sd->closure, randu, randv, bsdf_eval, omega_in, domega_in, pdf);
|
||||
*bsdf_eval *= sd->closure.weight;
|
||||
return label;
|
||||
#endif
|
||||
@ -478,12 +419,7 @@ __device int shader_bsdf_sample_closure(KernelGlobals *kg, const ShaderData *sd,
|
||||
float3 eval;
|
||||
|
||||
*pdf = 0.0f;
|
||||
#ifdef __OSL__
|
||||
if (kg->osl)
|
||||
label = OSLShader::bsdf_sample(sd, sc, randu, randv, eval, *omega_in, *domega_in, *pdf);
|
||||
else
|
||||
#endif
|
||||
label = svm_bsdf_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
|
||||
label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
|
||||
|
||||
if(*pdf != 0.0f)
|
||||
bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass);
|
||||
@ -497,17 +433,11 @@ __device void shader_bsdf_blur(KernelGlobals *kg, ShaderData *sd, float roughnes
|
||||
for(int i = 0; i< sd->num_closure; i++) {
|
||||
ShaderClosure *sc = &sd->closure[i];
|
||||
|
||||
if(CLOSURE_IS_BSDF(sc->type)) {
|
||||
#ifdef __OSL__
|
||||
if (kg->osl)
|
||||
OSLShader::bsdf_blur(sc, roughness);
|
||||
else
|
||||
#endif
|
||||
svm_bsdf_blur(sc, roughness);
|
||||
}
|
||||
if(CLOSURE_IS_BSDF(sc->type))
|
||||
bsdf_blur(kg, sc, roughness);
|
||||
}
|
||||
#else
|
||||
svm_bsdf_blur(&sd->closure, roughness);
|
||||
bsdf_blur(kg, &sd->closure, roughness);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -635,6 +565,16 @@ __device float3 shader_bsdf_ao(KernelGlobals *kg, ShaderData *sd, float ao_facto
|
||||
|
||||
/* Emission */
|
||||
|
||||
__device float3 emissive_eval(KernelGlobals *kg, ShaderData *sd, ShaderClosure *sc)
|
||||
{
|
||||
#ifdef __OSL__
|
||||
if(kg->osl && sc->prim)
|
||||
return OSLShader::emissive_eval(sd, sc);
|
||||
#endif
|
||||
|
||||
return emissive_simple_eval(sd->Ng, sd->I);
|
||||
}
|
||||
|
||||
__device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
|
||||
{
|
||||
float3 eval;
|
||||
@ -644,18 +584,11 @@ __device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
|
||||
for(int i = 0; i < sd->num_closure; i++) {
|
||||
ShaderClosure *sc = &sd->closure[i];
|
||||
|
||||
if(CLOSURE_IS_EMISSION(sc->type)) {
|
||||
#ifdef __OSL__
|
||||
if (kg->osl)
|
||||
eval += OSLShader::emissive_eval(sd, sc)*sc->weight;
|
||||
else
|
||||
#endif
|
||||
eval += svm_emissive_eval(sd, sc)*sc->weight;
|
||||
|
||||
}
|
||||
if(CLOSURE_IS_EMISSION(sc->type))
|
||||
eval += emissive_eval(kg, sd, sc)*sc->weight;
|
||||
}
|
||||
#else
|
||||
eval = svm_emissive_eval(sd, &sd->closure)*sd->closure.weight;
|
||||
eval = emissive_eval(kg, sd, &sd->closure)*sd->closure.weight;
|
||||
#endif
|
||||
|
||||
return eval;
|
||||
@ -687,11 +620,11 @@ __device float3 shader_holdout_eval(KernelGlobals *kg, ShaderData *sd)
|
||||
/* Surface Evaluation */
|
||||
|
||||
__device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
|
||||
float randb, int path_flag)
|
||||
float randb, int path_flag, ShaderContext ctx)
|
||||
{
|
||||
#ifdef __OSL__
|
||||
if (kg->osl)
|
||||
OSLShader::eval_surface(kg, sd, randb, path_flag);
|
||||
OSLShader::eval_surface(kg, sd, randb, path_flag, ctx);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
@ -706,11 +639,11 @@ __device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
|
||||
|
||||
/* Background Evaluation */
|
||||
|
||||
__device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag)
|
||||
__device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx)
|
||||
{
|
||||
#ifdef __OSL__
|
||||
if (kg->osl)
|
||||
return OSLShader::eval_background(kg, sd, path_flag);
|
||||
return OSLShader::eval_background(kg, sd, path_flag, ctx);
|
||||
else
|
||||
#endif
|
||||
|
||||
@ -753,31 +686,25 @@ __device float3 shader_volume_eval_phase(KernelGlobals *kg, ShaderData *sd,
|
||||
for(int i = 0; i< sd->num_closure; i++) {
|
||||
const ShaderClosure *sc = &sd->closure[i];
|
||||
|
||||
if(CLOSURE_IS_VOLUME(sc->type)) {
|
||||
#ifdef __OSL__
|
||||
if (kg->osl)
|
||||
eval += OSLShader::volume_eval_phase(sc, omega_in, omega_out);
|
||||
else
|
||||
#endif
|
||||
eval += volume_eval_phase(sc, omega_in, omega_out);
|
||||
}
|
||||
if(CLOSURE_IS_VOLUME(sc->type))
|
||||
eval += volume_eval_phase(kg, sc, omega_in, omega_out);
|
||||
}
|
||||
|
||||
return eval;
|
||||
#else
|
||||
return volume_eval_phase(&sd->closure, omega_in, omega_out);
|
||||
return volume_eval_phase(kg, &sd->closure, omega_in, omega_out);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Volume Evaluation */
|
||||
|
||||
__device void shader_eval_volume(KernelGlobals *kg, ShaderData *sd,
|
||||
float randb, int path_flag)
|
||||
float randb, int path_flag, ShaderContext ctx)
|
||||
{
|
||||
#ifdef __SVM__
|
||||
#ifdef __OSL__
|
||||
if (kg->osl)
|
||||
OSLShader::eval_volume(kg, sd, randb, path_flag);
|
||||
OSLShader::eval_volume(kg, sd, randb, path_flag, ctx);
|
||||
else
|
||||
#endif
|
||||
svm_eval_nodes(kg, sd, SHADER_TYPE_VOLUME, randb, path_flag);
|
||||
@ -786,13 +713,13 @@ __device void shader_eval_volume(KernelGlobals *kg, ShaderData *sd,
|
||||
|
||||
/* Displacement Evaluation */
|
||||
|
||||
__device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd)
|
||||
__device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd, ShaderContext ctx)
|
||||
{
|
||||
/* this will modify sd->P */
|
||||
#ifdef __SVM__
|
||||
#ifdef __OSL__
|
||||
if (kg->osl)
|
||||
OSLShader::eval_displacement(kg, sd);
|
||||
OSLShader::eval_displacement(kg, sd, ctx);
|
||||
else
|
||||
#endif
|
||||
svm_eval_nodes(kg, sd, SHADER_TYPE_DISPLACEMENT, 0.0f, 0);
|
||||
@ -818,7 +745,6 @@ __device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect)
|
||||
#ifdef __NON_PROGRESSIVE__
|
||||
__device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd)
|
||||
{
|
||||
#ifndef __OSL__
|
||||
/* merge identical closures, better when we sample a single closure at a time */
|
||||
for(int i = 0; i < sd->num_closure; i++) {
|
||||
ShaderClosure *sci = &sd->closure[i];
|
||||
@ -826,7 +752,7 @@ __device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd)
|
||||
for(int j = i + 1; j < sd->num_closure; j++) {
|
||||
ShaderClosure *scj = &sd->closure[j];
|
||||
|
||||
if(sci->type == scj->type && sci->data0 == scj->data0 && sci->data1 == scj->data1) {
|
||||
if(!sci->prim && sci->type == scj->type && sci->data0 == scj->data0 && sci->data1 == scj->data1) {
|
||||
sci->weight += scj->weight;
|
||||
sci->sample_weight += scj->sample_weight;
|
||||
|
||||
@ -838,7 +764,6 @@ __device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -846,10 +771,7 @@ __device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd)
|
||||
|
||||
__device void shader_release(KernelGlobals *kg, ShaderData *sd)
|
||||
{
|
||||
#ifdef __OSL__
|
||||
if (kg->osl)
|
||||
OSLShader::release(kg, sd);
|
||||
#endif
|
||||
/* nothing to do currently */
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@ -379,6 +379,18 @@ typedef struct ShaderClosure {
|
||||
#endif
|
||||
} ShaderClosure;
|
||||
|
||||
/* Shader Context
|
||||
*
|
||||
* For OSL we recycle a fixed number of contexts for speed */
|
||||
|
||||
typedef enum ShaderContext {
|
||||
SHADER_CONTEXT_MAIN = 0,
|
||||
SHADER_CONTEXT_INDIRECT = 1,
|
||||
SHADER_CONTEXT_EMISSION = 2,
|
||||
SHADER_CONTEXT_SHADOW = 3,
|
||||
SHADER_CONTEXT_NUM = 4
|
||||
} ShaderContext;
|
||||
|
||||
/* Shader Data
|
||||
*
|
||||
* Main shader state at a point on the surface or in a volume. All coordinates
|
||||
@ -466,11 +478,6 @@ typedef struct ShaderData {
|
||||
/* Closure data, with a single sampled closure for low memory usage */
|
||||
ShaderClosure closure;
|
||||
#endif
|
||||
|
||||
#ifdef __OSL__
|
||||
/* OSL context */
|
||||
void *osl_ctx;
|
||||
#endif
|
||||
} ShaderData;
|
||||
|
||||
/* Constrant Kernel Data
|
||||
|
@ -55,7 +55,7 @@ public:
|
||||
|
||||
void setup()
|
||||
{
|
||||
sc.N = TO_FLOAT3(N);
|
||||
sc.prim = this;
|
||||
m_shaderdata_flag = bsdf_diffuse_ramp_setup(&sc);
|
||||
|
||||
for(int i = 0; i < 8; i++)
|
||||
@ -101,7 +101,7 @@ public:
|
||||
ClosureParam *closure_bsdf_diffuse_ramp_params()
|
||||
{
|
||||
static ClosureParam params[] = {
|
||||
CLOSURE_VECTOR_PARAM(DiffuseRampClosure, N),
|
||||
CLOSURE_FLOAT3_PARAM(DiffuseRampClosure, sc.N),
|
||||
CLOSURE_COLOR_ARRAY_PARAM(DiffuseRampClosure, colors, 8),
|
||||
CLOSURE_STRING_KEYPARAM("label"),
|
||||
CLOSURE_FINISH_PARAM(DiffuseRampClosure)
|
||||
|
@ -54,7 +54,7 @@ public:
|
||||
|
||||
void setup()
|
||||
{
|
||||
sc.N = TO_FLOAT3(N);
|
||||
sc.prim = this;
|
||||
m_shaderdata_flag = bsdf_phong_ramp_setup(&sc);
|
||||
|
||||
for(int i = 0; i < 8; i++)
|
||||
@ -100,7 +100,7 @@ public:
|
||||
ClosureParam *closure_bsdf_phong_ramp_params()
|
||||
{
|
||||
static ClosureParam params[] = {
|
||||
CLOSURE_VECTOR_PARAM(PhongRampClosure, N),
|
||||
CLOSURE_FLOAT3_PARAM(PhongRampClosure, sc.N),
|
||||
CLOSURE_FLOAT_PARAM(PhongRampClosure, sc.data0),
|
||||
CLOSURE_COLOR_ARRAY_PARAM(PhongRampClosure, colors, 8),
|
||||
CLOSURE_STRING_KEYPARAM("label"),
|
||||
|
@ -65,7 +65,7 @@ public:
|
||||
|
||||
Color3 eval(const Vec3 &Ng, const Vec3 &omega_out) const
|
||||
{
|
||||
float3 result = emissive_eval(TO_FLOAT3(Ng), TO_FLOAT3(omega_out));
|
||||
float3 result = emissive_simple_eval(TO_FLOAT3(Ng), TO_FLOAT3(omega_out));
|
||||
return TO_COLOR3(result);
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@
|
||||
#include "kernel_types.h"
|
||||
#include "kernel_montecarlo.h"
|
||||
|
||||
#include "closure/bsdf.h"
|
||||
#include "closure/bsdf_util.h"
|
||||
#include "closure/bsdf_ashikhmin_velvet.h"
|
||||
#include "closure/bsdf_diffuse.h"
|
||||
#include "closure/bsdf_microfacet.h"
|
||||
@ -62,34 +62,34 @@ using namespace OSL;
|
||||
/* BSDF class definitions */
|
||||
|
||||
BSDF_CLOSURE_CLASS_BEGIN(Diffuse, diffuse, diffuse, LABEL_DIFFUSE)
|
||||
CLOSURE_VECTOR_PARAM(DiffuseClosure, N),
|
||||
CLOSURE_FLOAT3_PARAM(DiffuseClosure, sc.N),
|
||||
BSDF_CLOSURE_CLASS_END(Diffuse, diffuse)
|
||||
|
||||
BSDF_CLOSURE_CLASS_BEGIN(Translucent, translucent, translucent, LABEL_DIFFUSE)
|
||||
CLOSURE_VECTOR_PARAM(TranslucentClosure, N),
|
||||
CLOSURE_FLOAT3_PARAM(TranslucentClosure, sc.N),
|
||||
BSDF_CLOSURE_CLASS_END(Translucent, translucent)
|
||||
|
||||
BSDF_CLOSURE_CLASS_BEGIN(OrenNayar, oren_nayar, oren_nayar, LABEL_DIFFUSE)
|
||||
CLOSURE_VECTOR_PARAM(OrenNayarClosure, N),
|
||||
CLOSURE_FLOAT3_PARAM(OrenNayarClosure, sc.N),
|
||||
CLOSURE_FLOAT_PARAM(OrenNayarClosure, sc.data0),
|
||||
BSDF_CLOSURE_CLASS_END(OrenNayar, oren_nayar)
|
||||
|
||||
BSDF_CLOSURE_CLASS_BEGIN(Reflection, reflection, reflection, LABEL_SINGULAR)
|
||||
CLOSURE_VECTOR_PARAM(ReflectionClosure, N),
|
||||
CLOSURE_FLOAT3_PARAM(ReflectionClosure, sc.N),
|
||||
BSDF_CLOSURE_CLASS_END(Reflection, reflection)
|
||||
|
||||
BSDF_CLOSURE_CLASS_BEGIN(Refraction, refraction, refraction, LABEL_SINGULAR)
|
||||
CLOSURE_VECTOR_PARAM(RefractionClosure, N),
|
||||
CLOSURE_FLOAT3_PARAM(RefractionClosure, sc.N),
|
||||
CLOSURE_FLOAT_PARAM(RefractionClosure, sc.data0),
|
||||
BSDF_CLOSURE_CLASS_END(Refraction, refraction)
|
||||
|
||||
BSDF_CLOSURE_CLASS_BEGIN(WestinBackscatter, westin_backscatter, westin_backscatter, LABEL_GLOSSY)
|
||||
CLOSURE_VECTOR_PARAM(WestinBackscatterClosure, N),
|
||||
CLOSURE_FLOAT3_PARAM(WestinBackscatterClosure, sc.N),
|
||||
CLOSURE_FLOAT_PARAM(WestinBackscatterClosure, sc.data0),
|
||||
BSDF_CLOSURE_CLASS_END(WestinBackscatter, westin_backscatter)
|
||||
|
||||
BSDF_CLOSURE_CLASS_BEGIN(WestinSheen, westin_sheen, westin_sheen, LABEL_DIFFUSE)
|
||||
CLOSURE_VECTOR_PARAM(WestinSheenClosure, N),
|
||||
CLOSURE_FLOAT3_PARAM(WestinSheenClosure, sc.N),
|
||||
CLOSURE_FLOAT_PARAM(WestinSheenClosure, sc.data0),
|
||||
BSDF_CLOSURE_CLASS_END(WestinSheen, westin_sheen)
|
||||
|
||||
@ -97,35 +97,35 @@ BSDF_CLOSURE_CLASS_BEGIN(Transparent, transparent, transparent, LABEL_SINGULAR)
|
||||
BSDF_CLOSURE_CLASS_END(Transparent, transparent)
|
||||
|
||||
BSDF_CLOSURE_CLASS_BEGIN(AshikhminVelvet, ashikhmin_velvet, ashikhmin_velvet, LABEL_DIFFUSE)
|
||||
CLOSURE_VECTOR_PARAM(AshikhminVelvetClosure, N),
|
||||
CLOSURE_FLOAT3_PARAM(AshikhminVelvetClosure, sc.N),
|
||||
CLOSURE_FLOAT_PARAM(AshikhminVelvetClosure, sc.data0),
|
||||
BSDF_CLOSURE_CLASS_END(AshikhminVelvet, ashikhmin_velvet)
|
||||
|
||||
BSDF_CLOSURE_CLASS_BEGIN(Ward, ward, ward, LABEL_GLOSSY)
|
||||
CLOSURE_VECTOR_PARAM(WardClosure, N),
|
||||
CLOSURE_VECTOR_PARAM(WardClosure, T),
|
||||
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(MicrofacetGGX, microfacet_ggx, microfacet_ggx, LABEL_GLOSSY)
|
||||
CLOSURE_VECTOR_PARAM(MicrofacetGGXClosure, N),
|
||||
CLOSURE_FLOAT3_PARAM(MicrofacetGGXClosure, sc.N),
|
||||
CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure, sc.data0),
|
||||
BSDF_CLOSURE_CLASS_END(MicrofacetGGX, microfacet_ggx)
|
||||
|
||||
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmann, microfacet_beckmann, microfacet_beckmann, LABEL_GLOSSY)
|
||||
CLOSURE_VECTOR_PARAM(MicrofacetBeckmannClosure, N),
|
||||
CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannClosure, sc.N),
|
||||
CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure, sc.data0),
|
||||
BSDF_CLOSURE_CLASS_END(MicrofacetBeckmann, microfacet_beckmann)
|
||||
|
||||
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXRefraction, microfacet_ggx_refraction, microfacet_ggx, LABEL_GLOSSY)
|
||||
CLOSURE_VECTOR_PARAM(MicrofacetGGXRefractionClosure, N),
|
||||
CLOSURE_FLOAT3_PARAM(MicrofacetGGXRefractionClosure, sc.N),
|
||||
CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, sc.data0),
|
||||
CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, sc.data1),
|
||||
BSDF_CLOSURE_CLASS_END(MicrofacetGGXRefraction, microfacet_ggx_refraction)
|
||||
|
||||
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction, microfacet_beckmann, LABEL_GLOSSY)
|
||||
CLOSURE_VECTOR_PARAM(MicrofacetBeckmannRefractionClosure, N),
|
||||
CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannRefractionClosure, sc.N),
|
||||
CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, sc.data0),
|
||||
CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, sc.data1),
|
||||
BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction)
|
||||
|
@ -70,8 +70,11 @@ void name(RendererServices *, int id, void *data) \
|
||||
|
||||
#define CLOSURE_PREPARE_STATIC(name, classname) static CLOSURE_PREPARE(name, classname)
|
||||
|
||||
#define TO_VEC3(v) (*(OSL::Vec3 *)&(v))
|
||||
#define TO_COLOR3(v) (*(OSL::Color3 *)&(v))
|
||||
#define CLOSURE_FLOAT3_PARAM(st, fld) \
|
||||
{ TypeDesc::TypeVector, reckless_offsetof(st, fld), NULL, sizeof(OSL::Vec3) }
|
||||
|
||||
#define TO_VEC3(v) OSL::Vec3(v.x, v.y, v.z)
|
||||
#define TO_COLOR3(v) OSL::Color3(v.x, v.y, v.z)
|
||||
#define TO_FLOAT3(v) make_float3(v[0], v[1], v[2])
|
||||
|
||||
/* BSDF */
|
||||
@ -79,7 +82,6 @@ void name(RendererServices *, int id, void *data) \
|
||||
class CBSDFClosure : public OSL::ClosurePrimitive {
|
||||
public:
|
||||
ShaderClosure sc;
|
||||
OSL::Vec3 N, T;
|
||||
|
||||
CBSDFClosure(int scattering) : OSL::ClosurePrimitive(BSDF),
|
||||
m_scattering_label(scattering), m_shaderdata_flag(0) { }
|
||||
@ -87,7 +89,6 @@ public:
|
||||
|
||||
int scattering() const { return m_scattering_label; }
|
||||
int shaderdata_flag() const { return m_shaderdata_flag; }
|
||||
ClosureType shaderclosure_type() const { return sc.type; }
|
||||
|
||||
virtual void blur(float roughness) = 0;
|
||||
virtual float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float &pdf) const = 0;
|
||||
@ -114,8 +115,7 @@ public: \
|
||||
\
|
||||
void setup() \
|
||||
{ \
|
||||
sc.N = TO_FLOAT3(N); \
|
||||
sc.T = TO_FLOAT3(T); \
|
||||
sc.prim = NULL; \
|
||||
m_shaderdata_flag = bsdf_##lower##_setup(&sc); \
|
||||
} \
|
||||
\
|
||||
|
@ -75,10 +75,21 @@ struct OSLGlobals {
|
||||
vector<ustring> object_names;
|
||||
};
|
||||
|
||||
/* trace() call result */
|
||||
struct OSLTraceData {
|
||||
Ray ray;
|
||||
Intersection isect;
|
||||
ShaderData sd;
|
||||
bool setup;
|
||||
bool init;
|
||||
};
|
||||
|
||||
/* thread key for thread specific data lookup */
|
||||
struct OSLThreadData {
|
||||
OSL::ShaderGlobals globals;
|
||||
OSL::PerThreadInfo *thread_info;
|
||||
OSLTraceData tracedata;
|
||||
OSL::ShadingContext *context[SHADER_CONTEXT_NUM];
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@ -47,7 +47,7 @@ CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* RenderServices implementation */
|
||||
|
||||
#define TO_MATRIX44(m) (*(OSL::Matrix44 *)&(m))
|
||||
#define COPY_MATRIX44(m1, m2) memcpy(m1, m2, sizeof(*m2))
|
||||
|
||||
/* static ustrings */
|
||||
ustring OSLRenderServices::u_distance("distance");
|
||||
@ -121,7 +121,7 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr
|
||||
Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
|
||||
#endif
|
||||
tfm = transform_transpose(tfm);
|
||||
result = TO_MATRIX44(tfm);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -151,7 +151,7 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, OSL::Transform
|
||||
Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
|
||||
#endif
|
||||
itfm = transform_transpose(itfm);
|
||||
result = TO_MATRIX44(itfm);
|
||||
COPY_MATRIX44(&result, &itfm);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -166,22 +166,22 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, ustring from, float ti
|
||||
|
||||
if (from == u_ndc) {
|
||||
Transform tfm = transform_transpose(transform_quick_inverse(kernel_data.cam.worldtondc));
|
||||
result = TO_MATRIX44(tfm);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
return true;
|
||||
}
|
||||
else if (from == u_raster) {
|
||||
Transform tfm = transform_transpose(kernel_data.cam.rastertoworld);
|
||||
result = TO_MATRIX44(tfm);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
return true;
|
||||
}
|
||||
else if (from == u_screen) {
|
||||
Transform tfm = transform_transpose(kernel_data.cam.screentoworld);
|
||||
result = TO_MATRIX44(tfm);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
return true;
|
||||
}
|
||||
else if (from == u_camera) {
|
||||
Transform tfm = transform_transpose(kernel_data.cam.cameratoworld);
|
||||
result = TO_MATRIX44(tfm);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -194,22 +194,22 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, ustring to, fl
|
||||
|
||||
if (to == u_ndc) {
|
||||
Transform tfm = transform_transpose(kernel_data.cam.worldtondc);
|
||||
result = TO_MATRIX44(tfm);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
return true;
|
||||
}
|
||||
else if (to == u_raster) {
|
||||
Transform tfm = transform_transpose(kernel_data.cam.worldtoraster);
|
||||
result = TO_MATRIX44(tfm);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
return true;
|
||||
}
|
||||
else if (to == u_screen) {
|
||||
Transform tfm = transform_transpose(kernel_data.cam.worldtoscreen);
|
||||
result = TO_MATRIX44(tfm);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
return true;
|
||||
}
|
||||
else if (to == u_camera) {
|
||||
Transform tfm = transform_transpose(kernel_data.cam.worldtocamera);
|
||||
result = TO_MATRIX44(tfm);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -232,7 +232,7 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr
|
||||
Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
|
||||
#endif
|
||||
tfm = transform_transpose(tfm);
|
||||
result = TO_MATRIX44(tfm);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -257,7 +257,7 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, OSL::Transform
|
||||
Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
|
||||
#endif
|
||||
tfm = transform_transpose(tfm);
|
||||
result = TO_MATRIX44(tfm);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -272,22 +272,22 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, ustring from)
|
||||
|
||||
if (from == u_ndc) {
|
||||
Transform tfm = transform_transpose(transform_quick_inverse(kernel_data.cam.worldtondc));
|
||||
result = TO_MATRIX44(tfm);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
return true;
|
||||
}
|
||||
else if (from == u_raster) {
|
||||
Transform tfm = transform_transpose(kernel_data.cam.rastertoworld);
|
||||
result = TO_MATRIX44(tfm);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
return true;
|
||||
}
|
||||
else if (from == u_screen) {
|
||||
Transform tfm = transform_transpose(kernel_data.cam.screentoworld);
|
||||
result = TO_MATRIX44(tfm);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
return true;
|
||||
}
|
||||
else if (from == u_camera) {
|
||||
Transform tfm = transform_transpose(kernel_data.cam.cameratoworld);
|
||||
result = TO_MATRIX44(tfm);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -300,22 +300,22 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, ustring to)
|
||||
|
||||
if (to == u_ndc) {
|
||||
Transform tfm = transform_transpose(kernel_data.cam.worldtondc);
|
||||
result = TO_MATRIX44(tfm);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
return true;
|
||||
}
|
||||
else if (to == u_raster) {
|
||||
Transform tfm = transform_transpose(kernel_data.cam.worldtoraster);
|
||||
result = TO_MATRIX44(tfm);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
return true;
|
||||
}
|
||||
else if (to == u_screen) {
|
||||
Transform tfm = transform_transpose(kernel_data.cam.worldtoscreen);
|
||||
result = TO_MATRIX44(tfm);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
return true;
|
||||
}
|
||||
else if (to == u_camera) {
|
||||
Transform tfm = transform_transpose(kernel_data.cam.worldtocamera);
|
||||
result = TO_MATRIX44(tfm);
|
||||
COPY_MATRIX44(&result, &tfm);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -815,13 +815,10 @@ bool OSLRenderServices::trace(TraceOpt &options, OSL::ShaderGlobals *sg,
|
||||
ray.dD.dy = TO_FLOAT3(dRdy);
|
||||
|
||||
/* allocate trace data */
|
||||
TraceData *tracedata = new TraceData();
|
||||
OSLTraceData *tracedata = (OSLTraceData*)sg->tracedata;
|
||||
tracedata->ray = ray;
|
||||
tracedata->setup = false;
|
||||
|
||||
if(sg->tracedata)
|
||||
delete (TraceData*)sg->tracedata;
|
||||
sg->tracedata = tracedata;
|
||||
tracedata->init = true;
|
||||
|
||||
/* raytrace */
|
||||
return scene_intersect(kernel_globals, &ray, ~0, &tracedata->isect);
|
||||
@ -831,9 +828,9 @@ bool OSLRenderServices::trace(TraceOpt &options, OSL::ShaderGlobals *sg,
|
||||
bool OSLRenderServices::getmessage(OSL::ShaderGlobals *sg, ustring source, ustring name,
|
||||
TypeDesc type, void *val, bool derivatives)
|
||||
{
|
||||
TraceData *tracedata = (TraceData*)sg->tracedata;
|
||||
OSLTraceData *tracedata = (OSLTraceData*)sg->tracedata;
|
||||
|
||||
if(source == u_trace && tracedata) {
|
||||
if(source == u_trace && tracedata->init) {
|
||||
if(name == u_hit) {
|
||||
return set_attribute_int((tracedata->isect.prim != ~0), type, derivatives, val);
|
||||
}
|
||||
|
@ -106,13 +106,6 @@ public:
|
||||
static bool get_object_standard_attribute(KernelGlobals *kg, ShaderData *sd, ustring name,
|
||||
TypeDesc type, bool derivatives, void *val);
|
||||
|
||||
struct TraceData {
|
||||
Ray ray;
|
||||
Intersection isect;
|
||||
ShaderData sd;
|
||||
bool setup;
|
||||
};
|
||||
|
||||
static ustring u_distance;
|
||||
static ustring u_index;
|
||||
static ustring u_camera;
|
||||
|
@ -51,8 +51,13 @@ void OSLShader::thread_init(KernelGlobals *kg, KernelGlobals *kernel_globals, OS
|
||||
OSLThreadData *tdata = new OSLThreadData();
|
||||
|
||||
memset(&tdata->globals, 0, sizeof(OSL::ShaderGlobals));
|
||||
tdata->globals.tracedata = &tdata->tracedata;
|
||||
tdata->globals.flipHandedness = false;
|
||||
tdata->thread_info = ss->create_thread_info();
|
||||
|
||||
for(int i = 0; i < SHADER_CONTEXT_NUM; i++)
|
||||
tdata->context[i] = ss->get_context(tdata->thread_info);
|
||||
|
||||
kg->osl_ss = (OSLShadingSystem*)ss;
|
||||
kg->osl_tdata = tdata;
|
||||
}
|
||||
@ -65,6 +70,9 @@ void OSLShader::thread_free(KernelGlobals *kg)
|
||||
OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
|
||||
OSLThreadData *tdata = kg->osl_tdata;
|
||||
|
||||
for(int i = 0; i < SHADER_CONTEXT_NUM; i++)
|
||||
ss->release_context(tdata->context[i]);
|
||||
|
||||
ss->destroy_thread_info(tdata->thread_info);
|
||||
|
||||
delete tdata;
|
||||
@ -77,8 +85,10 @@ void OSLShader::thread_free(KernelGlobals *kg)
|
||||
/* Globals */
|
||||
|
||||
static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd,
|
||||
int path_flag, OSL::ShaderGlobals *globals)
|
||||
int path_flag, OSLThreadData *tdata)
|
||||
{
|
||||
OSL::ShaderGlobals *globals = &tdata->globals;
|
||||
|
||||
/* copy from shader data to shader globals */
|
||||
globals->P = TO_VEC3(sd->P);
|
||||
globals->dPdx = TO_VEC3(sd->dP.dx);
|
||||
@ -100,15 +110,11 @@ static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd,
|
||||
globals->time = sd->time;
|
||||
|
||||
/* booleans */
|
||||
globals->raytype = path_flag; /* todo: add our own ray types */
|
||||
globals->raytype = path_flag;
|
||||
globals->backfacing = (sd->flag & SD_BACKFACING);
|
||||
|
||||
/* don't know yet if we need this */
|
||||
globals->flipHandedness = false;
|
||||
|
||||
/* shader data to be used in services callbacks */
|
||||
globals->renderstate = sd;
|
||||
globals->tracedata = NULL;
|
||||
|
||||
/* hacky, we leave it to services to fetch actual object matrix */
|
||||
globals->shader2common = sd;
|
||||
@ -116,6 +122,9 @@ static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd,
|
||||
|
||||
/* must be set to NULL before execute */
|
||||
globals->Ci = NULL;
|
||||
|
||||
/* clear trace data */
|
||||
tdata->tracedata.init = false;
|
||||
}
|
||||
|
||||
/* Surface */
|
||||
@ -132,14 +141,10 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
|
||||
|
||||
if (prim) {
|
||||
ShaderClosure sc;
|
||||
sc.prim = prim;
|
||||
sc.weight = weight;
|
||||
|
||||
switch (prim->category()) {
|
||||
case OSL::ClosurePrimitive::BSDF: {
|
||||
if (sd->num_closure == MAX_CLOSURE)
|
||||
return;
|
||||
|
||||
CBSDFClosure *bsdf = (CBSDFClosure *)prim;
|
||||
int scattering = bsdf->scattering();
|
||||
|
||||
@ -151,8 +156,13 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
|
||||
float sample_weight = fabsf(average(weight));
|
||||
|
||||
sc.sample_weight = sample_weight;
|
||||
sc.type = bsdf->shaderclosure_type();
|
||||
sc.N = bsdf->sc.N; /* needed for AO */
|
||||
|
||||
sc.type = bsdf->sc.type;
|
||||
sc.N = bsdf->sc.N;
|
||||
sc.T = bsdf->sc.T;
|
||||
sc.data0 = bsdf->sc.data0;
|
||||
sc.data1 = bsdf->sc.data1;
|
||||
sc.prim = bsdf->sc.prim;
|
||||
|
||||
/* add */
|
||||
if(sc.sample_weight > 1e-5f && sd->num_closure < MAX_CLOSURE) {
|
||||
@ -170,6 +180,7 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
|
||||
|
||||
sc.sample_weight = sample_weight;
|
||||
sc.type = CLOSURE_EMISSION_ID;
|
||||
sc.prim = NULL;
|
||||
|
||||
/* flag */
|
||||
if(sd->num_closure < MAX_CLOSURE) {
|
||||
@ -179,14 +190,12 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
|
||||
break;
|
||||
}
|
||||
case AmbientOcclusion: {
|
||||
if (sd->num_closure == MAX_CLOSURE)
|
||||
return;
|
||||
|
||||
/* sample weight */
|
||||
float sample_weight = fabsf(average(weight));
|
||||
|
||||
sc.sample_weight = sample_weight;
|
||||
sc.type = CLOSURE_AMBIENT_OCCLUSION_ID;
|
||||
sc.prim = NULL;
|
||||
|
||||
if(sd->num_closure < MAX_CLOSURE) {
|
||||
sd->closure[sd->num_closure++] = sc;
|
||||
@ -195,11 +204,9 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
|
||||
break;
|
||||
}
|
||||
case OSL::ClosurePrimitive::Holdout:
|
||||
if (sd->num_closure == MAX_CLOSURE)
|
||||
return;
|
||||
|
||||
sc.sample_weight = 0.0f;
|
||||
sc.type = CLOSURE_HOLDOUT_ID;
|
||||
sc.prim = NULL;
|
||||
|
||||
if(sd->num_closure < MAX_CLOSURE) {
|
||||
sd->closure[sd->num_closure++] = sc;
|
||||
@ -226,26 +233,20 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
|
||||
}
|
||||
}
|
||||
|
||||
void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag)
|
||||
void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag, ShaderContext ctx)
|
||||
{
|
||||
/* gather pointers */
|
||||
OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
|
||||
OSLThreadData *tdata = kg->osl_tdata;
|
||||
OSL::ShaderGlobals *globals = &tdata->globals;
|
||||
OSL::ShadingContext *ctx = (OSL::ShadingContext *)sd->osl_ctx;
|
||||
|
||||
/* setup shader globals from shader data */
|
||||
shaderdata_to_shaderglobals(kg, sd, path_flag, globals);
|
||||
OSLThreadData *tdata = kg->osl_tdata;
|
||||
shaderdata_to_shaderglobals(kg, sd, path_flag, tdata);
|
||||
|
||||
/* execute shader for this point */
|
||||
OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
|
||||
OSL::ShaderGlobals *globals = &tdata->globals;
|
||||
OSL::ShadingContext *octx = tdata->context[(int)ctx];
|
||||
int shader = sd->shader & SHADER_MASK;
|
||||
|
||||
if (kg->osl->surface_state[shader])
|
||||
ss->execute(*ctx, *(kg->osl->surface_state[shader]), *globals);
|
||||
|
||||
/* free trace data */
|
||||
if(globals->tracedata)
|
||||
delete (OSLRenderServices::TraceData*)globals->tracedata;
|
||||
ss->execute(*octx, *(kg->osl->surface_state[shader]), *globals);
|
||||
|
||||
/* flatten closure tree */
|
||||
sd->num_closure = 0;
|
||||
@ -287,24 +288,19 @@ static float3 flatten_background_closure_tree(const OSL::ClosureColor *closure)
|
||||
return make_float3(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
float3 OSLShader::eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag)
|
||||
float3 OSLShader::eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx)
|
||||
{
|
||||
/* gather pointers */
|
||||
OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
|
||||
OSLThreadData *tdata = kg->osl_tdata;
|
||||
OSL::ShaderGlobals *globals = &tdata->globals;
|
||||
OSL::ShadingContext *ctx = (OSL::ShadingContext *)sd->osl_ctx;
|
||||
|
||||
/* setup shader globals from shader data */
|
||||
shaderdata_to_shaderglobals(kg, sd, path_flag, globals);
|
||||
OSLThreadData *tdata = kg->osl_tdata;
|
||||
shaderdata_to_shaderglobals(kg, sd, path_flag, tdata);
|
||||
|
||||
/* execute shader for this point */
|
||||
if (kg->osl->background_state)
|
||||
ss->execute(*ctx, *(kg->osl->background_state), *globals);
|
||||
OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
|
||||
OSL::ShaderGlobals *globals = &tdata->globals;
|
||||
OSL::ShadingContext *octx = tdata->context[(int)ctx];
|
||||
|
||||
/* free trace data */
|
||||
if(globals->tracedata)
|
||||
delete (OSLRenderServices::TraceData*)globals->tracedata;
|
||||
if (kg->osl->background_state)
|
||||
ss->execute(*octx, *(kg->osl->background_state), *globals);
|
||||
|
||||
/* return background color immediately */
|
||||
if (globals->Ci)
|
||||
@ -327,19 +323,16 @@ static void flatten_volume_closure_tree(ShaderData *sd,
|
||||
|
||||
if (prim) {
|
||||
ShaderClosure sc;
|
||||
sc.prim = prim;
|
||||
sc.weight = weight;
|
||||
|
||||
switch (prim->category()) {
|
||||
case OSL::ClosurePrimitive::Volume: {
|
||||
if (sd->num_closure == MAX_CLOSURE)
|
||||
return;
|
||||
|
||||
/* sample weight */
|
||||
float sample_weight = fabsf(average(weight));
|
||||
|
||||
sc.sample_weight = sample_weight;
|
||||
sc.type = CLOSURE_VOLUME_ID;
|
||||
sc.prim = NULL;
|
||||
|
||||
/* add */
|
||||
if(sc.sample_weight > 1e-5f && sd->num_closure < MAX_CLOSURE)
|
||||
@ -368,26 +361,20 @@ static void flatten_volume_closure_tree(ShaderData *sd,
|
||||
}
|
||||
}
|
||||
|
||||
void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag)
|
||||
void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag, ShaderContext ctx)
|
||||
{
|
||||
/* gather pointers */
|
||||
OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
|
||||
OSLThreadData *tdata = kg->osl_tdata;
|
||||
OSL::ShaderGlobals *globals = &tdata->globals;
|
||||
OSL::ShadingContext *ctx = (OSL::ShadingContext *)sd->osl_ctx;
|
||||
|
||||
/* setup shader globals from shader data */
|
||||
shaderdata_to_shaderglobals(kg, sd, path_flag, globals);
|
||||
OSLThreadData *tdata = kg->osl_tdata;
|
||||
shaderdata_to_shaderglobals(kg, sd, path_flag, tdata);
|
||||
|
||||
/* execute shader */
|
||||
OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
|
||||
OSL::ShaderGlobals *globals = &tdata->globals;
|
||||
OSL::ShadingContext *octx = tdata->context[(int)ctx];
|
||||
int shader = sd->shader & SHADER_MASK;
|
||||
|
||||
if (kg->osl->volume_state[shader])
|
||||
ss->execute(*ctx, *(kg->osl->volume_state[shader]), *globals);
|
||||
|
||||
/* free trace data */
|
||||
if(globals->tracedata)
|
||||
delete (OSLRenderServices::TraceData*)globals->tracedata;
|
||||
ss->execute(*octx, *(kg->osl->volume_state[shader]), *globals);
|
||||
|
||||
if (globals->Ci)
|
||||
flatten_volume_closure_tree(sd, globals->Ci);
|
||||
@ -395,46 +382,25 @@ void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int
|
||||
|
||||
/* Displacement */
|
||||
|
||||
void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd)
|
||||
void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd, ShaderContext ctx)
|
||||
{
|
||||
/* gather pointers */
|
||||
OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
|
||||
OSLThreadData *tdata = kg->osl_tdata;
|
||||
OSL::ShaderGlobals *globals = &tdata->globals;
|
||||
OSL::ShadingContext *ctx = (OSL::ShadingContext *)sd->osl_ctx;
|
||||
|
||||
/* setup shader globals from shader data */
|
||||
shaderdata_to_shaderglobals(kg, sd, 0, globals);
|
||||
OSLThreadData *tdata = kg->osl_tdata;
|
||||
shaderdata_to_shaderglobals(kg, sd, 0, tdata);
|
||||
|
||||
/* execute shader */
|
||||
OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
|
||||
OSL::ShaderGlobals *globals = &tdata->globals;
|
||||
OSL::ShadingContext *octx = tdata->context[(int)ctx];
|
||||
int shader = sd->shader & SHADER_MASK;
|
||||
|
||||
if (kg->osl->displacement_state[shader])
|
||||
ss->execute(*ctx, *(kg->osl->displacement_state[shader]), *globals);
|
||||
|
||||
/* free trace data */
|
||||
if(globals->tracedata)
|
||||
delete (OSLRenderServices::TraceData*)globals->tracedata;
|
||||
ss->execute(*octx, *(kg->osl->displacement_state[shader]), *globals);
|
||||
|
||||
/* get back position */
|
||||
sd->P = TO_FLOAT3(globals->P);
|
||||
}
|
||||
|
||||
void OSLShader::init(KernelGlobals *kg, ShaderData *sd)
|
||||
{
|
||||
OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
|
||||
OSLThreadData *tdata = kg->osl_tdata;
|
||||
|
||||
sd->osl_ctx = ss->get_context(tdata->thread_info);
|
||||
}
|
||||
|
||||
void OSLShader::release(KernelGlobals *kg, ShaderData *sd)
|
||||
{
|
||||
OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
|
||||
|
||||
ss->release_context((OSL::ShadingContext *)sd->osl_ctx);
|
||||
}
|
||||
|
||||
/* BSDF Closure */
|
||||
|
||||
int OSLShader::bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3& eval, float3& omega_in, differential3& domega_in, float& pdf)
|
||||
|
@ -55,10 +55,10 @@ public:
|
||||
static void thread_free(KernelGlobals *kg);
|
||||
|
||||
/* eval */
|
||||
static void eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag);
|
||||
static float3 eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag);
|
||||
static void eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag);
|
||||
static void eval_displacement(KernelGlobals *kg, ShaderData *sd);
|
||||
static void eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag, ShaderContext ctx);
|
||||
static float3 eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx);
|
||||
static void eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag, ShaderContext ctx);
|
||||
static void eval_displacement(KernelGlobals *kg, ShaderData *sd, ShaderContext ctx);
|
||||
|
||||
/* sample & eval */
|
||||
static int bsdf_sample(const ShaderData *sd, const ShaderClosure *sc,
|
||||
@ -73,10 +73,6 @@ public:
|
||||
static float3 volume_eval_phase(const ShaderClosure *sc,
|
||||
const float3 omega_in, const float3 omega_out);
|
||||
|
||||
/* release */
|
||||
static void init(KernelGlobals *kg, ShaderData *sd);
|
||||
static void release(KernelGlobals *kg, ShaderData *sd);
|
||||
|
||||
/* attributes */
|
||||
static int find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id);
|
||||
};
|
||||
|
@ -1,279 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011, Blender Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#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 int svm_bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, differential3 *domega_in, float *pdf)
|
||||
{
|
||||
int label;
|
||||
|
||||
switch(sc->type) {
|
||||
case CLOSURE_BSDF_DIFFUSE_ID:
|
||||
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
|
||||
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
|
||||
default:
|
||||
label = LABEL_NONE;
|
||||
break;
|
||||
}
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
__device float3 svm_bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, float *pdf)
|
||||
{
|
||||
float3 eval;
|
||||
|
||||
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 eval;
|
||||
}
|
||||
|
||||
__device void svm_bsdf_blur(ShaderClosure *sc, float roughness)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
Loading…
Reference in New Issue
Block a user