Blender V2.61 - r43446
|
00001 /* 00002 * Copyright 2011, Blender Foundation. 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #include "device.h" 00020 #include "graph.h" 00021 #include "light.h" 00022 #include "mesh.h" 00023 #include "nodes.h" 00024 #include "osl.h" 00025 #include "scene.h" 00026 #include "shader.h" 00027 #include "svm.h" 00028 00029 #include "util_foreach.h" 00030 00031 CCL_NAMESPACE_BEGIN 00032 00033 /* Shader */ 00034 00035 Shader::Shader() 00036 { 00037 name = ""; 00038 00039 graph = NULL; 00040 graph_bump = NULL; 00041 00042 sample_as_light = true; 00043 homogeneous_volume = false; 00044 00045 has_surface = false; 00046 has_surface_transparent = false; 00047 has_surface_emission = false; 00048 has_volume = false; 00049 has_displacement = false; 00050 00051 need_update = true; 00052 need_update_attributes = true; 00053 } 00054 00055 Shader::~Shader() 00056 { 00057 delete graph; 00058 delete graph_bump; 00059 } 00060 00061 void Shader::set_graph(ShaderGraph *graph_) 00062 { 00063 /* assign graph */ 00064 delete graph; 00065 delete graph_bump; 00066 graph = graph_; 00067 graph_bump = NULL; 00068 } 00069 00070 void Shader::tag_update(Scene *scene) 00071 { 00072 /* update tag */ 00073 need_update = true; 00074 scene->shader_manager->need_update = true; 00075 00076 /* if the shader previously was emissive, update light distribution, 00077 * if the new shader is emissive, a light manager update tag will be 00078 * done in the shader manager device update. */ 00079 if(sample_as_light && has_surface_emission) 00080 scene->light_manager->need_update = true; 00081 00082 /* get requested attributes. this could be optimized by pruning unused 00083 nodes here already, but that's the job of the shader manager currently, 00084 and may not be so great for interactive rendering where you temporarily 00085 disconnect a node */ 00086 AttributeRequestSet prev_attributes = attributes; 00087 00088 attributes.clear(); 00089 foreach(ShaderNode *node, graph->nodes) 00090 node->attributes(&attributes); 00091 00092 /* compare if the attributes changed, mesh manager will check 00093 need_update_attributes, update the relevant meshes and clear it. */ 00094 if(attributes.modified(prev_attributes)) { 00095 need_update_attributes = true; 00096 scene->mesh_manager->need_update = true; 00097 } 00098 } 00099 00100 /* Shader Manager */ 00101 00102 ShaderManager::ShaderManager() 00103 { 00104 need_update = true; 00105 } 00106 00107 ShaderManager::~ShaderManager() 00108 { 00109 } 00110 00111 ShaderManager *ShaderManager::create(Scene *scene) 00112 { 00113 ShaderManager *manager; 00114 00115 #ifdef WITH_OSL 00116 if(scene->params.shadingsystem == SceneParams::OSL) 00117 manager = new OSLShaderManager(); 00118 else 00119 #endif 00120 manager = new SVMShaderManager(); 00121 00122 add_default(scene); 00123 00124 return manager; 00125 } 00126 00127 uint ShaderManager::get_attribute_id(ustring name) 00128 { 00129 /* get a unique id for each name, for SVM attribute lookup */ 00130 AttributeIDMap::iterator it = unique_attribute_id.find(name); 00131 00132 if(it != unique_attribute_id.end()) 00133 return it->second; 00134 00135 uint id = (uint)Attribute::STD_NUM + unique_attribute_id.size(); 00136 unique_attribute_id[name] = id; 00137 return id; 00138 } 00139 00140 uint ShaderManager::get_attribute_id(Attribute::Standard std) 00141 { 00142 return (uint)std; 00143 } 00144 00145 int ShaderManager::get_shader_id(uint shader, Mesh *mesh, bool smooth) 00146 { 00147 /* get a shader id to pass to the kernel */ 00148 int id = shader*2; 00149 00150 /* index depends bump since this setting is not in the shader */ 00151 if(mesh && mesh->displacement_method != Mesh::DISPLACE_TRUE) 00152 id += 1; 00153 /* smooth flag */ 00154 if(smooth) 00155 id |= SHADER_SMOOTH_NORMAL; 00156 00157 /* default flags */ 00158 id |= SHADER_CAST_SHADOW|SHADER_AREA_LIGHT; 00159 00160 return id; 00161 } 00162 00163 void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress) 00164 { 00165 device_free_common(device, dscene); 00166 00167 if(scene->shaders.size() == 0) 00168 return; 00169 00170 uint shader_flag_size = scene->shaders.size()*2; 00171 uint *shader_flag = dscene->shader_flag.resize(shader_flag_size); 00172 uint i = 0; 00173 00174 foreach(Shader *shader, scene->shaders) { 00175 uint flag = 0; 00176 00177 if(shader->sample_as_light) 00178 flag |= SD_SAMPLE_AS_LIGHT; 00179 if(shader->has_surface_transparent) 00180 flag |= SD_HAS_SURFACE_TRANSPARENT; 00181 if(shader->has_volume) 00182 flag |= SD_HAS_VOLUME; 00183 if(shader->homogeneous_volume) 00184 flag |= SD_HOMOGENEOUS_VOLUME; 00185 00186 shader_flag[i++] = flag; 00187 shader_flag[i++] = flag; 00188 } 00189 00190 device->tex_alloc("__shader_flag", dscene->shader_flag); 00191 } 00192 00193 void ShaderManager::device_free_common(Device *device, DeviceScene *dscene) 00194 { 00195 device->tex_free(dscene->shader_flag); 00196 dscene->shader_flag.clear(); 00197 } 00198 00199 void ShaderManager::add_default(Scene *scene) 00200 { 00201 Shader *shader; 00202 ShaderGraph *graph; 00203 ShaderNode *closure, *out; 00204 00205 /* default surface */ 00206 { 00207 graph = new ShaderGraph(); 00208 00209 closure = graph->add(new DiffuseBsdfNode()); 00210 closure->input("Color")->value = make_float3(0.8f, 0.8f, 0.8f); 00211 out = graph->output(); 00212 00213 graph->connect(closure->output("BSDF"), out->input("Surface")); 00214 00215 shader = new Shader(); 00216 shader->name = "default_surface"; 00217 shader->graph = graph; 00218 scene->shaders.push_back(shader); 00219 scene->default_surface = scene->shaders.size() - 1; 00220 } 00221 00222 /* default light */ 00223 { 00224 graph = new ShaderGraph(); 00225 00226 closure = graph->add(new EmissionNode()); 00227 closure->input("Color")->value = make_float3(0.8f, 0.8f, 0.8f); 00228 closure->input("Strength")->value.x = 0.0f; 00229 out = graph->output(); 00230 00231 graph->connect(closure->output("Emission"), out->input("Surface")); 00232 00233 shader = new Shader(); 00234 shader->name = "default_light"; 00235 shader->graph = graph; 00236 scene->shaders.push_back(shader); 00237 scene->default_light = scene->shaders.size() - 1; 00238 } 00239 00240 /* default background */ 00241 { 00242 graph = new ShaderGraph(); 00243 00244 closure = graph->add(new BackgroundNode()); 00245 closure->input("Color")->value = make_float3(0.8f, 0.8f, 0.8f); 00246 out = graph->output(); 00247 00248 graph->connect(closure->output("Background"), out->input("Surface")); 00249 00250 shader = new Shader(); 00251 shader->name = "default_background"; 00252 shader->graph = graph; 00253 scene->shaders.push_back(shader); 00254 scene->default_background = scene->shaders.size() - 1; 00255 } 00256 } 00257 00258 CCL_NAMESPACE_END 00259