static void flatten_surface_closure_tree(ShaderData *sd, int path_flag, 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 * closure type, for evaluation, sampling, etc later on. */ switch(closure->id) { case OSL::ClosureColor::MUL: { OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; flatten_surface_closure_tree(sd, path_flag, mul->closure, TO_FLOAT3(mul->weight) * weight); break; } case OSL::ClosureColor::ADD: { OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; flatten_surface_closure_tree(sd, path_flag, add->closureA, weight); flatten_surface_closure_tree(sd, path_flag, add->closureB, weight); break; } default: { OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; CClosurePrimitive *prim = (CClosurePrimitive *)comp->data(); if(prim) { #ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS weight = weight*TO_FLOAT3(comp->w); #endif prim->setup(sd, path_flag, weight); } break; } } }
void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag) { /* gather pointers */ OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl*)kg->osl.ss; OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data); OSL::ShaderGlobals *globals = &tdata->globals; OSL::pvt::ShadingContext *ctx = ssi->get_context(tdata->thread_info); /* setup shader globals from shader data */ sd->osl_ctx = ctx; shaderdata_to_shaderglobals(kg, sd, path_flag, globals); /* execute shader for this point */ int shader = sd->shader & SHADER_MASK; if(kg->osl.surface_state[shader]) ctx->execute(OSL::pvt::ShadUseSurface, *(kg->osl.surface_state[shader]), *globals); /* flatten closure tree */ sd->num_closure = 0; sd->randb_closure = randb; if(globals->Ci) { bool no_glossy = (path_flag & PATH_RAY_DIFFUSE) && kernel_data.integrator.no_caustics; flatten_surface_closure_tree(sd, no_glossy, globals->Ci); } }
void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx) { /* setup shader globals from shader data */ OSLThreadData *tdata = kg->osl_tdata; shaderdata_to_shaderglobals(kg, sd, path_flag, tdata); /* execute shader for this point */ OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss; OSL::ShaderGlobals *globals = &tdata->globals; OSL::ShadingContext *octx = tdata->context[(int)ctx]; int shader = sd->shader & SHADER_MASK; if (kg->osl->surface_state[shader]) ss->execute(*octx, *(kg->osl->surface_state[shader]), *globals); /* flatten closure tree */ if (globals->Ci) flatten_surface_closure_tree(sd, path_flag, globals->Ci); }
void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag, ShaderContext ctx) { /* setup shader globals from shader data */ OSLThreadData *tdata = kg->osl_tdata; shaderdata_to_shaderglobals(kg, sd, path_flag, tdata); /* execute shader for this point */ OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss; OSL::ShaderGlobals *globals = &tdata->globals; OSL::ShadingContext *octx = tdata->context[(int)ctx]; int shader = sd->shader & SHADER_MASK; if (kg->osl->surface_state[shader]) ss->execute(*octx, *(kg->osl->surface_state[shader]), *globals); /* flatten closure tree */ sd->num_closure = 0; sd->randb_closure = randb; if (globals->Ci) { bool no_glossy = (path_flag & PATH_RAY_DIFFUSE) && kernel_data.integrator.no_caustics; flatten_surface_closure_tree(sd, no_glossy, globals->Ci); } }
static void flatten_surface_closure_tree(ShaderData *sd, int path_flag, 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 * closure type, for evaluation, sampling, etc later on. */ if (closure->type == OSL::ClosureColor::COMPONENT) { OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; CClosurePrimitive *prim = (CClosurePrimitive *)comp->data(); if (prim) { ShaderClosure sc; #ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS weight = weight*TO_FLOAT3(comp->w); #endif sc.weight = weight; prim->setup(); switch (prim->category) { case CClosurePrimitive::BSDF: { CBSDFClosure *bsdf = (CBSDFClosure *)prim; int scattering = bsdf->scattering(); /* no caustics option */ if(scattering == LABEL_GLOSSY && (path_flag & PATH_RAY_DIFFUSE)) { KernelGlobals *kg = sd->osl_globals; if(kernel_data.integrator.no_caustics) return; } /* sample weight */ float sample_weight = fabsf(average(weight)); sc.sample_weight = sample_weight; 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; #ifdef __HAIR__ sc.offset = bsdf->sc.offset; #endif /* add */ if(sc.sample_weight > 1e-5f && sd->num_closure < MAX_CLOSURE) { sd->closure[sd->num_closure++] = sc; sd->flag |= bsdf->shaderdata_flag(); } break; } case CClosurePrimitive::Emissive: { /* sample weight */ float sample_weight = fabsf(average(weight)); sc.sample_weight = sample_weight; sc.type = CLOSURE_EMISSION_ID; sc.data0 = 0.0f; sc.data1 = 0.0f; sc.prim = NULL; /* flag */ if(sd->num_closure < MAX_CLOSURE) { sd->closure[sd->num_closure++] = sc; sd->flag |= SD_EMISSION; } break; } case CClosurePrimitive::AmbientOcclusion: { /* sample weight */ float sample_weight = fabsf(average(weight)); sc.sample_weight = sample_weight; sc.type = CLOSURE_AMBIENT_OCCLUSION_ID; sc.data0 = 0.0f; sc.data1 = 0.0f; sc.prim = NULL; if(sd->num_closure < MAX_CLOSURE) { sd->closure[sd->num_closure++] = sc; sd->flag |= SD_AO; } break; } case CClosurePrimitive::Holdout: { sc.sample_weight = 0.0f; sc.type = CLOSURE_HOLDOUT_ID; sc.data0 = 0.0f; sc.data1 = 0.0f; sc.prim = NULL; if(sd->num_closure < MAX_CLOSURE) { sd->closure[sd->num_closure++] = sc; sd->flag |= SD_HOLDOUT; } break; } case CClosurePrimitive::BSSRDF: { CBSSRDFClosure *bssrdf = (CBSSRDFClosure *)prim; float sample_weight = fabsf(average(weight)); if(sample_weight > 1e-5f && sd->num_closure+2 < MAX_CLOSURE) { sc.sample_weight = sample_weight; sc.type = bssrdf->sc.type; sc.N = bssrdf->sc.N; sc.data1 = bssrdf->sc.data1; sc.T.x = bssrdf->sc.T.x; sc.prim = NULL; /* disable in case of diffuse ancestor, can't see it well then and * adds considerably noise due to probabilities of continuing path * getting lower and lower */ if(path_flag & PATH_RAY_DIFFUSE_ANCESTOR) bssrdf->radius = make_float3(0.0f, 0.0f, 0.0f); /* create one closure for each color channel */ if(fabsf(weight.x) > 0.0f) { sc.weight = make_float3(weight.x, 0.0f, 0.0f); sc.data0 = bssrdf->radius.x; sd->flag |= bssrdf_setup(&sc, sc.type); sd->closure[sd->num_closure++] = sc; } if(fabsf(weight.y) > 0.0f) { sc.weight = make_float3(0.0f, weight.y, 0.0f); sc.data0 = bssrdf->radius.y; sd->flag |= bssrdf_setup(&sc, sc.type); sd->closure[sd->num_closure++] = sc; } if(fabsf(weight.z) > 0.0f) { sc.weight = make_float3(0.0f, 0.0f, weight.z); sc.data0 = bssrdf->radius.z; sd->flag |= bssrdf_setup(&sc, sc.type); sd->closure[sd->num_closure++] = sc; } } break; } case CClosurePrimitive::Background: case CClosurePrimitive::Volume: break; /* not relevant */ } } } else if (closure->type == OSL::ClosureColor::MUL) { OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; flatten_surface_closure_tree(sd, path_flag, mul->closure, TO_FLOAT3(mul->weight) * weight); } else if (closure->type == OSL::ClosureColor::ADD) { OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; flatten_surface_closure_tree(sd, path_flag, add->closureA, weight); flatten_surface_closure_tree(sd, path_flag, add->closureB, weight); } }
static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy, 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 * closure type, for evaluation, sampling, etc later on. */ if (closure->type == OSL::ClosureColor::COMPONENT) { OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; OSL::ClosurePrimitive *prim = (OSL::ClosurePrimitive *)comp->data(); if (prim) { ShaderClosure sc; sc.weight = weight; switch (prim->category()) { case OSL::ClosurePrimitive::BSDF: { CBSDFClosure *bsdf = (CBSDFClosure *)prim; int scattering = bsdf->scattering(); /* no caustics option */ if (no_glossy && scattering == LABEL_GLOSSY) return; /* sample weight */ float sample_weight = fabsf(average(weight)); sc.sample_weight = sample_weight; sc.type = bsdf->sc.type; sc.N = bsdf->sc.N; sc.T = bsdf->sc.T; sc.data0 = bsdf->sc.data0; sc.data1 = bsdf->sc.data1; sc.prim = bsdf->sc.prim; /* add */ if(sc.sample_weight > 1e-5f && sd->num_closure < MAX_CLOSURE) { sd->closure[sd->num_closure++] = sc; sd->flag |= bsdf->shaderdata_flag(); } break; } case OSL::ClosurePrimitive::Emissive: { /* sample weight */ float sample_weight = fabsf(average(weight)); sc.sample_weight = sample_weight; sc.type = CLOSURE_EMISSION_ID; sc.prim = NULL; /* flag */ if(sd->num_closure < MAX_CLOSURE) { sd->closure[sd->num_closure++] = sc; sd->flag |= SD_EMISSION; } break; } case AmbientOcclusion: { /* sample weight */ float sample_weight = fabsf(average(weight)); sc.sample_weight = sample_weight; sc.type = CLOSURE_AMBIENT_OCCLUSION_ID; sc.prim = NULL; if(sd->num_closure < MAX_CLOSURE) { sd->closure[sd->num_closure++] = sc; sd->flag |= SD_AO; } break; } case OSL::ClosurePrimitive::Holdout: { sc.sample_weight = 0.0f; sc.type = CLOSURE_HOLDOUT_ID; sc.prim = NULL; if(sd->num_closure < MAX_CLOSURE) { sd->closure[sd->num_closure++] = sc; sd->flag |= SD_HOLDOUT; } break; } case OSL::ClosurePrimitive::BSSRDF: { CBSSRDFClosure *bssrdf = (CBSSRDFClosure *)prim; float sample_weight = fabsf(average(weight)); if(sample_weight > 1e-5f && sd->num_closure+2 < MAX_CLOSURE) { sc.sample_weight = sample_weight; sc.type = bssrdf->sc.type; sc.N = bssrdf->sc.N; sc.data1 = bssrdf->sc.data1; sc.prim = NULL; /* create one closure for each color channel */ if(fabsf(weight.x) > 0.0f) { sc.weight = make_float3(weight.x, 0.0f, 0.0f); sc.data0 = bssrdf->radius.x; sd->closure[sd->num_closure++] = sc; sd->flag |= bssrdf->shaderdata_flag(); } if(fabsf(weight.y) > 0.0f) { sc.weight = make_float3(0.0f, weight.y, 0.0f); sc.data0 = bssrdf->radius.y; sd->closure[sd->num_closure++] = sc; sd->flag |= bssrdf->shaderdata_flag(); } if(fabsf(weight.z) > 0.0f) { sc.weight = make_float3(0.0f, 0.0f, weight.z); sc.data0 = bssrdf->radius.z; sd->closure[sd->num_closure++] = sc; sd->flag |= bssrdf->shaderdata_flag(); } } break; } case OSL::ClosurePrimitive::Debug: break; /* not implemented */ case OSL::ClosurePrimitive::Background: case OSL::ClosurePrimitive::Volume: break; /* not relevant */ } } } else if (closure->type == OSL::ClosureColor::MUL) { OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; flatten_surface_closure_tree(sd, no_glossy, mul->closure, TO_FLOAT3(mul->weight) * weight); } else if (closure->type == OSL::ClosureColor::ADD) { OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; flatten_surface_closure_tree(sd, no_glossy, add->closureA, weight); flatten_surface_closure_tree(sd, no_glossy, add->closureB, weight); } }
static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy, const OSL::ClosureColor *closure, float3 weight = make_float3(1.0f, 1.0f, 1.0f)) { /* OSL gives use a closure tree, we flatten it into arrays per * closure type, for evaluation, sampling, etc later on. */ if(closure->type == OSL::ClosureColor::COMPONENT) { OSL::ClosureComponent *comp = (OSL::ClosureComponent*)closure; OSL::ClosurePrimitive *prim = (OSL::ClosurePrimitive*)comp->data(); if(prim) { ShaderClosure sc; sc.prim = prim; sc.weight = weight; switch(prim->category()) { case ClosurePrimitive::BSDF: { if(sd->num_closure == MAX_CLOSURE) return; OSL::BSDFClosure *bsdf = (OSL::BSDFClosure*)prim; ustring scattering = bsdf->scattering(); /* no caustics option */ if(no_glossy && scattering == OSL::Labels::GLOSSY) return; /* sample weight */ float albedo = bsdf->albedo(TO_VEC3(sd->I)); float sample_weight = fabsf(average(weight))*albedo; float sample_sum = sd->osl_closure.bsdf_sample_sum + sample_weight; sc.sample_weight = sample_weight; sc.type = CLOSURE_BSDF_ID; sd->osl_closure.bsdf_sample_sum = sample_sum; /* scattering flags */ if(scattering == OSL::Labels::DIFFUSE) sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL; else if(scattering == OSL::Labels::GLOSSY) sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; else sd->flag |= SD_BSDF; /* add */ sd->closure[sd->num_closure++] = sc; break; } case ClosurePrimitive::Emissive: { if(sd->num_closure == MAX_CLOSURE) return; /* sample weight */ float sample_weight = fabsf(average(weight)); float sample_sum = sd->osl_closure.emissive_sample_sum + sample_weight; sc.sample_weight = sample_weight; sc.type = CLOSURE_EMISSION_ID; sd->osl_closure.emissive_sample_sum = sample_sum; /* flag */ sd->flag |= SD_EMISSION; sd->closure[sd->num_closure++] = sc; break; } case ClosurePrimitive::Holdout: if(sd->num_closure == MAX_CLOSURE) return; sc.sample_weight = 0.0f; sc.type = CLOSURE_HOLDOUT_ID; sd->flag |= SD_HOLDOUT; sd->closure[sd->num_closure++] = sc; break; case ClosurePrimitive::BSSRDF: case ClosurePrimitive::Debug: break; /* not implemented */ case ClosurePrimitive::Background: case ClosurePrimitive::Volume: break; /* not relevant */ } } } else if(closure->type == OSL::ClosureColor::MUL) { OSL::ClosureMul *mul = (OSL::ClosureMul*)closure; flatten_surface_closure_tree(sd, no_glossy, mul->closure, TO_FLOAT3(mul->weight) * weight); } else if(closure->type == OSL::ClosureColor::ADD) { OSL::ClosureAdd *add = (OSL::ClosureAdd*)closure; flatten_surface_closure_tree(sd, no_glossy, add->closureA, weight); flatten_surface_closure_tree(sd, no_glossy, add->closureB, weight); } }
static void flatten_surface_closure_tree(ShaderData *sd, int path_flag, 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 * closure type, for evaluation, sampling, etc later on. */ #if OSL_LIBRARY_VERSION_CODE < 10700 switch(closure->type) { #else switch(closure->id) { #endif case OSL::ClosureColor::MUL: { OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; flatten_surface_closure_tree(sd, path_flag, mul->closure, TO_FLOAT3(mul->weight) * weight); break; } case OSL::ClosureColor::ADD: { OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; flatten_surface_closure_tree(sd, path_flag, add->closureA, weight); flatten_surface_closure_tree(sd, path_flag, add->closureB, weight); break; } default: { OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; CClosurePrimitive *prim = (CClosurePrimitive *)comp->data(); if(prim) { ShaderClosure sc; #ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS weight = weight*TO_FLOAT3(comp->w); #endif sc.weight = weight; prim->setup(); switch(prim->category) { case CClosurePrimitive::BSDF: { CBSDFClosure *bsdf = (CBSDFClosure *)prim; int scattering = bsdf->scattering(); /* caustic options */ if((scattering & LABEL_GLOSSY) && (path_flag & PATH_RAY_DIFFUSE)) { KernelGlobals *kg = sd->osl_globals; if((!kernel_data.integrator.caustics_reflective && (scattering & LABEL_REFLECT)) || (!kernel_data.integrator.caustics_refractive && (scattering & LABEL_TRANSMIT))) { return; } } /* sample weight */ float sample_weight = fabsf(average(weight)); sc.sample_weight = sample_weight; 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.data2 = bsdf->sc.data2; sc.prim = bsdf->sc.prim; /* add */ if(sc.sample_weight > CLOSURE_WEIGHT_CUTOFF && sd->num_closure < MAX_CLOSURE) { sd->closure[sd->num_closure++] = sc; sd->flag |= bsdf->shaderdata_flag(); } break; } case CClosurePrimitive::Emissive: { /* sample weight */ float sample_weight = fabsf(average(weight)); sc.sample_weight = sample_weight; sc.type = CLOSURE_EMISSION_ID; sc.data0 = 0.0f; sc.data1 = 0.0f; sc.data2 = 0.0f; sc.prim = NULL; /* flag */ if(sd->num_closure < MAX_CLOSURE) { sd->closure[sd->num_closure++] = sc; sd->flag |= SD_EMISSION; } break; } case CClosurePrimitive::AmbientOcclusion: { /* sample weight */ float sample_weight = fabsf(average(weight)); sc.sample_weight = sample_weight; sc.type = CLOSURE_AMBIENT_OCCLUSION_ID; sc.data0 = 0.0f; sc.data1 = 0.0f; sc.data2 = 0.0f; sc.prim = NULL; if(sd->num_closure < MAX_CLOSURE) { sd->closure[sd->num_closure++] = sc; sd->flag |= SD_AO; } break; } case CClosurePrimitive::Holdout: { sc.sample_weight = 0.0f; sc.type = CLOSURE_HOLDOUT_ID; sc.data0 = 0.0f; sc.data1 = 0.0f; sc.data2 = 0.0f; sc.prim = NULL; if(sd->num_closure < MAX_CLOSURE) { sd->closure[sd->num_closure++] = sc; sd->flag |= SD_HOLDOUT; } break; } case CClosurePrimitive::BSSRDF: { CBSSRDFClosure *bssrdf = (CBSSRDFClosure *)prim; float sample_weight = fabsf(average(weight)); if(sample_weight > CLOSURE_WEIGHT_CUTOFF && sd->num_closure+2 < MAX_CLOSURE) { sc.sample_weight = sample_weight; sc.type = bssrdf->sc.type; sc.N = bssrdf->sc.N; sc.data1 = bssrdf->sc.data1; sc.T.x = bssrdf->sc.T.x; sc.prim = NULL; /* disable in case of diffuse ancestor, can't see it well then and * adds considerably noise due to probabilities of continuing path * getting lower and lower */ if(path_flag & PATH_RAY_DIFFUSE_ANCESTOR) bssrdf->radius = make_float3(0.0f, 0.0f, 0.0f); /* create one closure for each color channel */ if(fabsf(weight.x) > 0.0f) { sc.weight = make_float3(weight.x, 0.0f, 0.0f); sc.data0 = bssrdf->radius.x; sc.data1 = 0.0f; sd->flag |= bssrdf_setup(&sc, sc.type); sd->closure[sd->num_closure++] = sc; } if(fabsf(weight.y) > 0.0f) { sc.weight = make_float3(0.0f, weight.y, 0.0f); sc.data0 = bssrdf->radius.y; sc.data1 = 0.0f; sd->flag |= bssrdf_setup(&sc, sc.type); sd->closure[sd->num_closure++] = sc; } if(fabsf(weight.z) > 0.0f) { sc.weight = make_float3(0.0f, 0.0f, weight.z); sc.data0 = bssrdf->radius.z; sc.data1 = 0.0f; sd->flag |= bssrdf_setup(&sc, sc.type); sd->closure[sd->num_closure++] = sc; } } break; } case CClosurePrimitive::Background: case CClosurePrimitive::Volume: break; /* not relevant */ } } break; } } } void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, PathState *state, int path_flag, ShaderContext ctx) { /* setup shader globals from shader data */ OSLThreadData *tdata = kg->osl_tdata; shaderdata_to_shaderglobals(kg, sd, state, path_flag, tdata); /* execute shader for this point */ OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss; OSL::ShaderGlobals *globals = &tdata->globals; OSL::ShadingContext *octx = tdata->context[(int)ctx]; int shader = sd->shader & SHADER_MASK; if(kg->osl->surface_state[shader]) { #if OSL_LIBRARY_VERSION_CODE < 10600 ss->execute(*octx, *(kg->osl->surface_state[shader]), *globals); #else ss->execute(octx, *(kg->osl->surface_state[shader]), *globals); #endif } /* flatten closure tree */ if(globals->Ci) flatten_surface_closure_tree(sd, path_flag, globals->Ci); }
void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, PathState *state, int path_flag) { /* setup shader globals from shader data */ OSLThreadData *tdata = kg->osl_tdata; shaderdata_to_shaderglobals(kg, sd, state, path_flag, tdata); /* execute shader for this point */ OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss; OSL::ShaderGlobals *globals = &tdata->globals; OSL::ShadingContext *octx = tdata->context; int shader = sd->shader & SHADER_MASK; /* automatic bump shader */ if(kg->osl->bump_state[shader]) { /* save state */ float3 P = sd->P; float3 dPdx = sd->dP.dx; float3 dPdy = sd->dP.dy; /* set state as if undisplaced */ if(sd->flag & SD_HAS_DISPLACEMENT) { float data[9]; bool found = kg->osl->services->get_attribute(sd, true, OSLRenderServices::u_empty, TypeDesc::TypeVector, OSLRenderServices::u_geom_undisplaced, data); (void)found; assert(found); memcpy(&sd->P, data, sizeof(float)*3); memcpy(&sd->dP.dx, data+3, sizeof(float)*3); memcpy(&sd->dP.dy, data+6, sizeof(float)*3); object_position_transform(kg, sd, &sd->P); object_dir_transform(kg, sd, &sd->dP.dx); object_dir_transform(kg, sd, &sd->dP.dy); globals->P = TO_VEC3(sd->P); globals->dPdx = TO_VEC3(sd->dP.dx); globals->dPdy = TO_VEC3(sd->dP.dy); } /* execute bump shader */ ss->execute(octx, *(kg->osl->bump_state[shader]), *globals); /* reset state */ sd->P = P; sd->dP.dx = dPdx; sd->dP.dy = dPdy; globals->P = TO_VEC3(P); globals->dPdx = TO_VEC3(dPdx); globals->dPdy = TO_VEC3(dPdy); } /* surface shader */ if(kg->osl->surface_state[shader]) { ss->execute(octx, *(kg->osl->surface_state[shader]), *globals); } /* flatten closure tree */ if(globals->Ci) flatten_surface_closure_tree(sd, path_flag, globals->Ci); }