~ubuntu-branches/ubuntu/saucy/blender/saucy-proposed

« back to all changes in this revision

Viewing changes to source/blender/compositor/operations/COM_OpenCLKernels.cl

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2013-03-06 12:08:47 UTC
  • mfrom: (1.5.1) (14.1.8 experimental)
  • Revision ID: package-import@ubuntu.com-20130306120847-frjfaryb2zrotwcg
Tags: 2.66a-1ubuntu1
* Resynchronize with Debian (LP: #1076930, #1089256, #1052743, #999024,
  #1122888, #1147084)
* debian/control:
  - Lower build-depends on libavcodec-dev since we're not
    doing the libav9 transition in Ubuntu yet

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 * Contributor: 
 
19
 *              Jeroen Bakker 
 
20
 *              Monique Dewanchand
 
21
 */
 
22
 
 
23
/// This file contains all opencl kernels for node-operation implementations 
 
24
 
 
25
// Global SAMPLERS
 
26
const sampler_t SAMPLER_NEAREST       = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;
 
27
const sampler_t SAMPLER_NEAREST_CLAMP = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;
 
28
 
 
29
__constant const int2 zero = {0,0};
 
30
 
 
31
// KERNEL --- BOKEH BLUR ---
 
32
__kernel void bokehBlurKernel(__read_only image2d_t boundingBox, __read_only image2d_t inputImage, 
 
33
                              __read_only image2d_t bokehImage, __write_only image2d_t output, 
 
34
                              int2 offsetInput, int2 offsetOutput, int radius, int step, int2 dimension, int2 offset) 
 
35
{
 
36
        int2 coords = {get_global_id(0), get_global_id(1)};
 
37
        coords += offset;
 
38
        float tempBoundingBox;
 
39
        float4 color = {0.0f,0.0f,0.0f,0.0f};
 
40
        float4 multiplyer = {0.0f,0.0f,0.0f,0.0f};
 
41
        float4 bokeh;
 
42
        const float radius2 = radius*2.0f;
 
43
        const int2 realCoordinate = coords + offsetOutput;
 
44
 
 
45
        tempBoundingBox = read_imagef(boundingBox, SAMPLER_NEAREST, coords).s0;
 
46
 
 
47
        if (tempBoundingBox > 0.0f && radius > 0 ) {
 
48
                const int2 bokehImageDim = get_image_dim(bokehImage);
 
49
                const int2 bokehImageCenter = bokehImageDim/2;
 
50
                const int2 minXY = max(realCoordinate - radius, zero);
 
51
                const int2 maxXY = min(realCoordinate + radius, dimension);
 
52
                int nx, ny;
 
53
                
 
54
                float2 uv;
 
55
                int2 inputXy;
 
56
                
 
57
                for (ny = minXY.y, inputXy.y = ny - offsetInput.y ; ny < maxXY.y ; ny += step, inputXy.y += step) {
 
58
                        uv.y = ((realCoordinate.y-ny)/radius2)*bokehImageDim.y+bokehImageCenter.y;
 
59
                        
 
60
                        for (nx = minXY.x, inputXy.x = nx - offsetInput.x; nx < maxXY.x ; nx += step, inputXy.x += step) {
 
61
                                uv.x = ((realCoordinate.x-nx)/radius2)*bokehImageDim.x+bokehImageCenter.x;
 
62
                                bokeh = read_imagef(bokehImage, SAMPLER_NEAREST, uv);
 
63
                                color += bokeh * read_imagef(inputImage, SAMPLER_NEAREST, inputXy);
 
64
                                multiplyer += bokeh;
 
65
                        }
 
66
                }
 
67
                color /= multiplyer;
 
68
                
 
69
        }
 
70
        else {
 
71
                int2 imageCoordinates = realCoordinate - offsetInput;
 
72
                color = read_imagef(inputImage, SAMPLER_NEAREST, imageCoordinates);
 
73
        }
 
74
        
 
75
        write_imagef(output, coords, color);
 
76
}
 
77
 
 
78
//KERNEL --- DEFOCUS /VARIABLESIZEBOKEHBLUR ---
 
79
__kernel void defocusKernel(__read_only image2d_t inputImage, __read_only image2d_t bokehImage, 
 
80
                                        __read_only image2d_t inputSize,
 
81
                                        __write_only image2d_t output, int2 offsetInput, int2 offsetOutput, 
 
82
                                        int step, int maxBlurScalar, float threshold, float scalar, int2 dimension, int2 offset) 
 
83
{
 
84
        float4 color = {1.0f, 0.0f, 0.0f, 1.0f};
 
85
        int2 coords = {get_global_id(0), get_global_id(1)};
 
86
        coords += offset;
 
87
        const int2 realCoordinate = coords + offsetOutput;
 
88
 
 
89
        float4 readColor;
 
90
        float4 tempColor;
 
91
        float4 bokeh;
 
92
        float size;
 
93
        float4 multiplier_accum = {1.0f, 1.0f, 1.0f, 1.0f};
 
94
        float4 color_accum;
 
95
        
 
96
        int minx = max(realCoordinate.s0 - maxBlurScalar, 0);
 
97
        int miny = max(realCoordinate.s1 - maxBlurScalar, 0);
 
98
        int maxx = min(realCoordinate.s0 + maxBlurScalar, dimension.s0);
 
99
        int maxy = min(realCoordinate.s1 + maxBlurScalar, dimension.s1);
 
100
        
 
101
        {
 
102
                int2 inputCoordinate = realCoordinate - offsetInput;
 
103
                float size_center = read_imagef(inputSize, SAMPLER_NEAREST, inputCoordinate).s0 * scalar;
 
104
                color_accum = read_imagef(inputImage, SAMPLER_NEAREST, inputCoordinate);
 
105
                readColor = color_accum;
 
106
 
 
107
                if (size_center > threshold) {
 
108
                        for (int ny = miny; ny < maxy; ny += step) {
 
109
                                inputCoordinate.s1 = ny - offsetInput.s1;
 
110
                                float dy = ny - realCoordinate.s1;
 
111
                                for (int nx = minx; nx < maxx; nx += step) {
 
112
                                        float dx = nx - realCoordinate.s0;
 
113
                                        if (dx != 0 || dy != 0) {
 
114
                                                inputCoordinate.s0 = nx - offsetInput.s0;
 
115
                                                size = read_imagef(inputSize, SAMPLER_NEAREST, inputCoordinate).s0 * scalar;
 
116
                                                if (size > threshold) {
 
117
                                                        if (size >= fabs(dx) && size >= fabs(dy)) {
 
118
                                                                float2 uv = {256.0f + dx * 255.0f / size,
 
119
                                                                             256.0f + dy * 255.0f / size};
 
120
                                                                bokeh = read_imagef(bokehImage, SAMPLER_NEAREST, uv);
 
121
                                                                tempColor = read_imagef(inputImage, SAMPLER_NEAREST, inputCoordinate);
 
122
                                                                color_accum += bokeh * tempColor;
 
123
                                                                multiplier_accum += bokeh;
 
124
                                                        }
 
125
                                                }
 
126
                                        }
 
127
                                }
 
128
                        }
 
129
                }
 
130
 
 
131
                color = color_accum * (1.0f / multiplier_accum);
 
132
                
 
133
                /* blend in out values over the threshold, otherwise we get sharp, ugly transitions */
 
134
                if ((size_center > threshold) &&
 
135
                    (size_center < threshold * 2.0f))
 
136
                {
 
137
                        /* factor from 0-1 */
 
138
                        float fac = (size_center - threshold) / threshold;
 
139
                        color = (readColor * (1.0f - fac)) +  (color * fac);
 
140
                }
 
141
                
 
142
                write_imagef(output, coords, color);
 
143
        }
 
144
}
 
145
 
 
146
 
 
147
// KERNEL --- DILATE ---
 
148
__kernel void dilateKernel(__read_only image2d_t inputImage,  __write_only image2d_t output,
 
149
                           int2 offsetInput, int2 offsetOutput, int scope, int distanceSquared, int2 dimension, 
 
150
                           int2 offset)
 
151
{
 
152
        int2 coords = {get_global_id(0), get_global_id(1)};
 
153
        coords += offset;
 
154
        const int2 realCoordinate = coords + offsetOutput;
 
155
 
 
156
        const int2 minXY = max(realCoordinate - scope, zero);
 
157
        const int2 maxXY = min(realCoordinate + scope, dimension);
 
158
        
 
159
        float value = 0.0f;
 
160
        int nx, ny;
 
161
        int2 inputXy;
 
162
        
 
163
        for (ny = minXY.y, inputXy.y = ny - offsetInput.y ; ny < maxXY.y ; ny ++, inputXy.y++) {
 
164
                const float deltaY = (realCoordinate.y - ny);
 
165
                for (nx = minXY.x, inputXy.x = nx - offsetInput.x; nx < maxXY.x ; nx ++, inputXy.x++) {
 
166
                        const float deltaX = (realCoordinate.x - nx);
 
167
                        const float measuredDistance = deltaX * deltaX + deltaY * deltaY;
 
168
                        if (measuredDistance <= distanceSquared) {
 
169
                                value = max(value, read_imagef(inputImage, SAMPLER_NEAREST, inputXy).s0);
 
170
                        }
 
171
                }
 
172
        }
 
173
 
 
174
        float4 color = {value,0.0f,0.0f,0.0f};
 
175
        write_imagef(output, coords, color);
 
176
}
 
177
 
 
178
// KERNEL --- DILATE ---
 
179
__kernel void erodeKernel(__read_only image2d_t inputImage,  __write_only image2d_t output,
 
180
                           int2 offsetInput, int2 offsetOutput, int scope, int distanceSquared, int2 dimension, 
 
181
                           int2 offset)
 
182
{
 
183
        int2 coords = {get_global_id(0), get_global_id(1)};
 
184
        coords += offset;
 
185
        const int2 realCoordinate = coords + offsetOutput;
 
186
 
 
187
        const int2 minXY = max(realCoordinate - scope, zero);
 
188
        const int2 maxXY = min(realCoordinate + scope, dimension);
 
189
        
 
190
        float value = 1.0f;
 
191
        int nx, ny;
 
192
        int2 inputXy;
 
193
        
 
194
        for (ny = minXY.y, inputXy.y = ny - offsetInput.y ; ny < maxXY.y ; ny ++, inputXy.y++) {
 
195
                for (nx = minXY.x, inputXy.x = nx - offsetInput.x; nx < maxXY.x ; nx ++, inputXy.x++) {
 
196
                        const float deltaX = (realCoordinate.x - nx);
 
197
                        const float deltaY = (realCoordinate.y - ny);
 
198
                        const float measuredDistance = deltaX * deltaX+deltaY * deltaY;
 
199
                        if (measuredDistance <= distanceSquared) {
 
200
                                value = min(value, read_imagef(inputImage, SAMPLER_NEAREST, inputXy).s0);
 
201
                        }
 
202
                }
 
203
        }
 
204
 
 
205
        float4 color = {value,0.0f,0.0f,0.0f};
 
206
        write_imagef(output, coords, color);
 
207
}
 
208
 
 
209
// KERNEL --- DIRECTIONAL BLUR ---
 
210
__kernel void directionalBlurKernel(__read_only image2d_t inputImage,  __write_only image2d_t output,
 
211
                           int2 offsetOutput, int iterations, float scale, float rotation, float2 translate,
 
212
                           float2 center, int2 offset)
 
213
{
 
214
        int2 coords = {get_global_id(0), get_global_id(1)};
 
215
        coords += offset;
 
216
        const int2 realCoordinate = coords + offsetOutput;
 
217
 
 
218
        float4 col;
 
219
        float2 ltxy = translate;
 
220
        float lsc = scale;
 
221
        float lrot = rotation;
 
222
        
 
223
        col = read_imagef(inputImage, SAMPLER_NEAREST, realCoordinate);
 
224
 
 
225
        /* blur the image */
 
226
        for (int i = 0; i < iterations; ++i) {
 
227
                const float cs = cos(lrot), ss = sin(lrot);
 
228
                const float isc = 1.0f / (1.0f + lsc);
 
229
 
 
230
                const float v = isc * (realCoordinate.s1 - center.s1) + ltxy.s1;
 
231
                const float u = isc * (realCoordinate.s0 - center.s0) + ltxy.s0;
 
232
                float2 uv = {
 
233
                        cs * u + ss * v + center.s0,
 
234
                        cs * v - ss * u + center.s1
 
235
                };
 
236
 
 
237
                col += read_imagef(inputImage, SAMPLER_NEAREST_CLAMP, uv);
 
238
 
 
239
                /* double transformations */
 
240
                ltxy += translate;
 
241
                lrot += rotation;
 
242
                lsc += scale;
 
243
        }
 
244
 
 
245
        col *= (1.0f/(iterations+1));
 
246
 
 
247
        write_imagef(output, coords, col);
 
248
}