Merge branch 'master' into blender2.8
[blender.git] / intern / cycles / kernel / svm / svm_gradient.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 /* Gradient */
20
21 ccl_device float svm_gradient(float3 p, NodeGradientType type)
22 {
23         float x, y, z;
24
25         x = p.x;
26         y = p.y;
27         z = p.z;
28
29         if(type == NODE_BLEND_LINEAR) {
30                 return x;
31         }
32         else if(type == NODE_BLEND_QUADRATIC) {
33                 float r = fmaxf(x, 0.0f);
34                 return r*r;
35         }
36         else if(type == NODE_BLEND_EASING) {
37                 float r = fminf(fmaxf(x, 0.0f), 1.0f);
38                 float t = r*r;
39                 
40                 return (3.0f*t - 2.0f*t*r);
41         }
42         else if(type == NODE_BLEND_DIAGONAL) {
43                 return (x + y) * 0.5f;
44         }
45         else if(type == NODE_BLEND_RADIAL) {
46                 return atan2f(y, x) / M_2PI_F + 0.5f;
47         }
48         else {
49                 /* Bias a little bit for the case where p is a unit length vector,
50                  * to get exactly zero instead of a small random value depending
51                  * on float precision. */
52                 float r = fmaxf(0.999999f - sqrtf(x*x + y*y + z*z), 0.0f);
53
54                 if(type == NODE_BLEND_QUADRATIC_SPHERE)
55                         return r*r;
56                 else if(type == NODE_BLEND_SPHERICAL)
57                         return r;
58         }
59
60         return 0.0f;
61 }
62
63 ccl_device void svm_node_tex_gradient(ShaderData *sd, float *stack, uint4 node)
64 {
65         uint type, co_offset, color_offset, fac_offset;
66
67         decode_node_uchar4(node.y, &type, &co_offset, &fac_offset, &color_offset);
68
69         float3 co = stack_load_float3(stack, co_offset);
70
71         float f = svm_gradient(co, (NodeGradientType)type);
72         f = saturate(f);
73
74         if(stack_valid(fac_offset))
75                 stack_store_float(stack, fac_offset, f);
76         if(stack_valid(color_offset))
77                 stack_store_float3(stack, color_offset, make_float3(f, f, f));
78 }
79
80 CCL_NAMESPACE_END
81