Cycles: fix AO pass not rendering with AO enabled for world, and make mask
[blender.git] / intern / cycles / render / film.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 "camera.h"
20 #include "device.h"
21 #include "film.h"
22 #include "integrator.h"
23 #include "scene.h"
24
25 #include "util_algorithm.h"
26 #include "util_foreach.h"
27
28 CCL_NAMESPACE_BEGIN
29
30 /* Pass */
31
32 static bool compare_pass_order(const Pass& a, const Pass& b)
33 {
34         if(a.components == b.components)
35                 return (a.type < b.type);
36         return (a.components > b.components);
37 }
38
39 void Pass::add(PassType type, vector<Pass>& passes)
40 {
41         Pass pass;
42
43         pass.type = type;
44         pass.filter = true;
45         pass.exposure = false;
46
47         switch(type) {
48                 case PASS_NONE:
49                         pass.components = 0;
50                         break;
51                 case PASS_COMBINED:
52                         pass.components = 4;
53                         pass.exposure = true;
54                         break;
55                 case PASS_DEPTH:
56                         pass.components = 1;
57                         pass.filter = false;
58                         break;
59                 case PASS_NORMAL:
60                         pass.components = 4;
61                         break;
62                 case PASS_UV:
63                         pass.components = 4;
64                         break;
65                 case PASS_OBJECT_ID:
66                         pass.components = 1;
67                         pass.filter = false;
68                         break;
69                 case PASS_MATERIAL_ID:
70                         pass.components = 1;
71                         pass.filter = false;
72                         break;
73                 case PASS_DIFFUSE_COLOR:
74                         pass.components = 4;
75                         break;
76                 case PASS_GLOSSY_COLOR:
77                         pass.components = 4;
78                         break;
79                 case PASS_TRANSMISSION_COLOR:
80                         pass.components = 4;
81                         break;
82                 case PASS_DIFFUSE_INDIRECT:
83                         pass.components = 4;
84                         pass.exposure = true;
85                         break;
86                 case PASS_GLOSSY_INDIRECT:
87                         pass.components = 4;
88                         pass.exposure = true;
89                         break;
90                 case PASS_TRANSMISSION_INDIRECT:
91                         pass.components = 4;
92                         pass.exposure = true;
93                         break;
94                 case PASS_DIFFUSE_DIRECT:
95                         pass.components = 4;
96                         pass.exposure = true;
97                         break;
98                 case PASS_GLOSSY_DIRECT:
99                         pass.components = 4;
100                         pass.exposure = true;
101                         break;
102                 case PASS_TRANSMISSION_DIRECT:
103                         pass.components = 4;
104                         pass.exposure = true;
105                         break;
106
107                 case PASS_EMISSION:
108                         pass.components = 4;
109                         pass.exposure = true;
110                         break;
111                 case PASS_BACKGROUND:
112                         pass.components = 4;
113                         pass.exposure = true;
114                         break;
115                 case PASS_AO:
116                         pass.components = 4;
117                         pass.exposure = true;
118                         break;
119         }
120
121         passes.push_back(pass);
122
123         /* order from by components, to ensure alignment so passes with size 4
124            come first and then passes with size 1 */
125         sort(passes.begin(), passes.end(), compare_pass_order);
126 }
127
128 bool Pass::equals(const vector<Pass>& A, const vector<Pass>& B)
129 {
130         if(A.size() != B.size())
131                 return false;
132         
133         for(int i = 0; i < A.size(); i++)
134                 if(A[i].type != B[i].type)
135                         return false;
136         
137         return true;
138 }
139
140 /* Film */
141
142 Film::Film()
143 {
144         exposure = 0.8f;
145         Pass::add(PASS_COMBINED, passes);
146         need_update = true;
147 }
148
149 Film::~Film()
150 {
151 }
152
153 void Film::device_update(Device *device, DeviceScene *dscene)
154 {
155         if(!need_update)
156                 return;
157
158         KernelFilm *kfilm = &dscene->data.film;
159
160         /* update __data */
161         kfilm->exposure = exposure;
162         kfilm->pass_flag = 0;
163         kfilm->pass_stride = 0;
164         kfilm->use_light_pass = 0;
165
166         foreach(Pass& pass, passes) {
167                 kfilm->pass_flag |= pass.type;
168
169                 switch(pass.type) {
170                         case PASS_COMBINED:
171                                 kfilm->pass_combined = kfilm->pass_stride;
172                                 break;
173                         case PASS_DEPTH:
174                                 kfilm->pass_depth = kfilm->pass_stride;
175                                 break;
176                         case PASS_NORMAL:
177                                 kfilm->pass_normal = kfilm->pass_stride;
178                                 break;
179                         case PASS_UV:
180                                 kfilm->pass_uv = kfilm->pass_stride;
181                                 break;
182                         case PASS_OBJECT_ID:
183                                 kfilm->pass_object_id = kfilm->pass_stride;
184                                 break;
185                         case PASS_MATERIAL_ID:
186                                 kfilm->pass_material_id = kfilm->pass_stride;
187                                 break;
188                         case PASS_DIFFUSE_COLOR:
189                                 kfilm->pass_diffuse_color = kfilm->pass_stride;
190                                 kfilm->use_light_pass = 1;
191                                 break;
192                         case PASS_GLOSSY_COLOR:
193                                 kfilm->pass_glossy_color = kfilm->pass_stride;
194                                 kfilm->use_light_pass = 1;
195                                 break;
196                         case PASS_TRANSMISSION_COLOR:
197                                 kfilm->pass_transmission_color = kfilm->pass_stride;
198                                 kfilm->use_light_pass = 1;
199                                 break;
200                         case PASS_DIFFUSE_INDIRECT:
201                                 kfilm->pass_diffuse_indirect = kfilm->pass_stride;
202                                 kfilm->use_light_pass = 1;
203                                 break;
204                         case PASS_GLOSSY_INDIRECT:
205                                 kfilm->pass_glossy_indirect = kfilm->pass_stride;
206                                 kfilm->use_light_pass = 1;
207                                 break;
208                         case PASS_TRANSMISSION_INDIRECT:
209                                 kfilm->pass_transmission_indirect = kfilm->pass_stride;
210                                 kfilm->use_light_pass = 1;
211                                 break;
212                         case PASS_DIFFUSE_DIRECT:
213                                 kfilm->pass_diffuse_direct = kfilm->pass_stride;
214                                 kfilm->use_light_pass = 1;
215                                 break;
216                         case PASS_GLOSSY_DIRECT:
217                                 kfilm->pass_glossy_direct = kfilm->pass_stride;
218                                 kfilm->use_light_pass = 1;
219                                 break;
220                         case PASS_TRANSMISSION_DIRECT:
221                                 kfilm->pass_transmission_direct = kfilm->pass_stride;
222                                 kfilm->use_light_pass = 1;
223                                 break;
224
225                         case PASS_EMISSION:
226                                 kfilm->pass_emission = kfilm->pass_stride;
227                                 kfilm->use_light_pass = 1;
228                                 break;
229                         case PASS_BACKGROUND:
230                                 kfilm->pass_background = kfilm->pass_stride;
231                                 kfilm->use_light_pass = 1;
232                         case PASS_AO:
233                                 kfilm->pass_ao = kfilm->pass_stride;
234                                 kfilm->use_light_pass = 1;
235                         case PASS_NONE:
236                                 break;
237                 }
238
239                 kfilm->pass_stride += pass.components;
240         }
241
242         kfilm->pass_stride = align_up(kfilm->pass_stride, 4);
243
244         need_update = false;
245 }
246
247 void Film::device_free(Device *device, DeviceScene *dscene)
248 {
249 }
250
251 bool Film::modified(const Film& film)
252 {
253         return !(exposure == film.exposure
254                 && Pass::equals(passes, film.passes));
255 }
256
257 void Film::tag_update(Scene *scene)
258 {
259         scene->integrator->tag_update(scene);
260         need_update = true;
261 }
262
263 CCL_NAMESPACE_END
264