3ed96732b1445c64476896b128d6da9d684bbfdf
[blender-staging.git] / intern / cycles / render / background.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 "render/background.h"
18 #include "device/device.h"
19 #include "render/integrator.h"
20 #include "render/graph.h"
21 #include "render/nodes.h"
22 #include "render/scene.h"
23 #include "render/shader.h"
24
25 #include "util/util_foreach.h"
26 #include "util/util_math.h"
27 #include "util/util_types.h"
28
29 CCL_NAMESPACE_BEGIN
30
31 NODE_DEFINE(Background)
32 {
33         NodeType* type = NodeType::add("background", create);
34
35         SOCKET_FLOAT(ao_factor, "AO Factor", 0.0f);
36         SOCKET_FLOAT(ao_distance, "AO Distance", FLT_MAX);
37
38         SOCKET_BOOLEAN(use_shader, "Use Shader", true);
39         SOCKET_BOOLEAN(use_ao, "Use AO", false);
40         SOCKET_UINT(visibility, "Visibility", PATH_RAY_ALL_VISIBILITY);
41         SOCKET_BOOLEAN(transparent, "Transparent", false);
42
43         SOCKET_NODE(shader, "Shader", &Shader::node_type);
44
45         return type;
46 }
47
48 Background::Background()
49 : Node(node_type)
50 {
51         need_update = true;
52 }
53
54 Background::~Background()
55 {
56 }
57
58 void Background::device_update(Device *device, DeviceScene *dscene, Scene *scene)
59 {
60         if(!need_update)
61                 return;
62         
63         device_free(device, dscene);
64
65         Shader *bg_shader = shader;
66
67         if(use_shader) {
68                 if(!bg_shader)
69                         bg_shader = scene->default_background;
70         }
71         else
72                 bg_shader = scene->default_empty;
73
74         /* set shader index and transparent option */
75         KernelBackground *kbackground = &dscene->data.background;
76
77         kbackground->ao_factor = (use_ao)? ao_factor: 0.0f;
78         kbackground->ao_bounces_factor = ao_factor;
79         kbackground->ao_distance = ao_distance;
80
81         kbackground->transparent = transparent;
82         kbackground->surface_shader = scene->shader_manager->get_shader_id(bg_shader);
83
84         if(bg_shader->has_volume)
85                 kbackground->volume_shader = kbackground->surface_shader;
86         else
87                 kbackground->volume_shader = SHADER_NONE;
88
89         /* No background node, make world shader invisible to all rays, to skip evaluation in kernel. */
90         if(bg_shader->graph->nodes.size() <= 1) {
91                 kbackground->surface_shader |= SHADER_EXCLUDE_ANY;
92         }
93         /* Background present, check visibilities */
94         else {
95                 if(!(visibility & PATH_RAY_DIFFUSE))
96                         kbackground->surface_shader |= SHADER_EXCLUDE_DIFFUSE;
97                 if(!(visibility & PATH_RAY_GLOSSY))
98                         kbackground->surface_shader |= SHADER_EXCLUDE_GLOSSY;
99                 if(!(visibility & PATH_RAY_TRANSMIT))
100                         kbackground->surface_shader |= SHADER_EXCLUDE_TRANSMIT;
101                 if(!(visibility & PATH_RAY_VOLUME_SCATTER))
102                         kbackground->surface_shader |= SHADER_EXCLUDE_SCATTER;
103                 if(!(visibility & PATH_RAY_CAMERA))
104                         kbackground->surface_shader |= SHADER_EXCLUDE_CAMERA;
105         }
106
107         need_update = false;
108 }
109
110 void Background::device_free(Device * /*device*/, DeviceScene * /*dscene*/)
111 {
112 }
113
114 bool Background::modified(const Background& background)
115 {
116         return !Node::equals(background);
117 }
118
119 void Background::tag_update(Scene *scene)
120 {
121         scene->integrator->tag_update(scene);
122         need_update = true;
123 }
124
125 CCL_NAMESPACE_END
126