Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/render/osl.cpp
| Show First 20 Lines • Show All 94 Lines • ▼ Show 20 Lines | void OSLShaderManager::device_update(Device *device, | ||||
| DeviceScene *dscene, | DeviceScene *dscene, | ||||
| Scene *scene, | Scene *scene, | ||||
| Progress &progress) | Progress &progress) | ||||
| { | { | ||||
| if (!need_update) | if (!need_update) | ||||
| return; | return; | ||||
| scoped_callback_timer timer([scene](double time) { | scoped_callback_timer timer([scene](double time) { | ||||
| if (scene->update_stats) { | if (scene->get_update_stats()) { | ||||
| scene->update_stats->osl.times.add_entry({"device_update", time}); | scene->get_update_stats()->osl.times.add_entry({"device_update", time}); | ||||
| } | } | ||||
| }); | }); | ||||
| VLOG(1) << "Total " << scene->shaders.size() << " shaders."; | VLOG(1) << "Total " << scene->get_shaders().size() << " shaders."; | ||||
| device_free(device, dscene, scene); | device_free(device, dscene, scene); | ||||
| /* set texture system */ | /* set texture system */ | ||||
| scene->image_manager->set_osl_texture_system((void *)ts); | scene->get_image_manager()->set_osl_texture_system((void *)ts); | ||||
| /* create shaders */ | /* create shaders */ | ||||
| OSLGlobals *og = (OSLGlobals *)device->osl_memory(); | OSLGlobals *og = (OSLGlobals *)device->osl_memory(); | ||||
| Shader *background_shader = scene->background->get_shader(scene); | Shader *background_shader = scene->get_background()->get_shader(scene); | ||||
| foreach (Shader *shader, scene->shaders) { | foreach (Shader *shader, scene->get_shaders()) { | ||||
| assert(shader->graph); | assert(shader->get_graph()); | ||||
| if (progress.get_cancel()) | if (progress.get_cancel()) | ||||
| return; | return; | ||||
| /* we can only compile one shader at the time as the OSL ShadingSytem | /* we can only compile one shader at the time as the OSL ShadingSytem | ||||
| * has a single state, but we put the lock here so different renders can | * has a single state, but we put the lock here so different renders can | ||||
| * compile shaders alternating */ | * compile shaders alternating */ | ||||
| thread_scoped_lock lock(ss_mutex); | thread_scoped_lock lock(ss_mutex); | ||||
| OSLCompiler compiler(this, services, ss, scene); | OSLCompiler compiler(this, services, ss, scene); | ||||
| compiler.background = (shader == background_shader); | compiler.background = (shader == background_shader); | ||||
| compiler.compile(og, shader); | compiler.compile(og, shader); | ||||
| if (shader->get_use_mis() && shader->has_surface_emission) | if (shader->get_use_mis() && shader->get_has_surface_emission()) | ||||
| scene->light_manager->need_update = true; | scene->get_light_manager()->need_update = true; | ||||
| } | } | ||||
| /* setup shader engine */ | /* setup shader engine */ | ||||
| og->ss = ss; | og->ss = ss; | ||||
| og->ts = ts; | og->ts = ts; | ||||
| og->services = services; | og->services = services; | ||||
| int background_id = scene->shader_manager->get_shader_id(background_shader); | int background_id = scene->get_shader_manager()->get_shader_id(background_shader); | ||||
| og->background_state = og->surface_state[background_id & SHADER_MASK]; | og->background_state = og->surface_state[background_id & SHADER_MASK]; | ||||
| og->use = true; | og->use = true; | ||||
| foreach (Shader *shader, scene->shaders) | foreach (Shader *shader, scene->get_shaders()) | ||||
| shader->clear_modified(); | shader->clear_modified(); | ||||
| need_update = false; | need_update = false; | ||||
| /* add special builtin texture types */ | /* add special builtin texture types */ | ||||
| services->textures.insert(ustring("@ao"), new OSLTextureHandle(OSLTextureHandle::AO)); | services->textures.insert(ustring("@ao"), new OSLTextureHandle(OSLTextureHandle::AO)); | ||||
| services->textures.insert(ustring("@bevel"), new OSLTextureHandle(OSLTextureHandle::BEVEL)); | services->textures.insert(ustring("@bevel"), new OSLTextureHandle(OSLTextureHandle::BEVEL)); | ||||
| ▲ Show 20 Lines • Show All 403 Lines • ▼ Show 20 Lines | for (int i = 0; i < info->query.nparams(); i++) { | ||||
| } | } | ||||
| else { | else { | ||||
| node->add_input(param->name, socket_type); | node->add_input(param->name, socket_type); | ||||
| } | } | ||||
| } | } | ||||
| /* set bytcode hash or filepath */ | /* set bytcode hash or filepath */ | ||||
| if (!bytecode_hash.empty()) { | if (!bytecode_hash.empty()) { | ||||
| node->bytecode_hash = bytecode_hash; | node->set_bytecode_hash(bytecode_hash); | ||||
| } | } | ||||
| else { | else { | ||||
| node->filepath = filepath; | node->set_filepath(filepath); | ||||
| } | } | ||||
| /* Generate inputs and outputs */ | /* Generate inputs and outputs */ | ||||
| node->create_inputs_outputs(node->type); | node->create_inputs_outputs(node->get_type()); | ||||
| return node; | return node; | ||||
| } | } | ||||
| /* Graph Compiler */ | /* Graph Compiler */ | ||||
| OSLCompiler::OSLCompiler(OSLShaderManager *manager, | OSLCompiler::OSLCompiler(OSLShaderManager *manager, | ||||
| OSLRenderServices *services, | OSLRenderServices *services, | ||||
| OSL::ShadingSystem *ss, | OSL::ShadingSystem *ss, | ||||
| Scene *scene) | Scene *scene) | ||||
| : scene(scene), manager(manager), services(services), ss(ss) | : scene(scene), manager(manager), services(services), ss(ss) | ||||
| { | { | ||||
| current_type = SHADER_TYPE_SURFACE; | current_type = SHADER_TYPE_SURFACE; | ||||
| current_shader = NULL; | current_shader = NULL; | ||||
| background = false; | background = false; | ||||
| } | } | ||||
| string OSLCompiler::id(ShaderNode *node) | string OSLCompiler::id(ShaderNode *node) | ||||
| { | { | ||||
| /* assign layer unique name based on pointer address + bump mode */ | /* assign layer unique name based on pointer address + bump mode */ | ||||
| stringstream stream; | stringstream stream; | ||||
| stream << "node_" << node->type->name << "_" << node; | stream << "node_" << node->get_type()->get_name() << "_" << node; | ||||
| return stream.str(); | return stream.str(); | ||||
| } | } | ||||
| string OSLCompiler::compatible_name(ShaderNode *node, ShaderInput *input) | string OSLCompiler::compatible_name(ShaderNode *node, ShaderInput *input) | ||||
| { | { | ||||
| string sname(input->name().string()); | string sname(input->name().string()); | ||||
| size_t i; | size_t i; | ||||
| /* strip whitespace */ | /* strip whitespace */ | ||||
| while ((i = sname.find(" ")) != string::npos) | while ((i = sname.find(" ")) != string::npos) | ||||
| sname.replace(i, 1, ""); | sname.replace(i, 1, ""); | ||||
| /* if output exists with the same name, add "In" suffix */ | /* if output exists with the same name, add "In" suffix */ | ||||
| foreach (ShaderOutput *output, node->outputs) { | foreach (ShaderOutput *output, node->get_outputs()) { | ||||
| if (input->name() == output->name()) { | if (input->name() == output->name()) { | ||||
| sname += "In"; | sname += "In"; | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| return sname; | return sname; | ||||
| } | } | ||||
| string OSLCompiler::compatible_name(ShaderNode *node, ShaderOutput *output) | string OSLCompiler::compatible_name(ShaderNode *node, ShaderOutput *output) | ||||
| { | { | ||||
| string sname(output->name().string()); | string sname(output->name().string()); | ||||
| size_t i; | size_t i; | ||||
| /* strip whitespace */ | /* strip whitespace */ | ||||
| while ((i = sname.find(" ")) != string::npos) | while ((i = sname.find(" ")) != string::npos) | ||||
| sname.replace(i, 1, ""); | sname.replace(i, 1, ""); | ||||
| /* if input exists with the same name, add "Out" suffix */ | /* if input exists with the same name, add "Out" suffix */ | ||||
| foreach (ShaderInput *input, node->inputs) { | foreach (ShaderInput *input, node->get_inputs()) { | ||||
| if (input->name() == output->name()) { | if (input->name() == output->name()) { | ||||
| sname += "Out"; | sname += "Out"; | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| return sname; | return sname; | ||||
| } | } | ||||
| bool OSLCompiler::node_skip_input(ShaderNode *node, ShaderInput *input) | bool OSLCompiler::node_skip_input(ShaderNode *node, ShaderInput *input) | ||||
| { | { | ||||
| /* exception for output node, only one input is actually used | /* exception for output node, only one input is actually used | ||||
| * depending on the current shader type */ | * depending on the current shader type */ | ||||
| if (input->flags() & SocketType::SVM_INTERNAL) | if (input->flags() & SocketType::SVM_INTERNAL) | ||||
| return true; | return true; | ||||
| if (node->special_type == SHADER_SPECIAL_TYPE_OUTPUT) { | if (node->get_special_type() == SHADER_SPECIAL_TYPE_OUTPUT) { | ||||
| if (input->name() == "Surface" && current_type != SHADER_TYPE_SURFACE) | if (input->name() == "Surface" && current_type != SHADER_TYPE_SURFACE) | ||||
| return true; | return true; | ||||
| if (input->name() == "Volume" && current_type != SHADER_TYPE_VOLUME) | if (input->name() == "Volume" && current_type != SHADER_TYPE_VOLUME) | ||||
| return true; | return true; | ||||
| if (input->name() == "Displacement" && current_type != SHADER_TYPE_DISPLACEMENT) | if (input->name() == "Displacement" && current_type != SHADER_TYPE_DISPLACEMENT) | ||||
| return true; | return true; | ||||
| if (input->name() == "Normal" && current_type != SHADER_TYPE_BUMP) | if (input->name() == "Normal" && current_type != SHADER_TYPE_BUMP) | ||||
| return true; | return true; | ||||
| } | } | ||||
| else if (node->special_type == SHADER_SPECIAL_TYPE_BUMP) { | else if (node->get_special_type() == SHADER_SPECIAL_TYPE_BUMP) { | ||||
| if (input->name() == "Height") | if (input->name() == "Height") | ||||
| return true; | return true; | ||||
| } | } | ||||
| else if (current_type == SHADER_TYPE_DISPLACEMENT && input->link && | else if (current_type == SHADER_TYPE_DISPLACEMENT && input->get_link() && | ||||
| input->link->parent->special_type == SHADER_SPECIAL_TYPE_BUMP) | input->get_link()->get_parent()->get_special_type() == SHADER_SPECIAL_TYPE_BUMP) | ||||
| return true; | return true; | ||||
| return false; | return false; | ||||
| } | } | ||||
| void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath) | void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath) | ||||
| { | { | ||||
| /* load filepath */ | /* load filepath */ | ||||
| if (isfilepath) { | if (isfilepath) { | ||||
| name = manager->shader_load_filepath(name); | name = manager->shader_load_filepath(name); | ||||
| if (name == NULL) | if (name == NULL) | ||||
| return; | return; | ||||
| } | } | ||||
| /* pass in fixed parameter values */ | /* pass in fixed parameter values */ | ||||
| foreach (ShaderInput *input, node->inputs) { | foreach (ShaderInput *input, node->get_inputs()) { | ||||
| if (!input->link) { | if (!input->get_link()) { | ||||
| /* checks to untangle graphs */ | /* checks to untangle graphs */ | ||||
| if (node_skip_input(node, input)) | if (node_skip_input(node, input)) | ||||
| continue; | continue; | ||||
| string param_name = compatible_name(node, input); | string param_name = compatible_name(node, input); | ||||
| const SocketType &socket = input->socket_type; | const SocketType &socket = input->get_socket_type(); | ||||
| switch (input->type()) { | switch (input->type()) { | ||||
| case SocketType::COLOR: | case SocketType::COLOR: | ||||
| parameter_color(param_name.c_str(), node->get_float3(socket)); | parameter_color(param_name.c_str(), node->get_float3(socket)); | ||||
| break; | break; | ||||
| case SocketType::POINT: | case SocketType::POINT: | ||||
| parameter_point(param_name.c_str(), node->get_float3(socket)); | parameter_point(param_name.c_str(), node->get_float3(socket)); | ||||
| break; | break; | ||||
| case SocketType::VECTOR: | case SocketType::VECTOR: | ||||
| Show All 28 Lines | void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath) | ||||
| else if (current_type == SHADER_TYPE_DISPLACEMENT) | else if (current_type == SHADER_TYPE_DISPLACEMENT) | ||||
| ss->Shader("displacement", name, id(node).c_str()); | ss->Shader("displacement", name, id(node).c_str()); | ||||
| else if (current_type == SHADER_TYPE_BUMP) | else if (current_type == SHADER_TYPE_BUMP) | ||||
| ss->Shader("displacement", name, id(node).c_str()); | ss->Shader("displacement", name, id(node).c_str()); | ||||
| else | else | ||||
| assert(0); | assert(0); | ||||
| /* link inputs to other nodes */ | /* link inputs to other nodes */ | ||||
| foreach (ShaderInput *input, node->inputs) { | foreach (ShaderInput *input, node->get_inputs()) { | ||||
| if (input->link) { | if (input->get_link()) { | ||||
| if (node_skip_input(node, input)) | if (node_skip_input(node, input)) | ||||
| continue; | continue; | ||||
| /* connect shaders */ | /* connect shaders */ | ||||
| string id_from = id(input->link->parent); | string id_from = id(input->get_link()->get_parent()); | ||||
| string id_to = id(node); | string id_to = id(node); | ||||
| string param_from = compatible_name(input->link->parent, input->link); | string param_from = compatible_name(input->get_link()->get_parent(), input->get_link()); | ||||
| string param_to = compatible_name(node, input); | string param_to = compatible_name(node, input); | ||||
| ss->ConnectShaders(id_from.c_str(), param_from.c_str(), id_to.c_str(), param_to.c_str()); | ss->ConnectShaders(id_from.c_str(), param_from.c_str(), id_to.c_str(), param_to.c_str()); | ||||
| } | } | ||||
| } | } | ||||
| /* test if we shader contains specific closures */ | /* test if we shader contains specific closures */ | ||||
| OSLShaderInfo *info = manager->shader_loaded_info(name); | OSLShaderInfo *info = manager->shader_loaded_info(name); | ||||
| if (current_type == SHADER_TYPE_SURFACE) { | if (current_type == SHADER_TYPE_SURFACE) { | ||||
| if (info) { | if (info) { | ||||
| if (info->has_surface_emission) | if (info->has_surface_emission) | ||||
| current_shader->has_surface_emission = true; | current_shader->set_has_surface_emission(true); | ||||
| if (info->has_surface_transparent) | if (info->has_surface_transparent) | ||||
| current_shader->has_surface_transparent = true; | current_shader->set_has_surface_transparent(true); | ||||
| if (info->has_surface_bssrdf) { | if (info->has_surface_bssrdf) { | ||||
| current_shader->has_surface_bssrdf = true; | current_shader->set_has_surface_bssrdf(true); | ||||
| current_shader->has_bssrdf_bump = true; /* can't detect yet */ | current_shader->set_has_bssrdf_bump(true); /* can't detect yet */ | ||||
| } | } | ||||
| current_shader->has_bump = true; /* can't detect yet */ | current_shader->set_has_bump(true); /* can't detect yet */ | ||||
| } | } | ||||
| if (node->has_spatial_varying()) { | if (node->has_spatial_varying()) { | ||||
| current_shader->has_surface_spatial_varying = true; | current_shader->set_has_surface_spatial_varying(true); | ||||
| } | } | ||||
| } | } | ||||
| else if (current_type == SHADER_TYPE_VOLUME) { | else if (current_type == SHADER_TYPE_VOLUME) { | ||||
| if (node->has_spatial_varying()) | if (node->has_spatial_varying()) | ||||
| current_shader->has_volume_spatial_varying = true; | current_shader->set_has_volume_spatial_varying(true); | ||||
| if (node->has_attribute_dependency()) | if (node->has_attribute_dependency()) | ||||
| current_shader->has_volume_attribute_dependency = true; | current_shader->set_has_volume_attribute_dependency(true); | ||||
| } | } | ||||
| if (node->has_integrator_dependency()) { | if (node->has_integrator_dependency()) { | ||||
| current_shader->has_integrator_dependency = true; | current_shader->set_has_integrator_dependency(true); | ||||
| } | } | ||||
| } | } | ||||
| static TypeDesc array_typedesc(TypeDesc typedesc, int arraylength) | static TypeDesc array_typedesc(TypeDesc typedesc, int arraylength) | ||||
| { | { | ||||
| return TypeDesc((TypeDesc::BASETYPE)typedesc.basetype, | return TypeDesc((TypeDesc::BASETYPE)typedesc.basetype, | ||||
| (TypeDesc::AGGREGATE)typedesc.aggregate, | (TypeDesc::AGGREGATE)typedesc.aggregate, | ||||
| (TypeDesc::VECSEMANTICS)typedesc.vecsemantics, | (TypeDesc::VECSEMANTICS)typedesc.vecsemantics, | ||||
| arraylength); | arraylength); | ||||
| } | } | ||||
| void OSLCompiler::parameter(ShaderNode *node, const char *name) | void OSLCompiler::parameter(ShaderNode *node, const char *name) | ||||
| { | { | ||||
| ustring uname = ustring(name); | ustring uname = ustring(name); | ||||
| const SocketType &socket = *(node->type->find_input(uname)); | const SocketType &socket = *(node->get_type()->find_input(uname)); | ||||
| switch (socket.type) { | switch (socket.get_type()) { | ||||
| case SocketType::BOOLEAN: { | case SocketType::BOOLEAN: { | ||||
| int value = node->get_bool(socket); | int value = node->get_bool(socket); | ||||
| ss->Parameter(name, TypeDesc::TypeInt, &value); | ss->Parameter(name, TypeDesc::TypeInt, &value); | ||||
| break; | break; | ||||
| } | } | ||||
| case SocketType::FLOAT: { | case SocketType::FLOAT: { | ||||
| float value = node->get_float(socket); | float value = node->get_float(socket); | ||||
| ss->Parameter(uname, TypeDesc::TypeFloat, &value); | ss->Parameter(uname, TypeDesc::TypeFloat, &value); | ||||
| ▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | case SocketType::INT_ARRAY: { | ||||
| break; | break; | ||||
| } | } | ||||
| case SocketType::COLOR_ARRAY: | case SocketType::COLOR_ARRAY: | ||||
| case SocketType::VECTOR_ARRAY: | case SocketType::VECTOR_ARRAY: | ||||
| case SocketType::POINT_ARRAY: | case SocketType::POINT_ARRAY: | ||||
| case SocketType::NORMAL_ARRAY: { | case SocketType::NORMAL_ARRAY: { | ||||
| TypeDesc typedesc; | TypeDesc typedesc; | ||||
| switch (socket.type) { | switch (socket.get_type()) { | ||||
| case SocketType::COLOR_ARRAY: | case SocketType::COLOR_ARRAY: | ||||
| typedesc = TypeDesc::TypeColor; | typedesc = TypeDesc::TypeColor; | ||||
| break; | break; | ||||
| case SocketType::VECTOR_ARRAY: | case SocketType::VECTOR_ARRAY: | ||||
| typedesc = TypeDesc::TypeVector; | typedesc = TypeDesc::TypeVector; | ||||
| break; | break; | ||||
| case SocketType::POINT_ARRAY: | case SocketType::POINT_ARRAY: | ||||
| typedesc = TypeDesc::TypePoint; | typedesc = TypeDesc::TypePoint; | ||||
| ▲ Show 20 Lines • Show All 127 Lines • ▼ Show 20 Lines | void OSLCompiler::parameter_attribute(const char *name, ustring s) | ||||
| if (Attribute::name_standard(s.c_str())) | if (Attribute::name_standard(s.c_str())) | ||||
| parameter(name, (string("geom:") + s.c_str()).c_str()); | parameter(name, (string("geom:") + s.c_str()).c_str()); | ||||
| else | else | ||||
| parameter(name, s.c_str()); | parameter(name, s.c_str()); | ||||
| } | } | ||||
| void OSLCompiler::find_dependencies(ShaderNodeSet &dependencies, ShaderInput *input) | void OSLCompiler::find_dependencies(ShaderNodeSet &dependencies, ShaderInput *input) | ||||
| { | { | ||||
| ShaderNode *node = (input->link) ? input->link->parent : NULL; | ShaderNode *node = (input->get_link()) ? input->get_link()->get_parent() : NULL; | ||||
| if (node != NULL && dependencies.find(node) == dependencies.end()) { | if (node != NULL && dependencies.find(node) == dependencies.end()) { | ||||
| foreach (ShaderInput *in, node->inputs) | foreach (ShaderInput *in, node->get_inputs()) | ||||
| if (!node_skip_input(node, in)) | if (!node_skip_input(node, in)) | ||||
| find_dependencies(dependencies, in); | find_dependencies(dependencies, in); | ||||
| dependencies.insert(node); | dependencies.insert(node); | ||||
| } | } | ||||
| } | } | ||||
| void OSLCompiler::generate_nodes(const ShaderNodeSet &nodes) | void OSLCompiler::generate_nodes(const ShaderNodeSet &nodes) | ||||
| { | { | ||||
| ShaderNodeSet done; | ShaderNodeSet done; | ||||
| bool nodes_done; | bool nodes_done; | ||||
| do { | do { | ||||
| nodes_done = true; | nodes_done = true; | ||||
| foreach (ShaderNode *node, nodes) { | foreach (ShaderNode *node, nodes) { | ||||
| if (done.find(node) == done.end()) { | if (done.find(node) == done.end()) { | ||||
| bool inputs_done = true; | bool inputs_done = true; | ||||
| foreach (ShaderInput *input, node->inputs) | foreach (ShaderInput *input, node->get_inputs()) | ||||
| if (!node_skip_input(node, input)) | if (!node_skip_input(node, input)) | ||||
| if (input->link && done.find(input->link->parent) == done.end()) | if (input->get_link() && done.find(input->get_link()->get_parent()) == done.end()) | ||||
| inputs_done = false; | inputs_done = false; | ||||
| if (inputs_done) { | if (inputs_done) { | ||||
| node->compile(*this); | node->compile(*this); | ||||
| done.insert(node); | done.insert(node); | ||||
| if (current_type == SHADER_TYPE_SURFACE) { | if (current_type == SHADER_TYPE_SURFACE) { | ||||
| if (node->has_surface_emission()) | if (node->has_surface_emission()) | ||||
| current_shader->has_surface_emission = true; | current_shader->set_has_surface_emission(true); | ||||
| if (node->has_surface_transparent()) | if (node->has_surface_transparent()) | ||||
| current_shader->has_surface_transparent = true; | current_shader->set_has_surface_transparent(true); | ||||
| if (node->has_spatial_varying()) | if (node->has_spatial_varying()) | ||||
| current_shader->has_surface_spatial_varying = true; | current_shader->set_has_surface_spatial_varying(true); | ||||
| if (node->has_surface_bssrdf()) { | if (node->has_surface_bssrdf()) { | ||||
| current_shader->has_surface_bssrdf = true; | current_shader->set_has_surface_bssrdf(true); | ||||
| if (node->has_bssrdf_bump()) | if (node->has_bssrdf_bump()) | ||||
| current_shader->has_bssrdf_bump = true; | current_shader->set_has_bssrdf_bump(true); | ||||
| } | } | ||||
| if (node->has_bump()) { | if (node->has_bump()) { | ||||
| current_shader->has_bump = true; | current_shader->set_has_bump(true); | ||||
| } | } | ||||
| } | } | ||||
| else if (current_type == SHADER_TYPE_VOLUME) { | else if (current_type == SHADER_TYPE_VOLUME) { | ||||
| if (node->has_spatial_varying()) | if (node->has_spatial_varying()) | ||||
| current_shader->has_volume_spatial_varying = true; | current_shader->set_has_volume_spatial_varying(true); | ||||
| } | } | ||||
| } | } | ||||
| else | else | ||||
| nodes_done = false; | nodes_done = false; | ||||
| } | } | ||||
| } | } | ||||
| } while (!nodes_done); | } while (!nodes_done); | ||||
| } | } | ||||
| OSL::ShaderGroupRef OSLCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType type) | OSL::ShaderGroupRef OSLCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType type) | ||||
| { | { | ||||
| current_type = type; | current_type = type; | ||||
| OSL::ShaderGroupRef group = ss->ShaderGroupBegin(shader->name.c_str()); | OSL::ShaderGroupRef group = ss->ShaderGroupBegin(shader->get_name().c_str()); | ||||
| ShaderNode *output = graph->output(); | ShaderNode *output = graph->output(); | ||||
| ShaderNodeSet dependencies; | ShaderNodeSet dependencies; | ||||
| if (type == SHADER_TYPE_SURFACE) { | if (type == SHADER_TYPE_SURFACE) { | ||||
| /* generate surface shader */ | /* generate surface shader */ | ||||
| find_dependencies(dependencies, output->input("Surface")); | find_dependencies(dependencies, output->input("Surface")); | ||||
| generate_nodes(dependencies); | generate_nodes(dependencies); | ||||
| Show All 23 Lines | OSL::ShaderGroupRef OSLCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType type) | ||||
| ss->ShaderGroupEnd(); | ss->ShaderGroupEnd(); | ||||
| return group; | return group; | ||||
| } | } | ||||
| void OSLCompiler::compile(OSLGlobals *og, Shader *shader) | void OSLCompiler::compile(OSLGlobals *og, Shader *shader) | ||||
| { | { | ||||
| if (shader->is_modified()) { | if (shader->is_modified()) { | ||||
| ShaderGraph *graph = shader->graph; | ShaderGraph *graph = shader->get_graph(); | ||||
| ShaderNode *output = (graph) ? graph->output() : NULL; | ShaderNode *output = (graph) ? graph->output() : NULL; | ||||
| bool has_bump = (shader->get_displacement_method() != DISPLACE_TRUE) && | bool has_bump = (shader->get_displacement_method() != DISPLACE_TRUE) && | ||||
| output->input("Surface")->link && output->input("Displacement")->link; | output->input("Surface")->get_link() && | ||||
| output->input("Displacement")->get_link(); | |||||
| /* finalize */ | /* finalize */ | ||||
| shader->graph->finalize(scene, | graph->finalize(scene, | ||||
| has_bump, | has_bump, | ||||
| shader->has_integrator_dependency, | shader->get_has_integrator_dependency(), | ||||
| shader->get_displacement_method() == DISPLACE_BOTH); | shader->get_displacement_method() == DISPLACE_BOTH); | ||||
| current_shader = shader; | current_shader = shader; | ||||
| shader->has_surface = false; | shader->set_has_surface(false); | ||||
| shader->has_surface_emission = false; | shader->set_has_surface_emission(false); | ||||
| shader->has_surface_transparent = false; | shader->set_has_surface_transparent(false); | ||||
| shader->has_surface_bssrdf = false; | shader->set_has_surface_bssrdf(false); | ||||
| shader->has_bump = has_bump; | shader->set_has_bump(has_bump); | ||||
| shader->has_bssrdf_bump = has_bump; | shader->set_has_bssrdf_bump(has_bump); | ||||
| shader->has_volume = false; | shader->set_has_volume(false); | ||||
| shader->has_displacement = false; | shader->set_has_displacement(false); | ||||
| shader->has_surface_spatial_varying = false; | shader->set_has_surface_spatial_varying(false); | ||||
| shader->has_volume_spatial_varying = false; | shader->set_has_volume_spatial_varying(false); | ||||
| shader->has_volume_attribute_dependency = false; | shader->set_has_volume_attribute_dependency(false); | ||||
| shader->has_integrator_dependency = false; | shader->set_has_integrator_dependency(false); | ||||
| /* generate surface shader */ | /* generate surface shader */ | ||||
| if (shader->used && graph && output->input("Surface")->link) { | if (shader->get_used() && graph && output->input("Surface")->get_link()) { | ||||
| shader->osl_surface_ref = compile_type(shader, shader->graph, SHADER_TYPE_SURFACE); | shader->set_osl_surface_ref(compile_type(shader, graph, SHADER_TYPE_SURFACE)); | ||||
| if (has_bump) | if (has_bump) | ||||
| shader->osl_surface_bump_ref = compile_type(shader, shader->graph, SHADER_TYPE_BUMP); | shader->set_osl_surface_bump_ref(compile_type(shader, graph, SHADER_TYPE_BUMP)); | ||||
| else | else | ||||
| shader->osl_surface_bump_ref = OSL::ShaderGroupRef(); | shader->set_osl_surface_bump_ref(OSL::ShaderGroupRef()); | ||||
| shader->has_surface = true; | shader->set_has_surface(true); | ||||
| } | } | ||||
| else { | else { | ||||
| shader->osl_surface_ref = OSL::ShaderGroupRef(); | shader->set_osl_surface_ref(OSL::ShaderGroupRef()); | ||||
| shader->osl_surface_bump_ref = OSL::ShaderGroupRef(); | shader->set_osl_surface_bump_ref(OSL::ShaderGroupRef()); | ||||
| } | } | ||||
| /* generate volume shader */ | /* generate volume shader */ | ||||
| if (shader->used && graph && output->input("Volume")->link) { | if (shader->get_used() && graph && output->input("Volume")->get_link()) { | ||||
| shader->osl_volume_ref = compile_type(shader, shader->graph, SHADER_TYPE_VOLUME); | shader->set_osl_volume_ref(compile_type(shader, graph, SHADER_TYPE_VOLUME)); | ||||
| shader->has_volume = true; | shader->set_has_volume(true); | ||||
| } | } | ||||
| else | else | ||||
| shader->osl_volume_ref = OSL::ShaderGroupRef(); | shader->set_osl_volume_ref(OSL::ShaderGroupRef()); | ||||
| /* generate displacement shader */ | /* generate displacement shader */ | ||||
| if (shader->used && graph && output->input("Displacement")->link) { | if (shader->get_used() && graph && output->input("Displacement")->get_link()) { | ||||
| shader->osl_displacement_ref = compile_type(shader, shader->graph, SHADER_TYPE_DISPLACEMENT); | shader->set_osl_displacement_ref(compile_type(shader, graph, SHADER_TYPE_DISPLACEMENT)); | ||||
| shader->has_displacement = true; | shader->set_has_displacement(true); | ||||
| } | } | ||||
| else | else | ||||
| shader->osl_displacement_ref = OSL::ShaderGroupRef(); | shader->set_osl_displacement_ref(OSL::ShaderGroupRef()); | ||||
| } | } | ||||
| /* push state to array for lookup */ | /* push state to array for lookup */ | ||||
| og->surface_state.push_back(shader->osl_surface_ref); | og->surface_state.push_back(shader->get_osl_surface_ref()); | ||||
| og->volume_state.push_back(shader->osl_volume_ref); | og->volume_state.push_back(shader->get_osl_volume_ref()); | ||||
| og->displacement_state.push_back(shader->osl_displacement_ref); | og->displacement_state.push_back(shader->get_osl_displacement_ref()); | ||||
| og->bump_state.push_back(shader->osl_surface_bump_ref); | og->bump_state.push_back(shader->get_osl_surface_bump_ref()); | ||||
| } | } | ||||
| void OSLCompiler::parameter_texture(const char *name, ustring filename, ustring colorspace) | void OSLCompiler::parameter_texture(const char *name, ustring filename, ustring colorspace) | ||||
| { | { | ||||
| /* Textured loaded through the OpenImageIO texture cache. For this | /* Textured loaded through the OpenImageIO texture cache. For this | ||||
| * case we need to do runtime color space conversion. */ | * case we need to do runtime color space conversion. */ | ||||
| OSLTextureHandle *handle = new OSLTextureHandle(OSLTextureHandle::OIIO); | OSLTextureHandle *handle = new OSLTextureHandle(OSLTextureHandle::OIIO); | ||||
| handle->processor = ColorSpaceManager::get_processor(colorspace); | handle->processor = ColorSpaceManager::get_processor(colorspace); | ||||
| ▲ Show 20 Lines • Show All 94 Lines • Show Last 20 Lines | |||||