diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-12-12 10:51:06 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-12-12 10:51:06 +0400 |
commit | 3759c10e5c832672920daf80b0f1018604cfb4b4 (patch) | |
tree | 1e7dc95b5a192213ea2f26927228e9fe173e5af4 /intern/cycles/render/osl.cpp | |
parent | cf723e5e7c99cf653196b47afe131cb3cac24050 (diff) |
Fix #33485: cycles OSL now autodetects the presence of emission and transparent
closures to enable multiple importance sampling and transparent shadows.
Diffstat (limited to 'intern/cycles/render/osl.cpp')
-rw-r--r-- | intern/cycles/render/osl.cpp | 41 |
1 files changed, 32 insertions, 9 deletions
diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp index b3b838be25b..28de56f3a72 100644 --- a/intern/cycles/render/osl.cpp +++ b/intern/cycles/render/osl.cpp @@ -76,12 +76,12 @@ void OSLShaderManager::device_update(Device *device, DeviceScene *dscene, Scene if(progress.get_cancel()) return; - if(shader->sample_as_light && shader->has_surface_emission) - scene->light_manager->need_update = true; - OSLCompiler compiler((void*)this, (void*)ss, scene->image_manager); compiler.background = (shader == scene->shaders[scene->default_background]); compiler.compile(og, shader); + + if(shader->sample_as_light && shader->has_surface_emission) + scene->light_manager->need_update = true; } /* setup shader engine */ @@ -202,8 +202,14 @@ static string shader_filepath_hash(const string& filepath, uint64_t modified_tim const char *OSLShaderManager::shader_test_loaded(const string& hash) { - set<string>::iterator it = loaded_shaders.find(hash); - return (it == loaded_shaders.end())? NULL: it->c_str(); + map<string, OSLShaderInfo>::iterator it = loaded_shaders.find(hash); + return (it == loaded_shaders.end())? NULL: it->first.c_str(); +} + +OSLShaderInfo *OSLShaderManager::shader_loaded_info(const string& hash) +{ + map<string, OSLShaderInfo>::iterator it = loaded_shaders.find(hash); + return (it == loaded_shaders.end())? NULL: &it->second; } const char *OSLShaderManager::shader_load_filepath(string filepath) @@ -261,7 +267,8 @@ const char *OSLShaderManager::shader_load_filepath(string filepath) if(!path_read_text(filepath, bytecode)) { fprintf(stderr, "Cycles shader graph: failed to read file %s\n", filepath.c_str()); - loaded_shaders.insert(bytecode_hash); /* to avoid repeat tries */ + OSLShaderInfo info; + loaded_shaders[bytecode_hash] = info; /* to avoid repeat tries */ return NULL; } @@ -306,7 +313,13 @@ const char *OSLShaderManager::shader_load_bytecode(const string& hash, const str { load_memory_shader(ss, hash.c_str(), bytecode.c_str()); - return loaded_shaders.insert(hash).first->c_str(); + /* this is a bit weak, but works */ + OSLShaderInfo info; + info.has_surface_emission = (bytecode.find("\"emission\"") != string::npos); + info.has_surface_transparent = (bytecode.find("\"transparent\"") != string::npos); + loaded_shaders[hash] = info; + + return loaded_shaders.find(hash)->first.c_str(); } /* Graph Compiler */ @@ -477,6 +490,16 @@ void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath) 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 */ + OSLShaderInfo *info = ((OSLShaderManager*)manager)->shader_loaded_info(name); + + if(info) { + if(info->has_surface_emission) + current_shader->has_surface_emission = true; + if(info->has_surface_transparent) + current_shader->has_surface_transparent = true; + } } void OSLCompiler::parameter(const char *name, float f) @@ -632,9 +655,9 @@ void OSLCompiler::generate_nodes(const set<ShaderNode*>& nodes) node->compile(*this); done.insert(node); - if(node->name == ustring("emission")) + if(node->has_surface_emission()) current_shader->has_surface_emission = true; - if(node->name == ustring("transparent")) + if(node->has_surface_transparent()) current_shader->has_surface_transparent = true; } else |