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
svm_mix_blend(float t,float3 col1,float3 col2)19 ccl_device float3 svm_mix_blend(float t, float3 col1, float3 col2)
20 {
21 return interp(col1, col2, t);
22 }
23
svm_mix_add(float t,float3 col1,float3 col2)24 ccl_device float3 svm_mix_add(float t, float3 col1, float3 col2)
25 {
26 return interp(col1, col1 + col2, t);
27 }
28
svm_mix_mul(float t,float3 col1,float3 col2)29 ccl_device float3 svm_mix_mul(float t, float3 col1, float3 col2)
30 {
31 return interp(col1, col1 * col2, t);
32 }
33
svm_mix_screen(float t,float3 col1,float3 col2)34 ccl_device float3 svm_mix_screen(float t, float3 col1, float3 col2)
35 {
36 float tm = 1.0f - t;
37 float3 one = make_float3(1.0f, 1.0f, 1.0f);
38 float3 tm3 = make_float3(tm, tm, tm);
39
40 return one - (tm3 + t * (one - col2)) * (one - col1);
41 }
42
svm_mix_overlay(float t,float3 col1,float3 col2)43 ccl_device float3 svm_mix_overlay(float t, float3 col1, float3 col2)
44 {
45 float tm = 1.0f - t;
46
47 float3 outcol = col1;
48
49 if (outcol.x < 0.5f)
50 outcol.x *= tm + 2.0f * t * col2.x;
51 else
52 outcol.x = 1.0f - (tm + 2.0f * t * (1.0f - col2.x)) * (1.0f - outcol.x);
53
54 if (outcol.y < 0.5f)
55 outcol.y *= tm + 2.0f * t * col2.y;
56 else
57 outcol.y = 1.0f - (tm + 2.0f * t * (1.0f - col2.y)) * (1.0f - outcol.y);
58
59 if (outcol.z < 0.5f)
60 outcol.z *= tm + 2.0f * t * col2.z;
61 else
62 outcol.z = 1.0f - (tm + 2.0f * t * (1.0f - col2.z)) * (1.0f - outcol.z);
63
64 return outcol;
65 }
66
svm_mix_sub(float t,float3 col1,float3 col2)67 ccl_device float3 svm_mix_sub(float t, float3 col1, float3 col2)
68 {
69 return interp(col1, col1 - col2, t);
70 }
71
svm_mix_div(float t,float3 col1,float3 col2)72 ccl_device float3 svm_mix_div(float t, float3 col1, float3 col2)
73 {
74 float tm = 1.0f - t;
75
76 float3 outcol = col1;
77
78 if (col2.x != 0.0f)
79 outcol.x = tm * outcol.x + t * outcol.x / col2.x;
80 if (col2.y != 0.0f)
81 outcol.y = tm * outcol.y + t * outcol.y / col2.y;
82 if (col2.z != 0.0f)
83 outcol.z = tm * outcol.z + t * outcol.z / col2.z;
84
85 return outcol;
86 }
87
svm_mix_diff(float t,float3 col1,float3 col2)88 ccl_device float3 svm_mix_diff(float t, float3 col1, float3 col2)
89 {
90 return interp(col1, fabs(col1 - col2), t);
91 }
92
svm_mix_dark(float t,float3 col1,float3 col2)93 ccl_device float3 svm_mix_dark(float t, float3 col1, float3 col2)
94 {
95 return interp(col1, min(col1, col2), t);
96 }
97
svm_mix_light(float t,float3 col1,float3 col2)98 ccl_device float3 svm_mix_light(float t, float3 col1, float3 col2)
99 {
100 return interp(col1, max(col1, col2), t);
101 }
102
svm_mix_dodge(float t,float3 col1,float3 col2)103 ccl_device float3 svm_mix_dodge(float t, float3 col1, float3 col2)
104 {
105 float3 outcol = col1;
106
107 if (outcol.x != 0.0f) {
108 float tmp = 1.0f - t * col2.x;
109 if (tmp <= 0.0f)
110 outcol.x = 1.0f;
111 else if ((tmp = outcol.x / tmp) > 1.0f)
112 outcol.x = 1.0f;
113 else
114 outcol.x = tmp;
115 }
116 if (outcol.y != 0.0f) {
117 float tmp = 1.0f - t * col2.y;
118 if (tmp <= 0.0f)
119 outcol.y = 1.0f;
120 else if ((tmp = outcol.y / tmp) > 1.0f)
121 outcol.y = 1.0f;
122 else
123 outcol.y = tmp;
124 }
125 if (outcol.z != 0.0f) {
126 float tmp = 1.0f - t * col2.z;
127 if (tmp <= 0.0f)
128 outcol.z = 1.0f;
129 else if ((tmp = outcol.z / tmp) > 1.0f)
130 outcol.z = 1.0f;
131 else
132 outcol.z = tmp;
133 }
134
135 return outcol;
136 }
137
svm_mix_burn(float t,float3 col1,float3 col2)138 ccl_device float3 svm_mix_burn(float t, float3 col1, float3 col2)
139 {
140 float tmp, tm = 1.0f - t;
141
142 float3 outcol = col1;
143
144 tmp = tm + t * col2.x;
145 if (tmp <= 0.0f)
146 outcol.x = 0.0f;
147 else if ((tmp = (1.0f - (1.0f - outcol.x) / tmp)) < 0.0f)
148 outcol.x = 0.0f;
149 else if (tmp > 1.0f)
150 outcol.x = 1.0f;
151 else
152 outcol.x = tmp;
153
154 tmp = tm + t * col2.y;
155 if (tmp <= 0.0f)
156 outcol.y = 0.0f;
157 else if ((tmp = (1.0f - (1.0f - outcol.y) / tmp)) < 0.0f)
158 outcol.y = 0.0f;
159 else if (tmp > 1.0f)
160 outcol.y = 1.0f;
161 else
162 outcol.y = tmp;
163
164 tmp = tm + t * col2.z;
165 if (tmp <= 0.0f)
166 outcol.z = 0.0f;
167 else if ((tmp = (1.0f - (1.0f - outcol.z) / tmp)) < 0.0f)
168 outcol.z = 0.0f;
169 else if (tmp > 1.0f)
170 outcol.z = 1.0f;
171 else
172 outcol.z = tmp;
173
174 return outcol;
175 }
176
svm_mix_hue(float t,float3 col1,float3 col2)177 ccl_device float3 svm_mix_hue(float t, float3 col1, float3 col2)
178 {
179 float3 outcol = col1;
180
181 float3 hsv2 = rgb_to_hsv(col2);
182
183 if (hsv2.y != 0.0f) {
184 float3 hsv = rgb_to_hsv(outcol);
185 hsv.x = hsv2.x;
186 float3 tmp = hsv_to_rgb(hsv);
187
188 outcol = interp(outcol, tmp, t);
189 }
190
191 return outcol;
192 }
193
svm_mix_sat(float t,float3 col1,float3 col2)194 ccl_device float3 svm_mix_sat(float t, float3 col1, float3 col2)
195 {
196 float tm = 1.0f - t;
197
198 float3 outcol = col1;
199
200 float3 hsv = rgb_to_hsv(outcol);
201
202 if (hsv.y != 0.0f) {
203 float3 hsv2 = rgb_to_hsv(col2);
204
205 hsv.y = tm * hsv.y + t * hsv2.y;
206 outcol = hsv_to_rgb(hsv);
207 }
208
209 return outcol;
210 }
211
svm_mix_val(float t,float3 col1,float3 col2)212 ccl_device float3 svm_mix_val(float t, float3 col1, float3 col2)
213 {
214 float tm = 1.0f - t;
215
216 float3 hsv = rgb_to_hsv(col1);
217 float3 hsv2 = rgb_to_hsv(col2);
218
219 hsv.z = tm * hsv.z + t * hsv2.z;
220
221 return hsv_to_rgb(hsv);
222 }
223
svm_mix_color(float t,float3 col1,float3 col2)224 ccl_device float3 svm_mix_color(float t, float3 col1, float3 col2)
225 {
226 float3 outcol = col1;
227 float3 hsv2 = rgb_to_hsv(col2);
228
229 if (hsv2.y != 0.0f) {
230 float3 hsv = rgb_to_hsv(outcol);
231 hsv.x = hsv2.x;
232 hsv.y = hsv2.y;
233 float3 tmp = hsv_to_rgb(hsv);
234
235 outcol = interp(outcol, tmp, t);
236 }
237
238 return outcol;
239 }
240
svm_mix_soft(float t,float3 col1,float3 col2)241 ccl_device float3 svm_mix_soft(float t, float3 col1, float3 col2)
242 {
243 float tm = 1.0f - t;
244
245 float3 one = make_float3(1.0f, 1.0f, 1.0f);
246 float3 scr = one - (one - col2) * (one - col1);
247
248 return tm * col1 + t * ((one - col1) * col2 * col1 + col1 * scr);
249 }
250
svm_mix_linear(float t,float3 col1,float3 col2)251 ccl_device float3 svm_mix_linear(float t, float3 col1, float3 col2)
252 {
253 return col1 + t * (2.0f * col2 + make_float3(-1.0f, -1.0f, -1.0f));
254 }
255
svm_mix_clamp(float3 col)256 ccl_device float3 svm_mix_clamp(float3 col)
257 {
258 return saturate3(col);
259 }
260
svm_mix(NodeMix type,float fac,float3 c1,float3 c2)261 ccl_device_noinline_cpu float3 svm_mix(NodeMix type, float fac, float3 c1, float3 c2)
262 {
263 float t = saturate(fac);
264
265 switch (type) {
266 case NODE_MIX_BLEND:
267 return svm_mix_blend(t, c1, c2);
268 case NODE_MIX_ADD:
269 return svm_mix_add(t, c1, c2);
270 case NODE_MIX_MUL:
271 return svm_mix_mul(t, c1, c2);
272 case NODE_MIX_SCREEN:
273 return svm_mix_screen(t, c1, c2);
274 case NODE_MIX_OVERLAY:
275 return svm_mix_overlay(t, c1, c2);
276 case NODE_MIX_SUB:
277 return svm_mix_sub(t, c1, c2);
278 case NODE_MIX_DIV:
279 return svm_mix_div(t, c1, c2);
280 case NODE_MIX_DIFF:
281 return svm_mix_diff(t, c1, c2);
282 case NODE_MIX_DARK:
283 return svm_mix_dark(t, c1, c2);
284 case NODE_MIX_LIGHT:
285 return svm_mix_light(t, c1, c2);
286 case NODE_MIX_DODGE:
287 return svm_mix_dodge(t, c1, c2);
288 case NODE_MIX_BURN:
289 return svm_mix_burn(t, c1, c2);
290 case NODE_MIX_HUE:
291 return svm_mix_hue(t, c1, c2);
292 case NODE_MIX_SAT:
293 return svm_mix_sat(t, c1, c2);
294 case NODE_MIX_VAL:
295 return svm_mix_val(t, c1, c2);
296 case NODE_MIX_COLOR:
297 return svm_mix_color(t, c1, c2);
298 case NODE_MIX_SOFT:
299 return svm_mix_soft(t, c1, c2);
300 case NODE_MIX_LINEAR:
301 return svm_mix_linear(t, c1, c2);
302 case NODE_MIX_CLAMP:
303 return svm_mix_clamp(c1);
304 }
305
306 return make_float3(0.0f, 0.0f, 0.0f);
307 }
308
svm_brightness_contrast(float3 color,float brightness,float contrast)309 ccl_device_inline float3 svm_brightness_contrast(float3 color, float brightness, float contrast)
310 {
311 float a = 1.0f + contrast;
312 float b = brightness - contrast * 0.5f;
313
314 color.x = max(a * color.x + b, 0.0f);
315 color.y = max(a * color.y + b, 0.0f);
316 color.z = max(a * color.z + b, 0.0f);
317
318 return color;
319 }
320
321 CCL_NAMESPACE_END
322