Cycles: change __device and similar qualifiers to ccl_device in kernel code.
[blender.git] / intern / cycles / kernel / kernel_passes.h
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 CCL_NAMESPACE_BEGIN
18
19 ccl_device_inline void kernel_write_pass_float(ccl_global float *buffer, int sample, float value)
20 {
21         ccl_global float *buf = buffer;
22         *buf = (sample == 0)? value: *buf + value;
23 }
24
25 ccl_device_inline void kernel_write_pass_float3(ccl_global float *buffer, int sample, float3 value)
26 {
27         ccl_global float3 *buf = (ccl_global float3*)buffer;
28         *buf = (sample == 0)? value: *buf + value;
29 }
30
31 ccl_device_inline void kernel_write_pass_float4(ccl_global float *buffer, int sample, float4 value)
32 {
33         ccl_global float4 *buf = (ccl_global float4*)buffer;
34         *buf = (sample == 0)? value: *buf + value;
35 }
36
37 ccl_device_inline void kernel_write_data_passes(KernelGlobals *kg, ccl_global float *buffer, PathRadiance *L,
38         ShaderData *sd, int sample, int path_flag, float3 throughput)
39 {
40 #ifdef __PASSES__
41         if(!(path_flag & PATH_RAY_CAMERA))
42                 return;
43
44         int flag = kernel_data.film.pass_flag;
45
46         if(!(flag & PASS_ALL))
47                 return;
48         
49         /* todo: add alpha threshold */
50         if(!(path_flag & PATH_RAY_TRANSPARENT)) {
51                 if(sample == 0) {
52                         if(flag & PASS_DEPTH) {
53                                 float depth = camera_distance(kg, sd->P);
54                                 kernel_write_pass_float(buffer + kernel_data.film.pass_depth, sample, depth);
55                         }
56                         if(flag & PASS_OBJECT_ID) {
57                                 float id = object_pass_id(kg, sd->object);
58                                 kernel_write_pass_float(buffer + kernel_data.film.pass_object_id, sample, id);
59                         }
60                         if(flag & PASS_MATERIAL_ID) {
61                                 float id = shader_pass_id(kg, sd);
62                                 kernel_write_pass_float(buffer + kernel_data.film.pass_material_id, sample, id);
63                         }
64                 }
65
66                 if(flag & PASS_NORMAL) {
67                         float3 normal = sd->N;
68                         kernel_write_pass_float3(buffer + kernel_data.film.pass_normal, sample, normal);
69                 }
70                 if(flag & PASS_UV) {
71                         float3 uv = primitive_uv(kg, sd);
72                         kernel_write_pass_float3(buffer + kernel_data.film.pass_uv, sample, uv);
73                 }
74                 if(flag & PASS_MOTION) {
75                         float4 speed = primitive_motion_vector(kg, sd);
76                         kernel_write_pass_float4(buffer + kernel_data.film.pass_motion, sample, speed);
77                         kernel_write_pass_float(buffer + kernel_data.film.pass_motion_weight, sample, 1.0f);
78                 }
79         }
80
81         if(flag & (PASS_DIFFUSE_INDIRECT|PASS_DIFFUSE_COLOR|PASS_DIFFUSE_DIRECT))
82                 L->color_diffuse += shader_bsdf_diffuse(kg, sd)*throughput;
83         if(flag & (PASS_GLOSSY_INDIRECT|PASS_GLOSSY_COLOR|PASS_GLOSSY_DIRECT))
84                 L->color_glossy += shader_bsdf_glossy(kg, sd)*throughput;
85         if(flag & (PASS_TRANSMISSION_INDIRECT|PASS_TRANSMISSION_COLOR|PASS_TRANSMISSION_DIRECT))
86                 L->color_transmission += shader_bsdf_transmission(kg, sd)*throughput;
87         if(flag & (PASS_SUBSURFACE_INDIRECT|PASS_SUBSURFACE_COLOR|PASS_SUBSURFACE_DIRECT))
88                 L->color_subsurface += shader_bsdf_subsurface(kg, sd)*throughput;
89
90         if(flag & PASS_MIST) {
91                 /* bring depth into 0..1 range */
92                 float mist_start = kernel_data.film.mist_start;
93                 float mist_inv_depth = kernel_data.film.mist_inv_depth;
94
95                 float depth = camera_distance(kg, sd->P);
96                 float mist = clamp((depth - mist_start)*mist_inv_depth, 0.0f, 1.0f);
97
98                 /* falloff */
99                 float mist_falloff = kernel_data.film.mist_falloff;
100
101                 if(mist_falloff == 1.0f)
102                         ;
103                 else if(mist_falloff == 2.0f)
104                         mist = mist*mist;
105                 else if(mist_falloff == 0.5f)
106                         mist = sqrtf(mist);
107                 else
108                         mist = powf(mist, mist_falloff);
109
110                 /* modulate by transparency */
111                 float3 alpha = shader_bsdf_alpha(kg, sd);
112                 L->mist += (1.0f - mist)*average(throughput*alpha);
113         }
114 #endif
115 }
116
117 ccl_device_inline void kernel_write_light_passes(KernelGlobals *kg, ccl_global float *buffer, PathRadiance *L, int sample)
118 {
119 #ifdef __PASSES__
120         int flag = kernel_data.film.pass_flag;
121
122         if(!kernel_data.film.use_light_pass)
123                 return;
124         
125         if(flag & PASS_DIFFUSE_INDIRECT)
126                 kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_indirect, sample, L->indirect_diffuse);
127         if(flag & PASS_GLOSSY_INDIRECT)
128                 kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_indirect, sample, L->indirect_glossy);
129         if(flag & PASS_TRANSMISSION_INDIRECT)
130                 kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_indirect, sample, L->indirect_transmission);
131         if(flag & PASS_SUBSURFACE_INDIRECT)
132                 kernel_write_pass_float3(buffer + kernel_data.film.pass_subsurface_indirect, sample, L->indirect_subsurface);
133         if(flag & PASS_DIFFUSE_DIRECT)
134                 kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_direct, sample, L->direct_diffuse);
135         if(flag & PASS_GLOSSY_DIRECT)
136                 kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_direct, sample, L->direct_glossy);
137         if(flag & PASS_TRANSMISSION_DIRECT)
138                 kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_direct, sample, L->direct_transmission);
139         if(flag & PASS_SUBSURFACE_DIRECT)
140                 kernel_write_pass_float3(buffer + kernel_data.film.pass_subsurface_direct, sample, L->direct_subsurface);
141
142         if(flag & PASS_EMISSION)
143                 kernel_write_pass_float3(buffer + kernel_data.film.pass_emission, sample, L->emission);
144         if(flag & PASS_BACKGROUND)
145                 kernel_write_pass_float3(buffer + kernel_data.film.pass_background, sample, L->background);
146         if(flag & PASS_AO)
147                 kernel_write_pass_float3(buffer + kernel_data.film.pass_ao, sample, L->ao);
148
149         if(flag & PASS_DIFFUSE_COLOR)
150                 kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_color, sample, L->color_diffuse);
151         if(flag & PASS_GLOSSY_COLOR)
152                 kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_color, sample, L->color_glossy);
153         if(flag & PASS_TRANSMISSION_COLOR)
154                 kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_color, sample, L->color_transmission);
155         if(flag & PASS_SUBSURFACE_COLOR)
156                 kernel_write_pass_float3(buffer + kernel_data.film.pass_subsurface_color, sample, L->color_subsurface);
157         if(flag & PASS_SHADOW) {
158                 float4 shadow = L->shadow;
159                 shadow.w = kernel_data.film.pass_shadow_scale;
160                 kernel_write_pass_float4(buffer + kernel_data.film.pass_shadow, sample, shadow);
161         }
162         if(flag & PASS_MIST)
163                 kernel_write_pass_float(buffer + kernel_data.film.pass_mist, sample, 1.0f - L->mist);
164 #endif
165 }
166
167 CCL_NAMESPACE_END
168