Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/kernel/osl/osl_shader.cpp
| Show All 19 Lines | |||||
| #include "kernel_montecarlo.h" | #include "kernel_montecarlo.h" | ||||
| #include "kernel_types.h" | #include "kernel_types.h" | ||||
| #include "kernel_globals.h" | #include "kernel_globals.h" | ||||
| #include "geom/geom_object.h" | #include "geom/geom_object.h" | ||||
| #include "closure/bsdf_diffuse.h" | #include "closure/bsdf_diffuse.h" | ||||
| #include "closure/bssrdf.h" | #include "closure/bssrdf.h" | ||||
| #include "closure/merge.h" | |||||
| #include "osl_bssrdf.h" | #include "osl_bssrdf.h" | ||||
| #include "osl_closures.h" | #include "osl_closures.h" | ||||
| #include "osl_globals.h" | #include "osl_globals.h" | ||||
| #include "osl_services.h" | #include "osl_services.h" | ||||
| #include "osl_shader.h" | #include "osl_shader.h" | ||||
| #include "util_foreach.h" | #include "util_foreach.h" | ||||
| ▲ Show 20 Lines • Show All 137 Lines • ▼ Show 20 Lines | #endif | ||||
| prim->setup(); | prim->setup(); | ||||
| switch(prim->category) { | switch(prim->category) { | ||||
| case CClosurePrimitive::BSDF: { | case CClosurePrimitive::BSDF: { | ||||
| CBSDFClosure *bsdf = (CBSDFClosure *)prim; | CBSDFClosure *bsdf = (CBSDFClosure *)prim; | ||||
| int scattering = bsdf->scattering(); | int scattering = bsdf->scattering(); | ||||
| if(bsdf->sc.type == CLOSURE_BSDF_TRANSPARENT_ID) { | |||||
| if(path_flag & PATH_RAY_EMISSION) { | |||||
| return; | |||||
| } | |||||
| } | |||||
| else if(path_flag & (PATH_RAY_SHADOW|PATH_RAY_EMISSION)) { | |||||
| return; | |||||
| } | |||||
| /* caustic options */ | /* caustic options */ | ||||
| if((scattering & LABEL_GLOSSY) && (path_flag & PATH_RAY_DIFFUSE)) { | if((scattering & LABEL_GLOSSY) && (path_flag & PATH_RAY_DIFFUSE)) { | ||||
| KernelGlobals *kg = sd->osl_globals; | KernelGlobals *kg = sd->osl_globals; | ||||
| if((!kernel_data.integrator.caustics_reflective && (scattering & LABEL_REFLECT)) || | if((!kernel_data.integrator.caustics_reflective && (scattering & LABEL_REFLECT)) || | ||||
| (!kernel_data.integrator.caustics_refractive && (scattering & LABEL_TRANSMIT))) | (!kernel_data.integrator.caustics_refractive && (scattering & LABEL_TRANSMIT))) | ||||
| { | { | ||||
| return; | return; | ||||
| Show All 9 Lines | #endif | ||||
| sc.N = bsdf->sc.N; | sc.N = bsdf->sc.N; | ||||
| sc.T = bsdf->sc.T; | sc.T = bsdf->sc.T; | ||||
| sc.data0 = bsdf->sc.data0; | sc.data0 = bsdf->sc.data0; | ||||
| sc.data1 = bsdf->sc.data1; | sc.data1 = bsdf->sc.data1; | ||||
| sc.data2 = bsdf->sc.data2; | sc.data2 = bsdf->sc.data2; | ||||
| sc.prim = bsdf->sc.prim; | sc.prim = bsdf->sc.prim; | ||||
| /* add */ | /* add */ | ||||
| if(sc.sample_weight > CLOSURE_WEIGHT_CUTOFF && sd->num_closure < MAX_CLOSURE) { | if(sc.sample_weight > CLOSURE_WEIGHT_CUTOFF && sd->num_closure < sd->max_closure) { | ||||
| sd->closure[sd->num_closure++] = sc; | sd->closure[sd->num_closure++] = sc; | ||||
| sd->flag |= bsdf->shaderdata_flag(); | sd->flag |= bsdf->shaderdata_flag(); | ||||
| shader_merge_last_closure_with_data(sd); | |||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| case CClosurePrimitive::Emissive: { | case CClosurePrimitive::Emissive: { | ||||
| if(path_flag & PATH_RAY_SHADOW) { | |||||
| 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_EMISSION_ID; | sc.type = CLOSURE_EMISSION_ID; | ||||
| sc.data0 = 0.0f; | sc.data0 = 0.0f; | ||||
| sc.data1 = 0.0f; | sc.data1 = 0.0f; | ||||
| sc.data2 = 0.0f; | sc.data2 = 0.0f; | ||||
| sc.prim = NULL; | sc.prim = NULL; | ||||
| /* flag */ | /* flag */ | ||||
| if(sd->num_closure < MAX_CLOSURE) { | if(sd->num_closure < sd->max_closure) { | ||||
| sd->closure[sd->num_closure++] = sc; | sd->closure[sd->num_closure++] = sc; | ||||
| shader_merge_last_closure_without_data(sd); | |||||
| sd->flag |= SD_EMISSION; | sd->flag |= SD_EMISSION; | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| case CClosurePrimitive::AmbientOcclusion: { | case CClosurePrimitive::AmbientOcclusion: { | ||||
| if(path_flag & (PATH_RAY_SHADOW|PATH_RAY_EMISSION)) { | |||||
| 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.data0 = 0.0f; | sc.data0 = 0.0f; | ||||
| sc.data1 = 0.0f; | sc.data1 = 0.0f; | ||||
| sc.data2 = 0.0f; | sc.data2 = 0.0f; | ||||
| sc.prim = NULL; | sc.prim = NULL; | ||||
| if(sd->num_closure < MAX_CLOSURE) { | if(sd->num_closure < sd->max_closure) { | ||||
| sd->closure[sd->num_closure++] = sc; | sd->closure[sd->num_closure++] = sc; | ||||
| shader_merge_last_closure_without_data(sd); | |||||
| sd->flag |= SD_AO; | sd->flag |= SD_AO; | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| case CClosurePrimitive::Holdout: { | case CClosurePrimitive::Holdout: { | ||||
| if(path_flag & (PATH_RAY_SHADOW|PATH_RAY_EMISSION)) { | |||||
| return; | |||||
| } | |||||
| sc.sample_weight = 0.0f; | sc.sample_weight = 0.0f; | ||||
| sc.type = CLOSURE_HOLDOUT_ID; | sc.type = CLOSURE_HOLDOUT_ID; | ||||
| sc.data0 = 0.0f; | sc.data0 = 0.0f; | ||||
| sc.data1 = 0.0f; | sc.data1 = 0.0f; | ||||
| sc.data2 = 0.0f; | sc.data2 = 0.0f; | ||||
| sc.prim = NULL; | sc.prim = NULL; | ||||
| if(sd->num_closure < MAX_CLOSURE) { | if(sd->num_closure < sd->max_closure) { | ||||
| sd->closure[sd->num_closure++] = sc; | sd->closure[sd->num_closure++] = sc; | ||||
| shader_merge_last_closure_without_data(sd); | |||||
| sd->flag |= SD_HOLDOUT; | sd->flag |= SD_HOLDOUT; | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| case CClosurePrimitive::BSSRDF: { | case CClosurePrimitive::BSSRDF: { | ||||
| if(path_flag & (PATH_RAY_SHADOW|PATH_RAY_EMISSION)) { | |||||
| return; | |||||
| } | |||||
| CBSSRDFClosure *bssrdf = (CBSSRDFClosure *)prim; | CBSSRDFClosure *bssrdf = (CBSSRDFClosure *)prim; | ||||
| float sample_weight = fabsf(average(weight)); | float sample_weight = fabsf(average(weight)); | ||||
| if(sample_weight > CLOSURE_WEIGHT_CUTOFF && sd->num_closure+2 < MAX_CLOSURE) { | if(sample_weight > CLOSURE_WEIGHT_CUTOFF && sd->num_closure+2 < sd->max_closure) { | ||||
| sc.sample_weight = sample_weight; | sc.sample_weight = sample_weight; | ||||
| sc.type = bssrdf->sc.type; | sc.type = bssrdf->sc.type; | ||||
| sc.N = bssrdf->sc.N; | sc.N = bssrdf->sc.N; | ||||
| sc.data1 = bssrdf->sc.data1; | sc.data1 = bssrdf->sc.data1; | ||||
| sc.T.x = bssrdf->sc.T.x; | sc.T.x = bssrdf->sc.T.x; | ||||
| sc.prim = NULL; | sc.prim = NULL; | ||||
| ▲ Show 20 Lines • Show All 124 Lines • ▼ Show 20 Lines | float3 OSLShader::eval_background(KernelGlobals *kg, ShaderData *sd, PathState *state, int path_flag, ShaderContext ctx) | ||||
| if(globals->Ci) | if(globals->Ci) | ||||
| return flatten_background_closure_tree(globals->Ci); | return flatten_background_closure_tree(globals->Ci); | ||||
| return make_float3(0.0f, 0.0f, 0.0f); | return make_float3(0.0f, 0.0f, 0.0f); | ||||
| } | } | ||||
| /* Volume */ | /* Volume */ | ||||
| static void flatten_volume_closure_tree(ShaderData *sd, | static void flatten_volume_closure_tree(ShaderData *sd, int path_flag, | ||||
| const OSL::ClosureColor *closure, float3 weight = make_float3(1.0f, 1.0f, 1.0f)) | const OSL::ClosureColor *closure, float3 weight = make_float3(1.0f, 1.0f, 1.0f)) | ||||
| { | { | ||||
| /* OSL gives us a closure tree, we flatten it into arrays per | /* OSL gives us a closure tree, we flatten it into arrays per | ||||
| * closure type, for evaluation, sampling, etc later on. */ | * closure type, for evaluation, sampling, etc later on. */ | ||||
| switch(closure->id) { | switch(closure->id) { | ||||
| case OSL::ClosureColor::MUL: { | case OSL::ClosureColor::MUL: { | ||||
| OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; | OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; | ||||
| flatten_volume_closure_tree(sd, mul->closure, TO_FLOAT3(mul->weight) * weight); | flatten_volume_closure_tree(sd, path_flag, mul->closure, TO_FLOAT3(mul->weight) * weight); | ||||
| break; | break; | ||||
| } | } | ||||
| case OSL::ClosureColor::ADD: { | case OSL::ClosureColor::ADD: { | ||||
| OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; | OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; | ||||
| flatten_volume_closure_tree(sd, add->closureA, weight); | flatten_volume_closure_tree(sd, path_flag, add->closureA, weight); | ||||
| flatten_volume_closure_tree(sd, add->closureB, weight); | flatten_volume_closure_tree(sd, path_flag, add->closureB, weight); | ||||
| break; | break; | ||||
| } | } | ||||
| default: { | default: { | ||||
| OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; | OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; | ||||
| CClosurePrimitive *prim = (CClosurePrimitive *)comp->data(); | CClosurePrimitive *prim = (CClosurePrimitive *)comp->data(); | ||||
| if(prim) { | if(prim) { | ||||
| ShaderClosure sc; | ShaderClosure sc; | ||||
| Show All 11 Lines | #endif | ||||
| /* 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 = volume->sc.type; | sc.type = volume->sc.type; | ||||
| sc.data0 = volume->sc.data0; | sc.data0 = volume->sc.data0; | ||||
| sc.data1 = volume->sc.data1; | sc.data1 = volume->sc.data1; | ||||
| if(path_flag & PATH_RAY_EMISSION) { | |||||
| return; | |||||
| } | |||||
| else if(path_flag & PATH_RAY_SHADOW) { | |||||
| // save closures space for shadow rays | |||||
| sc.type = CLOSURE_VOLUME_ABSORPTION_ID; | |||||
| } | |||||
| /* add */ | /* add */ | ||||
| if((sc.sample_weight > CLOSURE_WEIGHT_CUTOFF) && | if((sc.sample_weight > CLOSURE_WEIGHT_CUTOFF) && | ||||
| (sd->num_closure < MAX_CLOSURE)) | (sd->num_closure < sd->max_closure)) | ||||
| { | { | ||||
| sd->closure[sd->num_closure++] = sc; | sd->closure[sd->num_closure++] = sc; | ||||
| sd->flag |= volume->shaderdata_flag(); | sd->flag |= volume->shaderdata_flag(); | ||||
| shader_merge_last_closure_with_data(sd); | |||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| case CClosurePrimitive::Emissive: { | case CClosurePrimitive::Emissive: { | ||||
| if(path_flag & PATH_RAY_SHADOW) { | |||||
| 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_EMISSION_ID; | sc.type = CLOSURE_EMISSION_ID; | ||||
| sc.data0 = 0.0f; | sc.data0 = 0.0f; | ||||
| sc.data1 = 0.0f; | sc.data1 = 0.0f; | ||||
| sc.prim = NULL; | sc.prim = NULL; | ||||
| /* flag */ | /* flag */ | ||||
| if(sd->num_closure < MAX_CLOSURE) { | if(sd->num_closure < sd->max_closure) { | ||||
| sd->closure[sd->num_closure++] = sc; | sd->closure[sd->num_closure++] = sc; | ||||
| sd->flag |= SD_EMISSION; | sd->flag |= SD_EMISSION; | ||||
| shader_merge_last_closure_without_data(sd); | |||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| case CClosurePrimitive::Holdout: | case CClosurePrimitive::Holdout: | ||||
| break; /* not implemented */ | break; /* not implemented */ | ||||
| case CClosurePrimitive::Background: | case CClosurePrimitive::Background: | ||||
| case CClosurePrimitive::BSDF: | case CClosurePrimitive::BSDF: | ||||
| case CClosurePrimitive::BSSRDF: | case CClosurePrimitive::BSSRDF: | ||||
| Show All 18 Lines | void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, PathState *state, int path_flag, ShaderContext 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(octx, *(kg->osl->volume_state[shader]), *globals); | ss->execute(octx, *(kg->osl->volume_state[shader]), *globals); | ||||
| } | } | ||||
| /* flatten closure tree */ | /* flatten closure tree */ | ||||
| if(globals->Ci) | if(globals->Ci) | ||||
| flatten_volume_closure_tree(sd, globals->Ci); | flatten_volume_closure_tree(sd, path_flag, globals->Ci); | ||||
| } | } | ||||
| /* Displacement */ | /* Displacement */ | ||||
| void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd, ShaderContext ctx) | void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd, ShaderContext ctx) | ||||
| { | { | ||||
| /* setup shader globals from shader data */ | /* setup shader globals from shader data */ | ||||
| OSLThreadData *tdata = kg->osl_tdata; | OSLThreadData *tdata = kg->osl_tdata; | ||||
| ▲ Show 20 Lines • Show All 83 Lines • Show Last 20 Lines | |||||