diff options
Diffstat (limited to 'intern/cycles/kernel/osl/osl_shader.cpp')
-rw-r--r-- | intern/cycles/kernel/osl/osl_shader.cpp | 148 |
1 files changed, 80 insertions, 68 deletions
diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp index ea508dcb660..abf7c041cb3 100644 --- a/intern/cycles/kernel/osl/osl_shader.cpp +++ b/intern/cycles/kernel/osl/osl_shader.cpp @@ -21,6 +21,7 @@ #include "kernel_globals.h" #include "kernel_object.h" +#include "osl_closures.h" #include "osl_services.h" #include "osl_shader.h" @@ -31,9 +32,32 @@ CCL_NAMESPACE_BEGIN tls_ptr(OSLGlobals::ThreadData, OSLGlobals::thread_data); +volatile int OSLGlobals::thread_data_users = 0; +thread_mutex OSLGlobals::thread_data_mutex; /* Threads */ +void OSLGlobals::thread_data_init() +{ + thread_scoped_lock thread_data_lock(thread_data_mutex); + + if(thread_data_users == 0) + tls_create(OSLGlobals::ThreadData, thread_data); + + thread_data_users++; +} + +void OSLGlobals::thread_data_free() +{ + /* thread local storage delete */ + thread_scoped_lock thread_data_lock(thread_data_mutex); + + thread_data_users--; + + if(thread_data_users == 0) + tls_delete(OSLGlobals::ThreadData, thread_data); +} + void OSLShader::thread_init(KernelGlobals *kg) { OSL::ShadingSystem *ss = kg->osl.ss; @@ -61,10 +85,6 @@ void OSLShader::thread_free(KernelGlobals *kg) /* Globals */ -#define TO_VEC3(v) (*(OSL::Vec3 *)&(v)) -#define TO_COLOR3(v) (*(OSL::Color3 *)&(v)) -#define TO_FLOAT3(v) make_float3(v[0], v[1], v[2]) - static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd, int path_flag, OSL::ShaderGlobals *globals) { @@ -96,6 +116,7 @@ static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd, /* 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; @@ -127,39 +148,20 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy, if (sd->num_closure == MAX_CLOSURE) return; - OSL::BSDFClosure *bsdf = (OSL::BSDFClosure *)prim; - ustring scattering = bsdf->scattering(); + CBSDFClosure *bsdf = (CBSDFClosure *)prim; + int scattering = bsdf->scattering(); /* no caustics option */ - if (no_glossy && scattering == OSL::Labels::GLOSSY) + if (no_glossy && scattering == LABEL_GLOSSY) return; /* sample weight */ - float albedo = bsdf->albedo(TO_VEC3(sd->I)); - float sample_weight = fabsf(average(weight)) * albedo; + float sample_weight = fabsf(average(weight)); - sc.sample_weight = sample_weight; + sd->flag |= bsdf->shaderdata_flag(); - /* scattering flags */ - if (scattering == OSL::Labels::DIFFUSE) { - sd->flag |= SD_BSDF | SD_BSDF_HAS_EVAL; - sc.type = CLOSURE_BSDF_DIFFUSE_ID; - } - else if (scattering == OSL::Labels::GLOSSY) { - sd->flag |= SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_GLOSSY; - sc.type = CLOSURE_BSDF_GLOSSY_ID; - } - else if (scattering == OSL::Labels::STRAIGHT) { - sd->flag |= SD_BSDF; - sc.type = CLOSURE_BSDF_TRANSPARENT_ID; - } - else { - /* todo: we don't actually have a way to determine if - * this closure will reflect/transmit. could add our own - * own scattering flag that do give this info */ - sd->flag |= SD_BSDF; - sc.type = CLOSURE_BSDF_GLOSSY_ID; - } + sc.sample_weight = sample_weight; + sc.type = bsdf->shaderclosure_type(); /* add */ sd->closure[sd->num_closure++] = sc; @@ -181,6 +183,20 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy, sd->closure[sd->num_closure++] = sc; 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; + + sd->closure[sd->num_closure++] = sc; + sd->flag |= SD_AO; + break; + } case OSL::ClosurePrimitive::Holdout: if (sd->num_closure == MAX_CLOSURE) return; @@ -227,6 +243,10 @@ void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int 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; + /* flatten closure tree */ sd->num_closure = 0; sd->randb_closure = randb; @@ -282,6 +302,10 @@ float3 OSLShader::eval_background(KernelGlobals *kg, ShaderData *sd, int path_fl if (kg->osl.background_state) ss->execute(*ctx, *(kg->osl.background_state), *globals); + /* free trace data */ + if(globals->tracedata) + delete (OSLRenderServices::TraceData*)globals->tracedata; + /* return background color immediately */ if (globals->Ci) return flatten_background_closure_tree(globals->Ci); @@ -360,6 +384,10 @@ void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int 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; + if (globals->Ci) flatten_volume_closure_tree(sd, globals->Ci); } @@ -383,6 +411,10 @@ void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd) 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; + /* get back position */ sd->P = TO_FLOAT3(globals->P); } @@ -406,54 +438,34 @@ void OSLShader::release(KernelGlobals *kg, ShaderData *sd) int OSLShader::bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3& eval, float3& omega_in, differential3& domega_in, float& pdf) { - OSL::BSDFClosure *sample_bsdf = (OSL::BSDFClosure *)sc->prim; - int label = LABEL_NONE; + CBSDFClosure *sample_bsdf = (CBSDFClosure *)sc->prim; pdf = 0.0f; - /* sample BSDF closure */ - ustring ulabel; - - ulabel = sample_bsdf->sample(TO_VEC3(sd->Ng), - TO_VEC3(sd->I), TO_VEC3(sd->dI.dx), TO_VEC3(sd->dI.dy), - randu, randv, - TO_VEC3(omega_in), TO_VEC3(domega_in.dx), TO_VEC3(domega_in.dy), - pdf, TO_COLOR3(eval)); - - /* convert OSL label */ - if (ulabel == OSL::Labels::REFLECT) - label = LABEL_REFLECT; - else if (ulabel == OSL::Labels::TRANSMIT) - label = LABEL_TRANSMIT; - else - return LABEL_NONE; /* sampling failed */ - - /* convert scattering to our bitflag label */ - ustring uscattering = sample_bsdf->scattering(); - - if (uscattering == OSL::Labels::DIFFUSE) - label |= LABEL_DIFFUSE; - else if (uscattering == OSL::Labels::GLOSSY) - label |= LABEL_GLOSSY; - else if (uscattering == OSL::Labels::SINGULAR) - label |= LABEL_SINGULAR; - else - label |= LABEL_TRANSPARENT; - - return label; + return sample_bsdf->sample(sd->Ng, + sd->I, sd->dI.dx, sd->dI.dy, + randu, randv, + omega_in, domega_in.dx, domega_in.dy, + pdf, eval); } float3 OSLShader::bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, const float3& omega_in, float& pdf) { - OSL::BSDFClosure *bsdf = (OSL::BSDFClosure *)sc->prim; - OSL::Color3 bsdf_eval; + CBSDFClosure *bsdf = (CBSDFClosure *)sc->prim; + float3 bsdf_eval; if (dot(sd->Ng, omega_in) >= 0.0f) - bsdf_eval = bsdf->eval_reflect(TO_VEC3(sd->I), TO_VEC3(omega_in), pdf); + bsdf_eval = bsdf->eval_reflect(sd->I, omega_in, pdf); else - bsdf_eval = bsdf->eval_transmit(TO_VEC3(sd->I), TO_VEC3(omega_in), pdf); + bsdf_eval = bsdf->eval_transmit(sd->I, omega_in, pdf); - return TO_FLOAT3(bsdf_eval); + return bsdf_eval; +} + +void OSLShader::bsdf_blur(ShaderClosure *sc, float roughness) +{ + CBSDFClosure *bsdf = (CBSDFClosure *)sc->prim; + bsdf->blur(roughness); } /* Emissive Closure */ @@ -468,7 +480,7 @@ float3 OSLShader::emissive_eval(const ShaderData *sd, const ShaderClosure *sc) /* Volume Closure */ -float3 OSLShader::volume_eval_phase(const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, const float3 omega_out) +float3 OSLShader::volume_eval_phase(const ShaderClosure *sc, const float3 omega_in, const float3 omega_out) { OSL::VolumeClosure *volume = (OSL::VolumeClosure *)sc->prim; OSL::Color3 volume_eval = volume->eval_phase(TO_VEC3(omega_in), TO_VEC3(omega_out)); |