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"
42 sample_as_light = true;
43 homogeneous_volume = false;
46 has_surface_transparent = false;
47 has_surface_emission = false;
49 has_displacement = false;
52 need_update_attributes = true;
61 void Shader::set_graph(ShaderGraph *graph_)
70 void Shader::tag_update(Scene *scene)
74 scene->shader_manager->need_update = true;
76 /* if the shader previously was emissive, update light distribution,
77 * if the new shader is emissive, a light manager update tag will be
78 * done in the shader manager device update. */
79 if(sample_as_light && has_surface_emission)
80 scene->light_manager->need_update = true;
82 /* get requested attributes. this could be optimized by pruning unused
83 nodes here already, but that's the job of the shader manager currently,
84 and may not be so great for interactive rendering where you temporarily
86 AttributeRequestSet prev_attributes = attributes;
89 foreach(ShaderNode *node, graph->nodes)
90 node->attributes(&attributes);
92 /* compare if the attributes changed, mesh manager will check
93 need_update_attributes, update the relevant meshes and clear it. */
94 if(attributes.modified(prev_attributes)) {
95 need_update_attributes = true;
96 scene->mesh_manager->need_update = true;
102 ShaderManager::ShaderManager()
107 ShaderManager::~ShaderManager()
111 ShaderManager *ShaderManager::create(Scene *scene)
113 ShaderManager *manager;
116 if(scene->params.shadingsystem == SceneParams::OSL)
117 manager = new OSLShaderManager();
120 manager = new SVMShaderManager();
127 uint ShaderManager::get_attribute_id(ustring name)
129 /* get a unique id for each name, for SVM attribute lookup */
130 AttributeIDMap::iterator it = unique_attribute_id.find(name);
132 if(it != unique_attribute_id.end())
135 uint id = (uint)Attribute::STD_NUM + unique_attribute_id.size();
136 unique_attribute_id[name] = id;
140 uint ShaderManager::get_attribute_id(Attribute::Standard std)
145 int ShaderManager::get_shader_id(uint shader, Mesh *mesh, bool smooth)
147 /* get a shader id to pass to the kernel */
150 /* index depends bump since this setting is not in the shader */
151 if(mesh && mesh->displacement_method != Mesh::DISPLACE_TRUE)
155 id |= SHADER_SMOOTH_NORMAL;
158 id |= SHADER_CAST_SHADOW|SHADER_AREA_LIGHT;
163 void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
165 device_free_common(device, dscene);
167 if(scene->shaders.size() == 0)
170 uint shader_flag_size = scene->shaders.size()*2;
171 uint *shader_flag = dscene->shader_flag.resize(shader_flag_size);
174 foreach(Shader *shader, scene->shaders) {
177 if(shader->sample_as_light)
178 flag |= SD_SAMPLE_AS_LIGHT;
179 if(shader->has_surface_transparent)
180 flag |= SD_HAS_SURFACE_TRANSPARENT;
181 if(shader->has_volume)
182 flag |= SD_HAS_VOLUME;
183 if(shader->homogeneous_volume)
184 flag |= SD_HOMOGENEOUS_VOLUME;
186 shader_flag[i++] = flag;
187 shader_flag[i++] = flag;
190 device->tex_alloc("__shader_flag", dscene->shader_flag);
193 void ShaderManager::device_free_common(Device *device, DeviceScene *dscene)
195 device->tex_free(dscene->shader_flag);
196 dscene->shader_flag.clear();
199 void ShaderManager::add_default(Scene *scene)
203 ShaderNode *closure, *out;
205 /* default surface */
207 graph = new ShaderGraph();
209 closure = graph->add(new DiffuseBsdfNode());
210 closure->input("Color")->value = make_float3(0.8f, 0.8f, 0.8f);
211 out = graph->output();
213 graph->connect(closure->output("BSDF"), out->input("Surface"));
215 shader = new Shader();
216 shader->name = "default_surface";
217 shader->graph = graph;
218 scene->shaders.push_back(shader);
219 scene->default_surface = scene->shaders.size() - 1;
224 graph = new ShaderGraph();
226 closure = graph->add(new EmissionNode());
227 closure->input("Color")->value = make_float3(0.8f, 0.8f, 0.8f);
228 closure->input("Strength")->value.x = 0.0f;
229 out = graph->output();
231 graph->connect(closure->output("Emission"), out->input("Surface"));
233 shader = new Shader();
234 shader->name = "default_light";
235 shader->graph = graph;
236 scene->shaders.push_back(shader);
237 scene->default_light = scene->shaders.size() - 1;
240 /* default background */
242 graph = new ShaderGraph();
244 closure = graph->add(new BackgroundNode());
245 closure->input("Color")->value = make_float3(0.8f, 0.8f, 0.8f);
246 out = graph->output();
248 graph->connect(closure->output("Background"), out->input("Surface"));
250 shader = new Shader();
251 shader->name = "default_background";
252 shader->graph = graph;
253 scene->shaders.push_back(shader);
254 scene->default_background = scene->shaders.size() - 1;