Code cleanup: libmv C API
[blender.git] / intern / cycles / render / shader.cpp
1 /*
2  * Copyright 2011, Blender Foundation.
3  *
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.
8  *
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.
13  *
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.
17  */
18
19 #include "background.h"
20 #include "bssrdf.h"
21 #include "device.h"
22 #include "graph.h"
23 #include "light.h"
24 #include "mesh.h"
25 #include "nodes.h"
26 #include "osl.h"
27 #include "scene.h"
28 #include "shader.h"
29 #include "svm.h"
30 #include "tables.h"
31
32 #include "util_foreach.h"
33
34 CCL_NAMESPACE_BEGIN
35
36 /* Shader */
37
38 Shader::Shader()
39 {
40         name = "";
41         pass_id = 0;
42
43         graph = NULL;
44         graph_bump = NULL;
45
46         use_mis = true;
47         use_transparent_shadow = true;
48         homogeneous_volume = false;
49
50         has_surface = false;
51         has_surface_transparent = false;
52         has_surface_emission = false;
53         has_surface_bssrdf = false;
54         has_volume = false;
55         has_displacement = false;
56
57         used = false;
58
59         need_update = true;
60         need_update_attributes = true;
61 }
62
63 Shader::~Shader()
64 {
65         delete graph;
66         delete graph_bump;
67 }
68
69 void Shader::set_graph(ShaderGraph *graph_)
70 {
71         /* do this here already so that we can detect if mesh or object attributes
72          * are needed, since the node attribute callbacks check if their sockets
73          * are connected but proxy nodes should not count */
74         if(graph_)
75                 graph_->remove_unneeded_nodes();
76
77         /* assign graph */
78         delete graph;
79         delete graph_bump;
80         graph = graph_;
81         graph_bump = NULL;
82 }
83
84 void Shader::tag_update(Scene *scene)
85 {
86         /* update tag */
87         need_update = true;
88         scene->shader_manager->need_update = true;
89
90         /* if the shader previously was emissive, update light distribution,
91          * if the new shader is emissive, a light manager update tag will be
92          * done in the shader manager device update. */
93         if(use_mis && has_surface_emission)
94                 scene->light_manager->need_update = true;
95
96         /* get requested attributes. this could be optimized by pruning unused
97          * nodes here already, but that's the job of the shader manager currently,
98          * and may not be so great for interactive rendering where you temporarily
99          * disconnect a node */
100         AttributeRequestSet prev_attributes = attributes;
101
102         attributes.clear();
103         foreach(ShaderNode *node, graph->nodes)
104                 node->attributes(&attributes);
105         
106         /* compare if the attributes changed, mesh manager will check
107          * need_update_attributes, update the relevant meshes and clear it. */
108         if(attributes.modified(prev_attributes)) {
109                 need_update_attributes = true;
110                 scene->mesh_manager->need_update = true;
111         }
112 }
113
114 void Shader::tag_used(Scene *scene)
115 {
116         /* if an unused shader suddenly gets used somewhere, it needs to be
117          * recompiled because it was skipped for compilation before */
118         if(!used) {
119                 need_update = true;
120                 scene->shader_manager->need_update = true;
121         }
122 }
123
124 /* Shader Manager */
125
126 ShaderManager::ShaderManager()
127 {
128         need_update = true;
129         bssrdf_table_offset = TABLE_OFFSET_INVALID;
130 }
131
132 ShaderManager::~ShaderManager()
133 {
134 }
135
136 ShaderManager *ShaderManager::create(Scene *scene, int shadingsystem)
137 {
138         ShaderManager *manager;
139
140 #ifdef WITH_OSL
141         if(shadingsystem == SceneParams::OSL)
142                 manager = new OSLShaderManager();
143         else
144 #endif
145                 manager = new SVMShaderManager();
146         
147         add_default(scene);
148
149         return manager;
150 }
151
152 uint ShaderManager::get_attribute_id(ustring name)
153 {
154         /* get a unique id for each name, for SVM attribute lookup */
155         AttributeIDMap::iterator it = unique_attribute_id.find(name);
156
157         if(it != unique_attribute_id.end())
158                 return it->second;
159         
160         uint id = (uint)ATTR_STD_NUM + unique_attribute_id.size();
161         unique_attribute_id[name] = id;
162         return id;
163 }
164
165 uint ShaderManager::get_attribute_id(AttributeStandard std)
166 {
167         return (uint)std;
168 }
169
170 int ShaderManager::get_shader_id(uint shader, Mesh *mesh, bool smooth)
171 {
172         /* get a shader id to pass to the kernel */
173         int id = shader*2;
174         
175         /* index depends bump since this setting is not in the shader */
176         if(mesh && mesh->displacement_method != Mesh::DISPLACE_TRUE)
177                 id += 1;
178         /* smooth flag */
179         if(smooth)
180                 id |= SHADER_SMOOTH_NORMAL;
181         
182         /* default flags */
183         id |= SHADER_CAST_SHADOW|SHADER_AREA_LIGHT;
184         
185         return id;
186 }
187
188 void ShaderManager::device_update_shaders_used(Scene *scene)
189 {
190         /* figure out which shaders are in use, so SVM/OSL can skip compiling them
191          * for speed and avoid loading image textures into memory */
192         foreach(Shader *shader, scene->shaders)
193                 shader->used = false;
194
195         scene->shaders[scene->background->shader]->used = true;
196         scene->shaders[scene->default_surface]->used = true;
197         scene->shaders[scene->default_light]->used = true;
198         scene->shaders[scene->default_background]->used = true;
199         scene->shaders[scene->default_empty]->used = true;
200
201         foreach(Mesh *mesh, scene->meshes)
202                 foreach(uint shader, mesh->used_shaders)
203                         scene->shaders[shader]->used = true;
204
205         foreach(Light *light, scene->lights)
206                 scene->shaders[light->shader]->used = true;
207 }
208
209 void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
210 {
211         device->tex_free(dscene->shader_flag);
212         dscene->shader_flag.clear();
213
214         if(scene->shaders.size() == 0)
215                 return;
216
217         uint shader_flag_size = scene->shaders.size()*4;
218         uint *shader_flag = dscene->shader_flag.resize(shader_flag_size);
219         uint i = 0;
220         bool has_surface_bssrdf = false;
221
222         foreach(Shader *shader, scene->shaders) {
223                 uint flag = 0;
224
225                 if(shader->use_mis)
226                         flag |= SD_USE_MIS;
227                 if(shader->has_surface_transparent && shader->use_transparent_shadow)
228                         flag |= SD_HAS_TRANSPARENT_SHADOW;
229                 if(shader->has_volume)
230                         flag |= SD_HAS_VOLUME;
231                 if(shader->homogeneous_volume)
232                         flag |= SD_HOMOGENEOUS_VOLUME;
233                 if(shader->has_surface_bssrdf)
234                         has_surface_bssrdf = true;
235
236                 shader_flag[i++] = flag;
237                 shader_flag[i++] = shader->pass_id;
238                 shader_flag[i++] = flag;
239                 shader_flag[i++] = shader->pass_id;
240         }
241
242         device->tex_alloc("__shader_flag", dscene->shader_flag);
243
244         /* bssrdf lookup table */
245         KernelBSSRDF *kbssrdf = &dscene->data.bssrdf;
246
247         if(has_surface_bssrdf && bssrdf_table_offset == TABLE_OFFSET_INVALID) {
248                 vector<float> table;
249
250                 bssrdf_table_build(table);
251                 bssrdf_table_offset = scene->lookup_tables->add_table(dscene, table);
252
253                 kbssrdf->table_offset = (int)bssrdf_table_offset;
254                 kbssrdf->num_attempts = BSSRDF_MAX_ATTEMPTS;
255         }
256         else if(!has_surface_bssrdf && bssrdf_table_offset != TABLE_OFFSET_INVALID) {
257                 scene->lookup_tables->remove_table(bssrdf_table_offset);
258                 bssrdf_table_offset = TABLE_OFFSET_INVALID;
259         }
260 }
261
262 void ShaderManager::device_free_common(Device *device, DeviceScene *dscene, Scene *scene)
263 {
264         if(bssrdf_table_offset != TABLE_OFFSET_INVALID) {
265                 scene->lookup_tables->remove_table(bssrdf_table_offset);
266                 bssrdf_table_offset = TABLE_OFFSET_INVALID;
267         }
268
269         device->tex_free(dscene->shader_flag);
270         dscene->shader_flag.clear();
271 }
272
273 void ShaderManager::add_default(Scene *scene)
274 {
275         Shader *shader;
276         ShaderGraph *graph;
277         ShaderNode *closure, *out;
278
279         /* default surface */
280         {
281                 graph = new ShaderGraph();
282
283                 closure = graph->add(new DiffuseBsdfNode());
284                 closure->input("Color")->value = make_float3(0.8f, 0.8f, 0.8f);
285                 out = graph->output();
286
287                 graph->connect(closure->output("BSDF"), out->input("Surface"));
288
289                 shader = new Shader();
290                 shader->name = "default_surface";
291                 shader->graph = graph;
292                 scene->shaders.push_back(shader);
293                 scene->default_surface = scene->shaders.size() - 1;
294         }
295
296         /* default light */
297         {
298                 graph = new ShaderGraph();
299
300                 closure = graph->add(new EmissionNode());
301                 closure->input("Color")->value = make_float3(0.8f, 0.8f, 0.8f);
302                 closure->input("Strength")->value.x = 0.0f;
303                 out = graph->output();
304
305                 graph->connect(closure->output("Emission"), out->input("Surface"));
306
307                 shader = new Shader();
308                 shader->name = "default_light";
309                 shader->graph = graph;
310                 scene->shaders.push_back(shader);
311                 scene->default_light = scene->shaders.size() - 1;
312         }
313
314         /* default background */
315         {
316                 graph = new ShaderGraph();
317
318                 closure = graph->add(new BackgroundNode());
319                 closure->input("Color")->value = make_float3(0.8f, 0.8f, 0.8f);
320                 out = graph->output();
321
322                 graph->connect(closure->output("Background"), out->input("Surface"));
323
324                 shader = new Shader();
325                 shader->name = "default_background";
326                 shader->graph = graph;
327                 scene->shaders.push_back(shader);
328                 scene->default_background = scene->shaders.size() - 1;
329         }
330
331         /* default empty */
332         {
333                 graph = new ShaderGraph();
334
335                 shader = new Shader();
336                 shader->name = "default_empty";
337                 shader->graph = graph;
338                 scene->shaders.push_back(shader);
339                 scene->default_empty = scene->shaders.size() - 1;
340         }
341 }
342
343 CCL_NAMESPACE_END
344