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