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:
Brecht Van Lommel
2012-12-15 10:18:42 +00:00
parent 35dd893c36
commit 06888b7beb
21 changed files with 599 additions and 690 deletions

View File

@@ -56,6 +56,7 @@ set(SRC_CLOSURE_HEADERS
closure/bsdf_reflection.h closure/bsdf_reflection.h
closure/bsdf_refraction.h closure/bsdf_refraction.h
closure/bsdf_transparent.h closure/bsdf_transparent.h
closure/bsdf_util.h
closure/bsdf_ward.h closure/bsdf_ward.h
closure/bsdf_westin.h closure/bsdf_westin.h
closure/emissive.h closure/emissive.h
@@ -64,7 +65,6 @@ set(SRC_CLOSURE_HEADERS
set(SRC_SVM_HEADERS set(SRC_SVM_HEADERS
svm/svm.h svm/svm.h
svm/svm_attribute.h svm/svm_attribute.h
svm/svm_bsdf.h
svm/svm_camera.h svm/svm_camera.h
svm/svm_closure.h svm/svm_closure.h
svm/svm_convert.h svm/svm_convert.h

View File

@@ -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. * This program is free software; you can redistribute it and/or
* All Rights Reserved. * 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 * You should have received a copy of the GNU General Public License
* modification, are permitted provided that the following conditions are * along with this program; if not, write to the Free Software Foundation,
* met: * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* * 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__ #include "../closure/bsdf_ashikhmin_velvet.h"
#define __OSL_BSDF_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 CCL_NAMESPACE_BEGIN
__device float fresnel_dielectric(float eta, const float3 N, __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)
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; int label;
float3 Nn;
// compute reflection #ifdef __OSL__
*R = (2 * cos)* N - I; if(kg->osl && sc->prim)
#ifdef __RAY_DIFFERENTIALS__ return OSLShader::bsdf_sample(sd, sc, randu, randv, *eval, *omega_in, *domega_in, *pdf);
*dRdx = (2 * dot(N, dIdx)) * N - dIdx;
*dRdy = (2 * dot(N, dIdy)) * N - dIdy;
#endif #endif
// check which side of the surface we are on
if(cos > 0) { switch(sc->type) {
// we are on the outside of the surface, going in case CLOSURE_BSDF_DIFFUSE_ID:
neta = 1 / eta; label = bsdf_diffuse_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
Nn = N; eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
*is_inside = false; break;
} #ifdef __SVM__
else { case CLOSURE_BSDF_OREN_NAYAR_ID:
// we are inside the surface, label = bsdf_oren_nayar_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
cos = -cos; eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
neta = eta; break;
Nn = -N; /*case CLOSURE_BSDF_PHONG_RAMP_ID:
*is_inside = true; 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);
*R = (2 * cos)* Nn - I; break;
float arg = 1 -(neta * neta *(1 -(cos * cos))); case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
if(arg < 0) { label = bsdf_diffuse_ramp_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
*T = make_float3(0.0f, 0.0f, 0.0f); eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
#ifdef __RAY_DIFFERENTIALS__ break;*/
*dTdx = make_float3(0.0f, 0.0f, 0.0f); case CLOSURE_BSDF_TRANSLUCENT_ID:
*dTdy = make_float3(0.0f, 0.0f, 0.0f); 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 #endif
return 1; // total internal reflection case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
} label = bsdf_ashikhmin_velvet_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
else { eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
float dnp = sqrtf(arg); break;
float nK = (neta * cos)- dnp; case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
*T = -(neta * I)+(nK * Nn); label = bsdf_westin_backscatter_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
#ifdef __RAY_DIFFERENTIALS__ eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
*dTdx = -(neta * dIdx) + ((neta - neta * neta * cos / dnp) * dot(dIdx, Nn)) * Nn; break;
*dTdy = -(neta * dIdy) + ((neta - neta * neta * cos / dnp) * dot(dIdy, Nn)) * Nn; 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 #endif
// compute Fresnel terms default:
float cosTheta1 = cos; // N.R label = LABEL_NONE;
float cosTheta2 = -dot(Nn, *T); break;
float pPara = (cosTheta1 - eta * cosTheta2)/(cosTheta1 + eta * cosTheta2);
float pPerp = (eta * cosTheta1 - cosTheta2)/(eta * cosTheta1 + cosTheta2);
return 0.5f * (pPara * pPara + pPerp * pPerp);
} }
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 float3 eval;
// the refracted direction
float c = fabsf(cosi); #ifdef __OSL__
float g = eta * eta - 1 + c * c; if(kg->osl && sc->prim)
if(g > 0) { return OSLShader::bsdf_eval(sd, sc, omega_in, *pdf);
g = sqrtf(g); #endif
float A = (g - c)/(g + c);
float B = (c *(g + c)- 1)/(c *(g - c)+ 1); if(dot(sd->Ng, omega_in) >= 0.0f) {
return 0.5f * A * A *(1 + B * B); 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 { else {
float t = (x - edge0)/(edge1 - edge0); switch(sc->type) {
result = (3.0f-2.0f*t)*(t*t); 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 CCL_NAMESPACE_END
#endif /* __OSL_BSDF_H__ */

View 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__ */

View File

@@ -49,17 +49,12 @@ __device void emissive_sample(const float3 Ng, float randu, float randv,
/* todo: not implemented and used yet */ /* 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); float res = emissive_pdf(Ng, I);
return make_float3(res, res, res); 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 CCL_NAMESPACE_END

View File

@@ -53,8 +53,13 @@ __device float3 volume_transparent_eval_phase(const ShaderClosure *sc, const flo
/* VOLUME CLOSURE */ /* 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; float3 eval;
switch(sc->type) { switch(sc->type) {

View File

@@ -35,7 +35,7 @@ __device void kernel_shader_evaluate(KernelGlobals *kg, uint4 *input, float4 *ou
/* evaluate */ /* evaluate */
float3 P = sd.P; float3 P = sd.P;
shader_eval_displacement(kg, &sd); shader_eval_displacement(kg, &sd, SHADER_CONTEXT_MAIN);
out = sd.P - P; out = sd.P - P;
} }
else { // SHADER_EVAL_BACKGROUND else { // SHADER_EVAL_BACKGROUND
@@ -63,7 +63,7 @@ __device void kernel_shader_evaluate(KernelGlobals *kg, uint4 *input, float4 *ou
/* evaluate */ /* evaluate */
int flag = 0; /* we can't know which type of BSDF this is for */ 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); shader_release(kg, &sd);

View File

@@ -42,7 +42,7 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando,
ray.time = time; ray.time = time;
#endif #endif
shader_setup_from_background(kg, &sd, &ray); 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 else
#endif #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 /* no path flag, we're evaluating this for all closures. that's weak but
* we'd have to do multiple evaluations otherwise */ * 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 */ /* evaluate emissive closure */
if(sd.flag & SD_EMISSION) if(sd.flag & SD_EMISSION)
@@ -170,7 +170,7 @@ __device float3 indirect_background(KernelGlobals *kg, Ray *ray, int path_flag,
/* evaluate background closure */ /* evaluate background closure */
ShaderData sd; ShaderData sd;
shader_setup_from_background(kg, &sd, ray); 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); shader_release(kg, &sd);
#ifdef __BACKGROUND_MIS__ #ifdef __BACKGROUND_MIS__

View File

@@ -207,7 +207,7 @@ __device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *ra
ShaderData sd; ShaderData sd;
shader_setup_from_ray(kg, &sd, &isect, ray); 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); throughput *= shader_bsdf_transparency(kg, &sd);
@@ -272,7 +272,7 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
ShaderData sd; ShaderData sd;
shader_setup_from_ray(kg, &sd, &isect, &ray); shader_setup_from_ray(kg, &sd, &isect, &ray);
float rbsdf = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF); 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); 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; ShaderData sd;
shader_setup_from_ray(kg, &sd, &isect, &ray); shader_setup_from_ray(kg, &sd, &isect, &ray);
float rbsdf = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF); 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); shader_merge_closures(kg, &sd);
/* blurring of bsdf after bounces, for rays that have a small likelihood /* 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; ShaderData sd;
shader_setup_from_ray(kg, &sd, &isect, &ray); shader_setup_from_ray(kg, &sd, &isect, &ray);
float rbsdf = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF); 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); shader_merge_closures(kg, &sd);
kernel_write_data_passes(kg, buffer, &L, &sd, sample, state.flag, throughput); kernel_write_data_passes(kg, buffer, &L, &sd, sample, state.flag, throughput);

View File

@@ -26,11 +26,11 @@
* *
*/ */
#include "closure/bsdf_util.h"
#include "closure/bsdf.h" #include "closure/bsdf.h"
#include "closure/emissive.h" #include "closure/emissive.h"
#include "closure/volume.h" #include "closure/volume.h"
#include "svm/svm_bsdf.h"
#include "svm/svm.h" #include "svm/svm.h"
CCL_NAMESPACE_BEGIN 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, __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
const Intersection *isect, const Ray *ray) const Intersection *isect, const Ray *ray)
{ {
#ifdef __OSL__
if (kg->osl)
OSLShader::init(kg, sd);
#endif
/* fetch triangle data */ /* fetch triangle data */
int prim = kernel_tex_fetch(__prim_index, isect->prim); int prim = kernel_tex_fetch(__prim_index, isect->prim);
float4 Ns = kernel_tex_fetch(__tri_normal, 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, const float3 P, const float3 Ng, const float3 I,
int shader, int object, int prim, float u, float v, float t, float time) 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 */ /* vectors */
sd->P = P; sd->P = P;
sd->N = Ng; 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) __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 */ /* vectors */
sd->P = ray->D; sd->P = ray->D;
sd->N = -sd->P; sd->N = -sd->P;
@@ -320,9 +305,8 @@ __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData
#ifdef __MULTI_CLOSURE__ #ifdef __MULTI_CLOSURE__
#ifdef __OSL__ __device_inline void _shader_bsdf_multi_eval(KernelGlobals *kg, const ShaderData *sd, const float3 omega_in, float *pdf,
__device_inline void _shader_bsdf_multi_eval_osl(const ShaderData *sd, const float3 omega_in, float *pdf, int skip_bsdf, BsdfEval *result_eval, float sum_pdf, float sum_sample_weight)
int skip_bsdf, BsdfEval *bsdf_eval, float sum_pdf, float sum_sample_weight)
{ {
for(int i = 0; i< sd->num_closure; i++) { for(int i = 0; i< sd->num_closure; i++) {
if(i == skip_bsdf) 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)) { if(CLOSURE_IS_BSDF(sc->type)) {
float bsdf_pdf = 0.0f; float bsdf_pdf = 0.0f;
float3 eval = bsdf_eval(kg, sd, sc, omega_in, &bsdf_pdf);
float3 eval = OSLShader::bsdf_eval(sd, sc, omega_in, bsdf_pdf);
if(bsdf_pdf != 0.0f) { 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;
}
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);
sum_pdf += bsdf_pdf*sc->sample_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__ #ifdef __MULTI_CLOSURE__
bsdf_eval_init(eval, NBUILTIN_CLOSURES, make_float3(0.0f, 0.0f, 0.0f), kernel_data.film.use_light_pass); bsdf_eval_init(eval, NBUILTIN_CLOSURES, make_float3(0.0f, 0.0f, 0.0f), kernel_data.film.use_light_pass);
#ifdef __OSL__ return _shader_bsdf_multi_eval(kg, sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
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);
#else #else
const ShaderClosure *sc = &sd->closure; const ShaderClosure *sc = &sd->closure;
*pdf = 0.0f; *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 #endif
} }
@@ -439,24 +390,14 @@ __device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd,
float3 eval; float3 eval;
*pdf = 0.0f; *pdf = 0.0f;
#ifdef __OSL__ label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
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);
if(*pdf != 0.0f) { if(*pdf != 0.0f) {
bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass); bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass);
if(sd->num_closure > 1) { if(sd->num_closure > 1) {
float sweight = sc->sample_weight; float sweight = sc->sample_weight;
#ifdef __OSL__ _shader_bsdf_multi_eval(kg, sd, *omega_in, pdf, sampled, bsdf_eval, *pdf*sweight, sweight);
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);
} }
} }
@@ -464,7 +405,7 @@ __device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd,
#else #else
/* sample the single closure that we picked */ /* sample the single closure that we picked */
*pdf = 0.0f; *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; *bsdf_eval *= sd->closure.weight;
return label; return label;
#endif #endif
@@ -478,12 +419,7 @@ __device int shader_bsdf_sample_closure(KernelGlobals *kg, const ShaderData *sd,
float3 eval; float3 eval;
*pdf = 0.0f; *pdf = 0.0f;
#ifdef __OSL__ label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
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);
if(*pdf != 0.0f) if(*pdf != 0.0f)
bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass); 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++) { for(int i = 0; i< sd->num_closure; i++) {
ShaderClosure *sc = &sd->closure[i]; ShaderClosure *sc = &sd->closure[i];
if(CLOSURE_IS_BSDF(sc->type)) { if(CLOSURE_IS_BSDF(sc->type))
#ifdef __OSL__ bsdf_blur(kg, sc, roughness);
if (kg->osl)
OSLShader::bsdf_blur(sc, roughness);
else
#endif
svm_bsdf_blur(sc, roughness);
}
} }
#else #else
svm_bsdf_blur(&sd->closure, roughness); bsdf_blur(kg, &sd->closure, roughness);
#endif #endif
} }
@@ -635,6 +565,16 @@ __device float3 shader_bsdf_ao(KernelGlobals *kg, ShaderData *sd, float ao_facto
/* Emission */ /* 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) __device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
{ {
float3 eval; float3 eval;
@@ -644,18 +584,11 @@ __device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
for(int i = 0; i < sd->num_closure; i++) { for(int i = 0; i < sd->num_closure; i++) {
ShaderClosure *sc = &sd->closure[i]; ShaderClosure *sc = &sd->closure[i];
if(CLOSURE_IS_EMISSION(sc->type)) { if(CLOSURE_IS_EMISSION(sc->type))
#ifdef __OSL__ eval += emissive_eval(kg, sd, sc)*sc->weight;
if (kg->osl)
eval += OSLShader::emissive_eval(sd, sc)*sc->weight;
else
#endif
eval += svm_emissive_eval(sd, sc)*sc->weight;
}
} }
#else #else
eval = svm_emissive_eval(sd, &sd->closure)*sd->closure.weight; eval = emissive_eval(kg, sd, &sd->closure)*sd->closure.weight;
#endif #endif
return eval; return eval;
@@ -687,11 +620,11 @@ __device float3 shader_holdout_eval(KernelGlobals *kg, ShaderData *sd)
/* Surface Evaluation */ /* Surface Evaluation */
__device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd, __device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
float randb, int path_flag) float randb, int path_flag, ShaderContext ctx)
{ {
#ifdef __OSL__ #ifdef __OSL__
if (kg->osl) if (kg->osl)
OSLShader::eval_surface(kg, sd, randb, path_flag); OSLShader::eval_surface(kg, sd, randb, path_flag, ctx);
else else
#endif #endif
{ {
@@ -706,11 +639,11 @@ __device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
/* Background Evaluation */ /* 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__ #ifdef __OSL__
if (kg->osl) if (kg->osl)
return OSLShader::eval_background(kg, sd, path_flag); return OSLShader::eval_background(kg, sd, path_flag, ctx);
else else
#endif #endif
@@ -753,31 +686,25 @@ __device float3 shader_volume_eval_phase(KernelGlobals *kg, ShaderData *sd,
for(int i = 0; i< sd->num_closure; i++) { for(int i = 0; i< sd->num_closure; i++) {
const ShaderClosure *sc = &sd->closure[i]; const ShaderClosure *sc = &sd->closure[i];
if(CLOSURE_IS_VOLUME(sc->type)) { if(CLOSURE_IS_VOLUME(sc->type))
#ifdef __OSL__ eval += volume_eval_phase(kg, sc, omega_in, omega_out);
if (kg->osl)
eval += OSLShader::volume_eval_phase(sc, omega_in, omega_out);
else
#endif
eval += volume_eval_phase(sc, omega_in, omega_out);
}
} }
return eval; return eval;
#else #else
return volume_eval_phase(&sd->closure, omega_in, omega_out); return volume_eval_phase(kg, &sd->closure, omega_in, omega_out);
#endif #endif
} }
/* Volume Evaluation */ /* Volume Evaluation */
__device void shader_eval_volume(KernelGlobals *kg, ShaderData *sd, __device void shader_eval_volume(KernelGlobals *kg, ShaderData *sd,
float randb, int path_flag) float randb, int path_flag, ShaderContext ctx)
{ {
#ifdef __SVM__ #ifdef __SVM__
#ifdef __OSL__ #ifdef __OSL__
if (kg->osl) if (kg->osl)
OSLShader::eval_volume(kg, sd, randb, path_flag); OSLShader::eval_volume(kg, sd, randb, path_flag, ctx);
else else
#endif #endif
svm_eval_nodes(kg, sd, SHADER_TYPE_VOLUME, randb, path_flag); 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 */ /* 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 */ /* this will modify sd->P */
#ifdef __SVM__ #ifdef __SVM__
#ifdef __OSL__ #ifdef __OSL__
if (kg->osl) if (kg->osl)
OSLShader::eval_displacement(kg, sd); OSLShader::eval_displacement(kg, sd, ctx);
else else
#endif #endif
svm_eval_nodes(kg, sd, SHADER_TYPE_DISPLACEMENT, 0.0f, 0); 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__ #ifdef __NON_PROGRESSIVE__
__device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd) __device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd)
{ {
#ifndef __OSL__
/* merge identical closures, better when we sample a single closure at a time */ /* merge identical closures, better when we sample a single closure at a time */
for(int i = 0; i < sd->num_closure; i++) { for(int i = 0; i < sd->num_closure; i++) {
ShaderClosure *sci = &sd->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++) { for(int j = i + 1; j < sd->num_closure; j++) {
ShaderClosure *scj = &sd->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->weight += scj->weight;
sci->sample_weight += scj->sample_weight; sci->sample_weight += scj->sample_weight;
@@ -838,7 +764,6 @@ __device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd)
} }
} }
} }
#endif
} }
#endif #endif
@@ -846,10 +771,7 @@ __device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd)
__device void shader_release(KernelGlobals *kg, ShaderData *sd) __device void shader_release(KernelGlobals *kg, ShaderData *sd)
{ {
#ifdef __OSL__ /* nothing to do currently */
if (kg->osl)
OSLShader::release(kg, sd);
#endif
} }
CCL_NAMESPACE_END CCL_NAMESPACE_END

View File

@@ -379,6 +379,18 @@ typedef struct ShaderClosure {
#endif #endif
} ShaderClosure; } 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 /* Shader Data
* *
* Main shader state at a point on the surface or in a volume. All coordinates * 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 */ /* Closure data, with a single sampled closure for low memory usage */
ShaderClosure closure; ShaderClosure closure;
#endif #endif
#ifdef __OSL__
/* OSL context */
void *osl_ctx;
#endif
} ShaderData; } ShaderData;
/* Constrant Kernel Data /* Constrant Kernel Data

View File

@@ -55,7 +55,7 @@ public:
void setup() void setup()
{ {
sc.N = TO_FLOAT3(N); sc.prim = this;
m_shaderdata_flag = bsdf_diffuse_ramp_setup(&sc); m_shaderdata_flag = bsdf_diffuse_ramp_setup(&sc);
for(int i = 0; i < 8; i++) for(int i = 0; i < 8; i++)
@@ -101,7 +101,7 @@ public:
ClosureParam *closure_bsdf_diffuse_ramp_params() ClosureParam *closure_bsdf_diffuse_ramp_params()
{ {
static ClosureParam params[] = { static ClosureParam params[] = {
CLOSURE_VECTOR_PARAM(DiffuseRampClosure, N), CLOSURE_FLOAT3_PARAM(DiffuseRampClosure, sc.N),
CLOSURE_COLOR_ARRAY_PARAM(DiffuseRampClosure, colors, 8), CLOSURE_COLOR_ARRAY_PARAM(DiffuseRampClosure, colors, 8),
CLOSURE_STRING_KEYPARAM("label"), CLOSURE_STRING_KEYPARAM("label"),
CLOSURE_FINISH_PARAM(DiffuseRampClosure) CLOSURE_FINISH_PARAM(DiffuseRampClosure)

View File

@@ -54,7 +54,7 @@ public:
void setup() void setup()
{ {
sc.N = TO_FLOAT3(N); sc.prim = this;
m_shaderdata_flag = bsdf_phong_ramp_setup(&sc); m_shaderdata_flag = bsdf_phong_ramp_setup(&sc);
for(int i = 0; i < 8; i++) for(int i = 0; i < 8; i++)
@@ -100,7 +100,7 @@ public:
ClosureParam *closure_bsdf_phong_ramp_params() ClosureParam *closure_bsdf_phong_ramp_params()
{ {
static ClosureParam params[] = { static ClosureParam params[] = {
CLOSURE_VECTOR_PARAM(PhongRampClosure, N), CLOSURE_FLOAT3_PARAM(PhongRampClosure, sc.N),
CLOSURE_FLOAT_PARAM(PhongRampClosure, sc.data0), CLOSURE_FLOAT_PARAM(PhongRampClosure, sc.data0),
CLOSURE_COLOR_ARRAY_PARAM(PhongRampClosure, colors, 8), CLOSURE_COLOR_ARRAY_PARAM(PhongRampClosure, colors, 8),
CLOSURE_STRING_KEYPARAM("label"), CLOSURE_STRING_KEYPARAM("label"),

View File

@@ -65,7 +65,7 @@ public:
Color3 eval(const Vec3 &Ng, const Vec3 &omega_out) const 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); return TO_COLOR3(result);
} }

View File

@@ -43,7 +43,7 @@
#include "kernel_types.h" #include "kernel_types.h"
#include "kernel_montecarlo.h" #include "kernel_montecarlo.h"
#include "closure/bsdf.h" #include "closure/bsdf_util.h"
#include "closure/bsdf_ashikhmin_velvet.h" #include "closure/bsdf_ashikhmin_velvet.h"
#include "closure/bsdf_diffuse.h" #include "closure/bsdf_diffuse.h"
#include "closure/bsdf_microfacet.h" #include "closure/bsdf_microfacet.h"
@@ -62,34 +62,34 @@ using namespace OSL;
/* BSDF class definitions */ /* BSDF class definitions */
BSDF_CLOSURE_CLASS_BEGIN(Diffuse, diffuse, diffuse, LABEL_DIFFUSE) 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_END(Diffuse, diffuse)
BSDF_CLOSURE_CLASS_BEGIN(Translucent, translucent, translucent, LABEL_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_END(Translucent, translucent)
BSDF_CLOSURE_CLASS_BEGIN(OrenNayar, oren_nayar, oren_nayar, LABEL_DIFFUSE) 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), CLOSURE_FLOAT_PARAM(OrenNayarClosure, sc.data0),
BSDF_CLOSURE_CLASS_END(OrenNayar, oren_nayar) BSDF_CLOSURE_CLASS_END(OrenNayar, oren_nayar)
BSDF_CLOSURE_CLASS_BEGIN(Reflection, reflection, reflection, LABEL_SINGULAR) 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_END(Reflection, reflection)
BSDF_CLOSURE_CLASS_BEGIN(Refraction, refraction, refraction, LABEL_SINGULAR) 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), CLOSURE_FLOAT_PARAM(RefractionClosure, sc.data0),
BSDF_CLOSURE_CLASS_END(Refraction, refraction) BSDF_CLOSURE_CLASS_END(Refraction, refraction)
BSDF_CLOSURE_CLASS_BEGIN(WestinBackscatter, westin_backscatter, westin_backscatter, LABEL_GLOSSY) 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), CLOSURE_FLOAT_PARAM(WestinBackscatterClosure, sc.data0),
BSDF_CLOSURE_CLASS_END(WestinBackscatter, westin_backscatter) BSDF_CLOSURE_CLASS_END(WestinBackscatter, westin_backscatter)
BSDF_CLOSURE_CLASS_BEGIN(WestinSheen, westin_sheen, westin_sheen, LABEL_DIFFUSE) 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), CLOSURE_FLOAT_PARAM(WestinSheenClosure, sc.data0),
BSDF_CLOSURE_CLASS_END(WestinSheen, westin_sheen) 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_END(Transparent, transparent)
BSDF_CLOSURE_CLASS_BEGIN(AshikhminVelvet, ashikhmin_velvet, ashikhmin_velvet, LABEL_DIFFUSE) 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), CLOSURE_FLOAT_PARAM(AshikhminVelvetClosure, sc.data0),
BSDF_CLOSURE_CLASS_END(AshikhminVelvet, ashikhmin_velvet) BSDF_CLOSURE_CLASS_END(AshikhminVelvet, ashikhmin_velvet)
BSDF_CLOSURE_CLASS_BEGIN(Ward, ward, ward, LABEL_GLOSSY) BSDF_CLOSURE_CLASS_BEGIN(Ward, ward, ward, LABEL_GLOSSY)
CLOSURE_VECTOR_PARAM(WardClosure, N), CLOSURE_FLOAT3_PARAM(WardClosure, sc.N),
CLOSURE_VECTOR_PARAM(WardClosure, T), CLOSURE_FLOAT3_PARAM(WardClosure, sc.T),
CLOSURE_FLOAT_PARAM(WardClosure, sc.data0), CLOSURE_FLOAT_PARAM(WardClosure, sc.data0),
CLOSURE_FLOAT_PARAM(WardClosure, sc.data1), CLOSURE_FLOAT_PARAM(WardClosure, sc.data1),
BSDF_CLOSURE_CLASS_END(Ward, ward) BSDF_CLOSURE_CLASS_END(Ward, ward)
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGX, microfacet_ggx, microfacet_ggx, LABEL_GLOSSY) 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), CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure, sc.data0),
BSDF_CLOSURE_CLASS_END(MicrofacetGGX, microfacet_ggx) BSDF_CLOSURE_CLASS_END(MicrofacetGGX, microfacet_ggx)
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmann, microfacet_beckmann, microfacet_beckmann, LABEL_GLOSSY) 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), CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure, sc.data0),
BSDF_CLOSURE_CLASS_END(MicrofacetBeckmann, microfacet_beckmann) BSDF_CLOSURE_CLASS_END(MicrofacetBeckmann, microfacet_beckmann)
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXRefraction, microfacet_ggx_refraction, microfacet_ggx, LABEL_GLOSSY) 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.data0),
CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, sc.data1), CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, sc.data1),
BSDF_CLOSURE_CLASS_END(MicrofacetGGXRefraction, microfacet_ggx_refraction) BSDF_CLOSURE_CLASS_END(MicrofacetGGXRefraction, microfacet_ggx_refraction)
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction, microfacet_beckmann, LABEL_GLOSSY) 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.data0),
CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, sc.data1), CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, sc.data1),
BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction) BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction)

View File

@@ -70,8 +70,11 @@ void name(RendererServices *, int id, void *data) \
#define CLOSURE_PREPARE_STATIC(name, classname) static CLOSURE_PREPARE(name, classname) #define CLOSURE_PREPARE_STATIC(name, classname) static CLOSURE_PREPARE(name, classname)
#define TO_VEC3(v) (*(OSL::Vec3 *)&(v)) #define CLOSURE_FLOAT3_PARAM(st, fld) \
#define TO_COLOR3(v) (*(OSL::Color3 *)&(v)) { 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]) #define TO_FLOAT3(v) make_float3(v[0], v[1], v[2])
/* BSDF */ /* BSDF */
@@ -79,7 +82,6 @@ void name(RendererServices *, int id, void *data) \
class CBSDFClosure : public OSL::ClosurePrimitive { class CBSDFClosure : public OSL::ClosurePrimitive {
public: public:
ShaderClosure sc; ShaderClosure sc;
OSL::Vec3 N, T;
CBSDFClosure(int scattering) : OSL::ClosurePrimitive(BSDF), CBSDFClosure(int scattering) : OSL::ClosurePrimitive(BSDF),
m_scattering_label(scattering), m_shaderdata_flag(0) { } m_scattering_label(scattering), m_shaderdata_flag(0) { }
@@ -87,7 +89,6 @@ public:
int scattering() const { return m_scattering_label; } int scattering() const { return m_scattering_label; }
int shaderdata_flag() const { return m_shaderdata_flag; } int shaderdata_flag() const { return m_shaderdata_flag; }
ClosureType shaderclosure_type() const { return sc.type; }
virtual void blur(float roughness) = 0; virtual void blur(float roughness) = 0;
virtual float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float &pdf) const = 0; virtual float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float &pdf) const = 0;
@@ -114,8 +115,7 @@ public: \
\ \
void setup() \ void setup() \
{ \ { \
sc.N = TO_FLOAT3(N); \ sc.prim = NULL; \
sc.T = TO_FLOAT3(T); \
m_shaderdata_flag = bsdf_##lower##_setup(&sc); \ m_shaderdata_flag = bsdf_##lower##_setup(&sc); \
} \ } \
\ \

View File

@@ -75,10 +75,21 @@ struct OSLGlobals {
vector<ustring> object_names; 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 */ /* thread key for thread specific data lookup */
struct OSLThreadData { struct OSLThreadData {
OSL::ShaderGlobals globals; OSL::ShaderGlobals globals;
OSL::PerThreadInfo *thread_info; OSL::PerThreadInfo *thread_info;
OSLTraceData tracedata;
OSL::ShadingContext *context[SHADER_CONTEXT_NUM];
}; };
CCL_NAMESPACE_END CCL_NAMESPACE_END

View File

@@ -47,7 +47,7 @@ CCL_NAMESPACE_BEGIN
/* RenderServices implementation */ /* RenderServices implementation */
#define TO_MATRIX44(m) (*(OSL::Matrix44 *)&(m)) #define COPY_MATRIX44(m1, m2) memcpy(m1, m2, sizeof(*m2))
/* static ustrings */ /* static ustrings */
ustring OSLRenderServices::u_distance("distance"); 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); Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
#endif #endif
tfm = transform_transpose(tfm); tfm = transform_transpose(tfm);
result = TO_MATRIX44(tfm); COPY_MATRIX44(&result, &tfm);
return true; 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); Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
#endif #endif
itfm = transform_transpose(itfm); itfm = transform_transpose(itfm);
result = TO_MATRIX44(itfm); COPY_MATRIX44(&result, &itfm);
return true; return true;
} }
@@ -166,22 +166,22 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, ustring from, float ti
if (from == u_ndc) { if (from == u_ndc) {
Transform tfm = transform_transpose(transform_quick_inverse(kernel_data.cam.worldtondc)); Transform tfm = transform_transpose(transform_quick_inverse(kernel_data.cam.worldtondc));
result = TO_MATRIX44(tfm); COPY_MATRIX44(&result, &tfm);
return true; return true;
} }
else if (from == u_raster) { else if (from == u_raster) {
Transform tfm = transform_transpose(kernel_data.cam.rastertoworld); Transform tfm = transform_transpose(kernel_data.cam.rastertoworld);
result = TO_MATRIX44(tfm); COPY_MATRIX44(&result, &tfm);
return true; return true;
} }
else if (from == u_screen) { else if (from == u_screen) {
Transform tfm = transform_transpose(kernel_data.cam.screentoworld); Transform tfm = transform_transpose(kernel_data.cam.screentoworld);
result = TO_MATRIX44(tfm); COPY_MATRIX44(&result, &tfm);
return true; return true;
} }
else if (from == u_camera) { else if (from == u_camera) {
Transform tfm = transform_transpose(kernel_data.cam.cameratoworld); Transform tfm = transform_transpose(kernel_data.cam.cameratoworld);
result = TO_MATRIX44(tfm); COPY_MATRIX44(&result, &tfm);
return true; return true;
} }
@@ -194,22 +194,22 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, ustring to, fl
if (to == u_ndc) { if (to == u_ndc) {
Transform tfm = transform_transpose(kernel_data.cam.worldtondc); Transform tfm = transform_transpose(kernel_data.cam.worldtondc);
result = TO_MATRIX44(tfm); COPY_MATRIX44(&result, &tfm);
return true; return true;
} }
else if (to == u_raster) { else if (to == u_raster) {
Transform tfm = transform_transpose(kernel_data.cam.worldtoraster); Transform tfm = transform_transpose(kernel_data.cam.worldtoraster);
result = TO_MATRIX44(tfm); COPY_MATRIX44(&result, &tfm);
return true; return true;
} }
else if (to == u_screen) { else if (to == u_screen) {
Transform tfm = transform_transpose(kernel_data.cam.worldtoscreen); Transform tfm = transform_transpose(kernel_data.cam.worldtoscreen);
result = TO_MATRIX44(tfm); COPY_MATRIX44(&result, &tfm);
return true; return true;
} }
else if (to == u_camera) { else if (to == u_camera) {
Transform tfm = transform_transpose(kernel_data.cam.worldtocamera); Transform tfm = transform_transpose(kernel_data.cam.worldtocamera);
result = TO_MATRIX44(tfm); COPY_MATRIX44(&result, &tfm);
return true; return true;
} }
@@ -232,7 +232,7 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr
Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
#endif #endif
tfm = transform_transpose(tfm); tfm = transform_transpose(tfm);
result = TO_MATRIX44(tfm); COPY_MATRIX44(&result, &tfm);
return true; 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); Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
#endif #endif
tfm = transform_transpose(tfm); tfm = transform_transpose(tfm);
result = TO_MATRIX44(tfm); COPY_MATRIX44(&result, &tfm);
return true; return true;
} }
@@ -272,22 +272,22 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, ustring from)
if (from == u_ndc) { if (from == u_ndc) {
Transform tfm = transform_transpose(transform_quick_inverse(kernel_data.cam.worldtondc)); Transform tfm = transform_transpose(transform_quick_inverse(kernel_data.cam.worldtondc));
result = TO_MATRIX44(tfm); COPY_MATRIX44(&result, &tfm);
return true; return true;
} }
else if (from == u_raster) { else if (from == u_raster) {
Transform tfm = transform_transpose(kernel_data.cam.rastertoworld); Transform tfm = transform_transpose(kernel_data.cam.rastertoworld);
result = TO_MATRIX44(tfm); COPY_MATRIX44(&result, &tfm);
return true; return true;
} }
else if (from == u_screen) { else if (from == u_screen) {
Transform tfm = transform_transpose(kernel_data.cam.screentoworld); Transform tfm = transform_transpose(kernel_data.cam.screentoworld);
result = TO_MATRIX44(tfm); COPY_MATRIX44(&result, &tfm);
return true; return true;
} }
else if (from == u_camera) { else if (from == u_camera) {
Transform tfm = transform_transpose(kernel_data.cam.cameratoworld); Transform tfm = transform_transpose(kernel_data.cam.cameratoworld);
result = TO_MATRIX44(tfm); COPY_MATRIX44(&result, &tfm);
return true; return true;
} }
@@ -300,22 +300,22 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, ustring to)
if (to == u_ndc) { if (to == u_ndc) {
Transform tfm = transform_transpose(kernel_data.cam.worldtondc); Transform tfm = transform_transpose(kernel_data.cam.worldtondc);
result = TO_MATRIX44(tfm); COPY_MATRIX44(&result, &tfm);
return true; return true;
} }
else if (to == u_raster) { else if (to == u_raster) {
Transform tfm = transform_transpose(kernel_data.cam.worldtoraster); Transform tfm = transform_transpose(kernel_data.cam.worldtoraster);
result = TO_MATRIX44(tfm); COPY_MATRIX44(&result, &tfm);
return true; return true;
} }
else if (to == u_screen) { else if (to == u_screen) {
Transform tfm = transform_transpose(kernel_data.cam.worldtoscreen); Transform tfm = transform_transpose(kernel_data.cam.worldtoscreen);
result = TO_MATRIX44(tfm); COPY_MATRIX44(&result, &tfm);
return true; return true;
} }
else if (to == u_camera) { else if (to == u_camera) {
Transform tfm = transform_transpose(kernel_data.cam.worldtocamera); Transform tfm = transform_transpose(kernel_data.cam.worldtocamera);
result = TO_MATRIX44(tfm); COPY_MATRIX44(&result, &tfm);
return true; return true;
} }
@@ -815,13 +815,10 @@ bool OSLRenderServices::trace(TraceOpt &options, OSL::ShaderGlobals *sg,
ray.dD.dy = TO_FLOAT3(dRdy); ray.dD.dy = TO_FLOAT3(dRdy);
/* allocate trace data */ /* allocate trace data */
TraceData *tracedata = new TraceData(); OSLTraceData *tracedata = (OSLTraceData*)sg->tracedata;
tracedata->ray = ray; tracedata->ray = ray;
tracedata->setup = false; tracedata->setup = false;
tracedata->init = true;
if(sg->tracedata)
delete (TraceData*)sg->tracedata;
sg->tracedata = tracedata;
/* raytrace */ /* raytrace */
return scene_intersect(kernel_globals, &ray, ~0, &tracedata->isect); 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, bool OSLRenderServices::getmessage(OSL::ShaderGlobals *sg, ustring source, ustring name,
TypeDesc type, void *val, bool derivatives) 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) { if(name == u_hit) {
return set_attribute_int((tracedata->isect.prim != ~0), type, derivatives, val); return set_attribute_int((tracedata->isect.prim != ~0), type, derivatives, val);
} }

View File

@@ -106,13 +106,6 @@ public:
static bool get_object_standard_attribute(KernelGlobals *kg, ShaderData *sd, ustring name, static bool get_object_standard_attribute(KernelGlobals *kg, ShaderData *sd, ustring name,
TypeDesc type, bool derivatives, void *val); TypeDesc type, bool derivatives, void *val);
struct TraceData {
Ray ray;
Intersection isect;
ShaderData sd;
bool setup;
};
static ustring u_distance; static ustring u_distance;
static ustring u_index; static ustring u_index;
static ustring u_camera; static ustring u_camera;

View File

@@ -51,8 +51,13 @@ void OSLShader::thread_init(KernelGlobals *kg, KernelGlobals *kernel_globals, OS
OSLThreadData *tdata = new OSLThreadData(); OSLThreadData *tdata = new OSLThreadData();
memset(&tdata->globals, 0, sizeof(OSL::ShaderGlobals)); memset(&tdata->globals, 0, sizeof(OSL::ShaderGlobals));
tdata->globals.tracedata = &tdata->tracedata;
tdata->globals.flipHandedness = false;
tdata->thread_info = ss->create_thread_info(); 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_ss = (OSLShadingSystem*)ss;
kg->osl_tdata = tdata; kg->osl_tdata = tdata;
} }
@@ -65,6 +70,9 @@ void OSLShader::thread_free(KernelGlobals *kg)
OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss; OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
OSLThreadData *tdata = kg->osl_tdata; 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); ss->destroy_thread_info(tdata->thread_info);
delete tdata; delete tdata;
@@ -77,8 +85,10 @@ void OSLShader::thread_free(KernelGlobals *kg)
/* Globals */ /* Globals */
static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd, 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 */ /* copy from shader data to shader globals */
globals->P = TO_VEC3(sd->P); globals->P = TO_VEC3(sd->P);
globals->dPdx = TO_VEC3(sd->dP.dx); globals->dPdx = TO_VEC3(sd->dP.dx);
@@ -100,15 +110,11 @@ static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd,
globals->time = sd->time; globals->time = sd->time;
/* booleans */ /* booleans */
globals->raytype = path_flag; /* todo: add our own ray types */ globals->raytype = path_flag;
globals->backfacing = (sd->flag & SD_BACKFACING); 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 */ /* shader data to be used in services callbacks */
globals->renderstate = sd; globals->renderstate = sd;
globals->tracedata = NULL;
/* hacky, we leave it to services to fetch actual object matrix */ /* hacky, we leave it to services to fetch actual object matrix */
globals->shader2common = sd; globals->shader2common = sd;
@@ -116,6 +122,9 @@ static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd,
/* must be set to NULL before execute */ /* must be set to NULL before execute */
globals->Ci = NULL; globals->Ci = NULL;
/* clear trace data */
tdata->tracedata.init = false;
} }
/* Surface */ /* Surface */
@@ -132,14 +141,10 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
if (prim) { if (prim) {
ShaderClosure sc; ShaderClosure sc;
sc.prim = prim;
sc.weight = weight; sc.weight = weight;
switch (prim->category()) { switch (prim->category()) {
case OSL::ClosurePrimitive::BSDF: { case OSL::ClosurePrimitive::BSDF: {
if (sd->num_closure == MAX_CLOSURE)
return;
CBSDFClosure *bsdf = (CBSDFClosure *)prim; CBSDFClosure *bsdf = (CBSDFClosure *)prim;
int scattering = bsdf->scattering(); 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)); float sample_weight = fabsf(average(weight));
sc.sample_weight = sample_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 */ /* add */
if(sc.sample_weight > 1e-5f && sd->num_closure < MAX_CLOSURE) { 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.sample_weight = sample_weight;
sc.type = CLOSURE_EMISSION_ID; sc.type = CLOSURE_EMISSION_ID;
sc.prim = NULL;
/* flag */ /* flag */
if(sd->num_closure < MAX_CLOSURE) { if(sd->num_closure < MAX_CLOSURE) {
@@ -179,14 +190,12 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
break; break;
} }
case AmbientOcclusion: { case AmbientOcclusion: {
if (sd->num_closure == MAX_CLOSURE)
return;
/* sample weight */ /* sample weight */
float sample_weight = fabsf(average(weight)); float sample_weight = fabsf(average(weight));
sc.sample_weight = sample_weight; sc.sample_weight = sample_weight;
sc.type = CLOSURE_AMBIENT_OCCLUSION_ID; sc.type = CLOSURE_AMBIENT_OCCLUSION_ID;
sc.prim = NULL;
if(sd->num_closure < MAX_CLOSURE) { if(sd->num_closure < MAX_CLOSURE) {
sd->closure[sd->num_closure++] = sc; sd->closure[sd->num_closure++] = sc;
@@ -195,11 +204,9 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
break; break;
} }
case OSL::ClosurePrimitive::Holdout: case OSL::ClosurePrimitive::Holdout:
if (sd->num_closure == MAX_CLOSURE)
return;
sc.sample_weight = 0.0f; sc.sample_weight = 0.0f;
sc.type = CLOSURE_HOLDOUT_ID; sc.type = CLOSURE_HOLDOUT_ID;
sc.prim = NULL;
if(sd->num_closure < MAX_CLOSURE) { if(sd->num_closure < MAX_CLOSURE) {
sd->closure[sd->num_closure++] = sc; 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 */ /* 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 */ /* 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; int shader = sd->shader & SHADER_MASK;
if (kg->osl->surface_state[shader]) if (kg->osl->surface_state[shader])
ss->execute(*ctx, *(kg->osl->surface_state[shader]), *globals); ss->execute(*octx, *(kg->osl->surface_state[shader]), *globals);
/* free trace data */
if(globals->tracedata)
delete (OSLRenderServices::TraceData*)globals->tracedata;
/* flatten closure tree */ /* flatten closure tree */
sd->num_closure = 0; 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); 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 */ /* 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 */ /* execute shader for this point */
if (kg->osl->background_state) OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
ss->execute(*ctx, *(kg->osl->background_state), *globals); OSL::ShaderGlobals *globals = &tdata->globals;
OSL::ShadingContext *octx = tdata->context[(int)ctx];
/* free trace data */ if (kg->osl->background_state)
if(globals->tracedata) ss->execute(*octx, *(kg->osl->background_state), *globals);
delete (OSLRenderServices::TraceData*)globals->tracedata;
/* return background color immediately */ /* return background color immediately */
if (globals->Ci) if (globals->Ci)
@@ -327,19 +323,16 @@ static void flatten_volume_closure_tree(ShaderData *sd,
if (prim) { if (prim) {
ShaderClosure sc; ShaderClosure sc;
sc.prim = prim;
sc.weight = weight; sc.weight = weight;
switch (prim->category()) { switch (prim->category()) {
case OSL::ClosurePrimitive::Volume: { case OSL::ClosurePrimitive::Volume: {
if (sd->num_closure == MAX_CLOSURE)
return;
/* sample weight */ /* sample weight */
float sample_weight = fabsf(average(weight)); float sample_weight = fabsf(average(weight));
sc.sample_weight = sample_weight; sc.sample_weight = sample_weight;
sc.type = CLOSURE_VOLUME_ID; sc.type = CLOSURE_VOLUME_ID;
sc.prim = NULL;
/* add */ /* add */
if(sc.sample_weight > 1e-5f && sd->num_closure < MAX_CLOSURE) 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 */ /* 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 */ /* 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; int shader = sd->shader & SHADER_MASK;
if (kg->osl->volume_state[shader]) if (kg->osl->volume_state[shader])
ss->execute(*ctx, *(kg->osl->volume_state[shader]), *globals); ss->execute(*octx, *(kg->osl->volume_state[shader]), *globals);
/* free trace data */
if(globals->tracedata)
delete (OSLRenderServices::TraceData*)globals->tracedata;
if (globals->Ci) if (globals->Ci)
flatten_volume_closure_tree(sd, 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 */ /* 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 */ /* 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 */ /* 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; int shader = sd->shader & SHADER_MASK;
if (kg->osl->displacement_state[shader]) if (kg->osl->displacement_state[shader])
ss->execute(*ctx, *(kg->osl->displacement_state[shader]), *globals); ss->execute(*octx, *(kg->osl->displacement_state[shader]), *globals);
/* free trace data */
if(globals->tracedata)
delete (OSLRenderServices::TraceData*)globals->tracedata;
/* get back position */ /* get back position */
sd->P = TO_FLOAT3(globals->P); 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 */ /* 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) int OSLShader::bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3& eval, float3& omega_in, differential3& domega_in, float& pdf)

View File

@@ -55,10 +55,10 @@ public:
static void thread_free(KernelGlobals *kg); static void thread_free(KernelGlobals *kg);
/* eval */ /* eval */
static void eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag); 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); 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); static void eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag, ShaderContext ctx);
static void eval_displacement(KernelGlobals *kg, ShaderData *sd); static void eval_displacement(KernelGlobals *kg, ShaderData *sd, ShaderContext ctx);
/* sample & eval */ /* sample & eval */
static int bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, static int bsdf_sample(const ShaderData *sd, const ShaderClosure *sc,
@@ -73,10 +73,6 @@ public:
static float3 volume_eval_phase(const ShaderClosure *sc, static float3 volume_eval_phase(const ShaderClosure *sc,
const float3 omega_in, const float3 omega_out); const float3 omega_in, const float3 omega_out);
/* release */
static void init(KernelGlobals *kg, ShaderData *sd);
static void release(KernelGlobals *kg, ShaderData *sd);
/* attributes */ /* attributes */
static int find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id); static int find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id);
}; };

View File

@@ -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