b25673b36c3462a4357662bf21f99095c5cb5943
[blender.git] / intern / cycles / render / shader.cpp
1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License
15  */
16
17 #include "background.h"
18 #include "blackbody.h"
19 #include "device.h"
20 #include "graph.h"
21 #include "light.h"
22 #include "mesh.h"
23 #include "nodes.h"
24 #include "osl.h"
25 #include "scene.h"
26 #include "shader.h"
27 #include "svm.h"
28 #include "tables.h"
29
30 #include "util_foreach.h"
31
32 CCL_NAMESPACE_BEGIN
33
34 /* Shader */
35
36 Shader::Shader()
37 {
38         name = "";
39         pass_id = 0;
40
41         graph = NULL;
42         graph_bump = NULL;
43
44         use_mis = true;
45         use_transparent_shadow = true;
46         heterogeneous_volume = true;
47
48         has_surface = false;
49         has_surface_transparent = false;
50         has_surface_emission = false;
51         has_surface_bssrdf = false;
52         has_converter_blackbody = false;
53         has_volume = false;
54         has_displacement = false;
55         has_bssrdf_bump = false;
56         has_heterogeneous_volume = false;
57
58         used = false;
59
60         need_update = true;
61         need_update_attributes = true;
62 }
63
64 Shader::~Shader()
65 {
66         delete graph;
67         delete graph_bump;
68 }
69
70 void Shader::set_graph(ShaderGraph *graph_)
71 {
72         /* do this here already so that we can detect if mesh or object attributes
73          * are needed, since the node attribute callbacks check if their sockets
74          * are connected but proxy nodes should not count */
75         if(graph_)
76                 graph_->remove_unneeded_nodes();
77
78         /* assign graph */
79         delete graph;
80         delete graph_bump;
81         graph = graph_;
82         graph_bump = NULL;
83 }
84
85 void Shader::tag_update(Scene *scene)
86 {
87         /* update tag */
88         need_update = true;
89         scene->shader_manager->need_update = true;
90
91         /* if the shader previously was emissive, update light distribution,
92          * if the new shader is emissive, a light manager update tag will be
93          * done in the shader manager device update. */
94         if(use_mis && has_surface_emission)
95                 scene->light_manager->need_update = true;
96
97         /* quick detection of which kind of shaders we have to avoid loading
98          * e.g. surface attributes when there is only a volume shader. this could
99          * be more fine grained but it's better than nothing */
100         OutputNode *output = graph->output();
101         has_surface = has_surface || output->input("Surface")->link;
102         has_volume = has_volume || output->input("Volume")->link;
103         has_displacement = has_displacement || output->input("Displacement")->link;
104
105         /* get requested attributes. this could be optimized by pruning unused
106          * nodes here already, but that's the job of the shader manager currently,
107          * and may not be so great for interactive rendering where you temporarily
108          * disconnect a node */
109
110         AttributeRequestSet prev_attributes = attributes;
111
112         attributes.clear();
113         foreach(ShaderNode *node, graph->nodes)
114                 node->attributes(this, &attributes);
115         
116         /* compare if the attributes changed, mesh manager will check
117          * need_update_attributes, update the relevant meshes and clear it. */
118         if(attributes.modified(prev_attributes)) {
119                 need_update_attributes = true;
120                 scene->mesh_manager->need_update = true;
121         }
122 }
123
124 void Shader::tag_used(Scene *scene)
125 {
126         /* if an unused shader suddenly gets used somewhere, it needs to be
127          * recompiled because it was skipped for compilation before */
128         if(!used) {
129                 need_update = true;
130                 scene->shader_manager->need_update = true;
131         }
132 }
133
134 /* Shader Manager */
135
136 ShaderManager::ShaderManager()
137 {
138         need_update = true;
139         blackbody_table_offset = TABLE_OFFSET_INVALID;
140 }
141
142 ShaderManager::~ShaderManager()
143 {
144 }
145
146 ShaderManager *ShaderManager::create(Scene *scene, int shadingsystem)
147 {
148         ShaderManager *manager;
149
150 #ifdef WITH_OSL
151         if(shadingsystem == SceneParams::OSL)
152                 manager = new OSLShaderManager();
153         else
154 #endif
155                 manager = new SVMShaderManager();
156         
157         add_default(scene);
158
159         return manager;
160 }
161
162 uint ShaderManager::get_attribute_id(ustring name)
163 {
164         /* get a unique id for each name, for SVM attribute lookup */
165         AttributeIDMap::iterator it = unique_attribute_id.find(name);
166
167         if(it != unique_attribute_id.end())
168                 return it->second;
169         
170         uint id = (uint)ATTR_STD_NUM + unique_attribute_id.size();
171         unique_attribute_id[name] = id;
172         return id;
173 }
174
175 uint ShaderManager::get_attribute_id(AttributeStandard std)
176 {
177         return (uint)std;
178 }
179
180 int ShaderManager::get_shader_id(uint shader, Mesh *mesh, bool smooth)
181 {
182         /* get a shader id to pass to the kernel */
183         int id = shader*2;
184         
185         /* index depends bump since this setting is not in the shader */
186         if(mesh && mesh->displacement_method != Mesh::DISPLACE_TRUE)
187                 id += 1;
188         /* smooth flag */
189         if(smooth)
190                 id |= SHADER_SMOOTH_NORMAL;
191         
192         /* default flags */
193         id |= SHADER_CAST_SHADOW|SHADER_AREA_LIGHT;
194         
195         return id;
196 }
197
198 void ShaderManager::device_update_shaders_used(Scene *scene)
199 {
200         /* figure out which shaders are in use, so SVM/OSL can skip compiling them
201          * for speed and avoid loading image textures into memory */
202         foreach(Shader *shader, scene->shaders)
203                 shader->used = false;
204
205         scene->shaders[scene->background->shader]->used = true;
206         scene->shaders[scene->default_surface]->used = true;
207         scene->shaders[scene->default_light]->used = true;
208         scene->shaders[scene->default_background]->used = true;
209         scene->shaders[scene->default_empty]->used = true;
210
211         foreach(Mesh *mesh, scene->meshes)
212                 foreach(uint shader, mesh->used_shaders)
213                         scene->shaders[shader]->used = true;
214
215         foreach(Light *light, scene->lights)
216                 scene->shaders[light->shader]->used = true;
217 }
218
219 void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
220 {
221         device->tex_free(dscene->shader_flag);
222         dscene->shader_flag.clear();
223
224         if(scene->shaders.size() == 0)
225                 return;
226
227         uint shader_flag_size = scene->shaders.size()*4;
228         uint *shader_flag = dscene->shader_flag.resize(shader_flag_size);
229         uint i = 0;
230         bool has_converter_blackbody = false;
231         bool has_volumes = false;
232
233         foreach(Shader *shader, scene->shaders) {
234                 uint flag = 0;
235
236                 if(shader->use_mis)
237                         flag |= SD_USE_MIS;
238                 if(shader->has_surface_transparent && shader->use_transparent_shadow)
239                         flag |= SD_HAS_TRANSPARENT_SHADOW;
240                 if(shader->has_volume) {
241                         flag |= SD_HAS_VOLUME;
242                         has_volumes = true;
243
244                         /* in this case we can assume transparent surface */
245                         if(!shader->has_surface)
246                                 flag |= SD_HAS_ONLY_VOLUME;
247
248                         /* todo: this could check more fine grained, to skip useless volumes
249                          * enclosed inside an opaque bsdf, although we still need to handle
250                          * the case with camera inside volumes too */
251                         flag |= SD_HAS_TRANSPARENT_SHADOW;
252                 }
253                 if(shader->heterogeneous_volume && shader->has_heterogeneous_volume)
254                         flag |= SD_HETEROGENEOUS_VOLUME;
255                 if(shader->has_bssrdf_bump)
256                         flag |= SD_HAS_BSSRDF_BUMP;
257                 if(shader->has_converter_blackbody)
258                         has_converter_blackbody = true;
259
260                 /* regular shader */
261                 shader_flag[i++] = flag;
262                 shader_flag[i++] = shader->pass_id;
263
264                 /* shader with bump mapping */
265                 if(shader->graph_bump)
266                         flag |= SD_HAS_BSSRDF_BUMP;
267
268                 shader_flag[i++] = flag;
269                 shader_flag[i++] = shader->pass_id;
270         }
271
272         device->tex_alloc("__shader_flag", dscene->shader_flag);
273
274         /* blackbody lookup table */
275         KernelBlackbody *kblackbody = &dscene->data.blackbody;
276         
277         if(has_converter_blackbody && blackbody_table_offset == TABLE_OFFSET_INVALID) {
278                 vector<float> table = blackbody_table();
279                 blackbody_table_offset = scene->lookup_tables->add_table(dscene, table);
280                 
281                 kblackbody->table_offset = (int)blackbody_table_offset;
282         }
283         else if(!has_converter_blackbody && blackbody_table_offset != TABLE_OFFSET_INVALID) {
284                 scene->lookup_tables->remove_table(blackbody_table_offset);
285                 blackbody_table_offset = TABLE_OFFSET_INVALID;
286         }
287
288         /* volumes */
289         KernelIntegrator *kintegrator = &dscene->data.integrator;
290         kintegrator->use_volumes = has_volumes;
291 }
292
293 void ShaderManager::device_free_common(Device *device, DeviceScene *dscene, Scene *scene)
294 {
295         if(blackbody_table_offset != TABLE_OFFSET_INVALID) {
296                 scene->lookup_tables->remove_table(blackbody_table_offset);
297                 blackbody_table_offset = TABLE_OFFSET_INVALID;
298         }
299
300         device->tex_free(dscene->shader_flag);
301         dscene->shader_flag.clear();
302 }
303
304 void ShaderManager::add_default(Scene *scene)
305 {
306         Shader *shader;
307         ShaderGraph *graph;
308         ShaderNode *closure, *out;
309
310         /* default surface */
311         {
312                 graph = new ShaderGraph();
313
314                 closure = graph->add(new DiffuseBsdfNode());
315                 closure->input("Color")->value = make_float3(0.8f, 0.8f, 0.8f);
316                 out = graph->output();
317
318                 graph->connect(closure->output("BSDF"), out->input("Surface"));
319
320                 shader = new Shader();
321                 shader->name = "default_surface";
322                 shader->graph = graph;
323                 scene->shaders.push_back(shader);
324                 scene->default_surface = scene->shaders.size() - 1;
325         }
326
327         /* default light */
328         {
329                 graph = new ShaderGraph();
330
331                 closure = graph->add(new EmissionNode());
332                 closure->input("Color")->value = make_float3(0.8f, 0.8f, 0.8f);
333                 closure->input("Strength")->value.x = 0.0f;
334                 out = graph->output();
335
336                 graph->connect(closure->output("Emission"), out->input("Surface"));
337
338                 shader = new Shader();
339                 shader->name = "default_light";
340                 shader->graph = graph;
341                 scene->shaders.push_back(shader);
342                 scene->default_light = scene->shaders.size() - 1;
343         }
344
345         /* default background */
346         {
347                 graph = new ShaderGraph();
348
349                 shader = new Shader();
350                 shader->name = "default_background";
351                 shader->graph = graph;
352                 scene->shaders.push_back(shader);
353                 scene->default_background = scene->shaders.size() - 1;
354         }
355
356         /* default empty */
357         {
358                 graph = new ShaderGraph();
359
360                 shader = new Shader();
361                 shader->name = "default_empty";
362                 shader->graph = graph;
363                 scene->shaders.push_back(shader);
364                 scene->default_empty = scene->shaders.size() - 1;
365         }
366 }
367
368 CCL_NAMESPACE_END
369