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