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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/kernel/osl/osl_shader.cpp')
-rw-r--r--intern/cycles/kernel/osl/osl_shader.cpp148
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));