2 * Copyright 2011, Blender Foundation.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
29 #include "util_foreach.h"
43 sample_as_light = true;
44 homogeneous_volume = false;
47 has_surface_transparent = false;
48 has_surface_emission = false;
50 has_displacement = false;
53 need_update_attributes = true;
62 void Shader::set_graph(ShaderGraph *graph_)
71 void Shader::tag_update(Scene *scene)
75 scene->shader_manager->need_update = true;
77 /* if the shader previously was emissive, update light distribution,
78 * if the new shader is emissive, a light manager update tag will be
79 * done in the shader manager device update. */
80 if(sample_as_light && has_surface_emission)
81 scene->light_manager->need_update = true;
83 /* get requested attributes. this could be optimized by pruning unused
84 nodes here already, but that's the job of the shader manager currently,
85 and may not be so great for interactive rendering where you temporarily
87 AttributeRequestSet prev_attributes = attributes;
90 foreach(ShaderNode *node, graph->nodes)
91 node->attributes(&attributes);
93 /* compare if the attributes changed, mesh manager will check
94 need_update_attributes, update the relevant meshes and clear it. */
95 if(attributes.modified(prev_attributes)) {
96 need_update_attributes = true;
97 scene->mesh_manager->need_update = true;
103 ShaderManager::ShaderManager()
108 ShaderManager::~ShaderManager()
112 ShaderManager *ShaderManager::create(Scene *scene)
114 ShaderManager *manager;
117 if(scene->params.shadingsystem == SceneParams::OSL)
118 manager = new OSLShaderManager();
121 manager = new SVMShaderManager();
128 uint ShaderManager::get_attribute_id(ustring name)
130 /* get a unique id for each name, for SVM attribute lookup */
131 AttributeIDMap::iterator it = unique_attribute_id.find(name);
133 if(it != unique_attribute_id.end())
136 uint id = (uint)Attribute::STD_NUM + unique_attribute_id.size();
137 unique_attribute_id[name] = id;
141 uint ShaderManager::get_attribute_id(Attribute::Standard std)
146 int ShaderManager::get_shader_id(uint shader, Mesh *mesh, bool smooth)
148 /* get a shader id to pass to the kernel */
151 /* index depends bump since this setting is not in the shader */
152 if(mesh && mesh->displacement_method != Mesh::DISPLACE_TRUE)
156 id |= SHADER_SMOOTH_NORMAL;
159 id |= SHADER_CAST_SHADOW|SHADER_AREA_LIGHT;
164 void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
166 device_free_common(device, dscene);
168 if(scene->shaders.size() == 0)
171 uint shader_flag_size = scene->shaders.size()*4;
172 uint *shader_flag = dscene->shader_flag.resize(shader_flag_size);
175 foreach(Shader *shader, scene->shaders) {
178 if(shader->sample_as_light)
179 flag |= SD_SAMPLE_AS_LIGHT;
180 if(shader->has_surface_transparent)
181 flag |= SD_HAS_SURFACE_TRANSPARENT;
182 if(shader->has_volume)
183 flag |= SD_HAS_VOLUME;
184 if(shader->homogeneous_volume)
185 flag |= SD_HOMOGENEOUS_VOLUME;
187 shader_flag[i++] = flag;
188 shader_flag[i++] = shader->pass_id;
189 shader_flag[i++] = flag;
190 shader_flag[i++] = shader->pass_id;
193 device->tex_alloc("__shader_flag", dscene->shader_flag);
196 void ShaderManager::device_free_common(Device *device, DeviceScene *dscene)
198 device->tex_free(dscene->shader_flag);
199 dscene->shader_flag.clear();
202 void ShaderManager::add_default(Scene *scene)
206 ShaderNode *closure, *out;
208 /* default surface */
210 graph = new ShaderGraph();
212 closure = graph->add(new DiffuseBsdfNode());
213 closure->input("Color")->value = make_float3(0.8f, 0.8f, 0.8f);
214 out = graph->output();
216 graph->connect(closure->output("BSDF"), out->input("Surface"));
218 shader = new Shader();
219 shader->name = "default_surface";
220 shader->graph = graph;
221 scene->shaders.push_back(shader);
222 scene->default_surface = scene->shaders.size() - 1;
227 graph = new ShaderGraph();
229 closure = graph->add(new EmissionNode());
230 closure->input("Color")->value = make_float3(0.8f, 0.8f, 0.8f);
231 closure->input("Strength")->value.x = 0.0f;
232 out = graph->output();
234 graph->connect(closure->output("Emission"), out->input("Surface"));
236 shader = new Shader();
237 shader->name = "default_light";
238 shader->graph = graph;
239 scene->shaders.push_back(shader);
240 scene->default_light = scene->shaders.size() - 1;
243 /* default background */
245 graph = new ShaderGraph();
247 closure = graph->add(new BackgroundNode());
248 closure->input("Color")->value = make_float3(0.8f, 0.8f, 0.8f);
249 out = graph->output();
251 graph->connect(closure->output("Background"), out->input("Surface"));
253 shader = new Shader();
254 shader->name = "default_background";
255 shader->graph = graph;
256 scene->shaders.push_back(shader);
257 scene->default_background = scene->shaders.size() - 1;
260 /* default holdout */
262 graph = new ShaderGraph();
264 closure = graph->add(new HoldoutNode());
265 out = graph->output();
267 graph->connect(closure->output("Holdout"), out->input("Surface"));
269 shader = new Shader();
270 shader->name = "default_holdout";
271 shader->graph = graph;
272 scene->shaders.push_back(shader);
273 scene->default_holdout = scene->shaders.size() - 1;