Integer socket support in Cycles. Int values are already supported natively in OSL...
[blender.git] / intern / cycles / kernel / svm / svm_tex_coord.h
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 CCL_NAMESPACE_BEGIN
20
21 /* Texture Coordinate Node */
22
23 __device_inline float3 svm_background_offset(KernelGlobals *kg)
24 {
25         Transform cameratoworld = kernel_data.cam.cameratoworld;
26         return make_float3(cameratoworld.x.w, cameratoworld.y.w, cameratoworld.z.w);
27 }
28
29 __device_inline float3 svm_world_to_ndc(KernelGlobals *kg, ShaderData *sd, float3 P)
30 {
31         if(kernel_data.cam.type != CAMERA_PANORAMA) {
32                 if(sd->object == ~0)
33                         P += svm_background_offset(kg);
34
35                 Transform tfm = kernel_data.cam.worldtondc;
36                 return transform_perspective(&tfm, P);
37         }
38         else {
39                 Transform tfm = kernel_data.cam.worldtocamera;
40
41                 if(sd->object != ~0)
42                         P = normalize(transform_point(&tfm, P));
43                 else
44                         P = normalize(transform_direction(&tfm, P));
45
46                 float2 uv = direction_to_panorama(kg, P);
47
48                 return make_float3(uv.x, uv.y, 0.0f);
49         }
50 }
51
52 __device void svm_node_tex_coord(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
53 {
54         float3 data;
55
56         switch(type) {
57                 case NODE_TEXCO_OBJECT: {
58                         if(sd->object != ~0) {
59                                 data = sd->P;
60                                 object_inverse_position_transform(kg, sd, &data);
61                         }
62                         else
63                                 data = sd->P;
64                         break;
65                 }
66                 case NODE_TEXCO_NORMAL: {
67                         if(sd->object != ~0) {
68                                 data = sd->N;
69                                 object_inverse_normal_transform(kg, sd, &data);
70                         }
71                         else
72                                 data = sd->N;
73                         break;
74                 }
75                 case NODE_TEXCO_CAMERA: {
76                         Transform tfm = kernel_data.cam.worldtocamera;
77
78                         if(sd->object != ~0)
79                                 data = transform_point(&tfm, sd->P);
80                         else
81                                 data = transform_point(&tfm, sd->P + svm_background_offset(kg));
82                         break;
83                 }
84                 case NODE_TEXCO_WINDOW: {
85                         data = svm_world_to_ndc(kg, sd, sd->P);
86                         break;
87                 }
88                 case NODE_TEXCO_REFLECTION: {
89                         if(sd->object != ~0)
90                                 data = 2.0f*dot(sd->N, sd->I)*sd->N - sd->I;
91                         else
92                                 data = sd->I;
93                         break;
94                 }
95                 case NODE_TEXCO_DUPLI_GENERATED: {
96                         data = object_dupli_generated(kg, sd->object);
97                         break;
98                 }
99                 case NODE_TEXCO_DUPLI_UV: {
100                         data = object_dupli_uv(kg, sd->object);
101                         break;
102                 }
103         }
104
105         stack_store_float3(stack, out_offset, data);
106 }
107
108 __device void svm_node_tex_coord_bump_dx(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
109 {
110 #ifdef __RAY_DIFFERENTIALS__
111         float3 data;
112
113         switch(type) {
114                 case NODE_TEXCO_OBJECT: {
115                         if(sd->object != ~0) {
116                                 data = sd->P + sd->dP.dx;
117                                 object_inverse_position_transform(kg, sd, &data);
118                         }
119                         else
120                                 data = sd->P + sd->dP.dx;
121                         break;
122                 }
123                 case NODE_TEXCO_NORMAL: {
124                         if(sd->object != ~0) {
125                                 data = sd->N;
126                                 object_inverse_normal_transform(kg, sd, &data);
127                         }
128                         else
129                                 data = sd->N;
130                         break;
131                 }
132                 case NODE_TEXCO_CAMERA: {
133                         Transform tfm = kernel_data.cam.worldtocamera;
134
135                         if(sd->object != ~0)
136                                 data = transform_point(&tfm, sd->P + sd->dP.dx);
137                         else
138                                 data = transform_point(&tfm, sd->P + sd->dP.dx + svm_background_offset(kg));
139                         break;
140                 }
141                 case NODE_TEXCO_WINDOW: {
142                         data = svm_world_to_ndc(kg, sd, sd->P + sd->dP.dx);
143                         break;
144                 }
145                 case NODE_TEXCO_REFLECTION: {
146                         if(sd->object != ~0)
147                                 data = 2.0f*dot(sd->N, sd->I)*sd->N - sd->I;
148                         else
149                                 data = sd->I;
150                         break;
151                 }
152                 case NODE_TEXCO_DUPLI_GENERATED: {
153                         data = object_dupli_generated(kg, sd->object);
154                         break;
155                 }
156                 case NODE_TEXCO_DUPLI_UV: {
157                         data = object_dupli_uv(kg, sd->object);
158                         break;
159                 }
160         }
161
162         stack_store_float3(stack, out_offset, data);
163 #else
164         svm_node_tex_coord(kg, sd, stack, type, out_offset);
165 #endif
166 }
167
168 __device void svm_node_tex_coord_bump_dy(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
169 {
170 #ifdef __RAY_DIFFERENTIALS__
171         float3 data;
172
173         switch(type) {
174                 case NODE_TEXCO_OBJECT: {
175                         if(sd->object != ~0) {
176                                 data = sd->P + sd->dP.dy;
177                                 object_inverse_position_transform(kg, sd, &data);
178                         }
179                         else
180                                 data = sd->P + sd->dP.dy;
181                         break;
182                 }
183                 case NODE_TEXCO_NORMAL: {
184                         if(sd->object != ~0) {
185                                 data = sd->N;
186                                 object_inverse_normal_transform(kg, sd, &data);
187                         }
188                         else
189                                 data = sd->N;
190                         break;
191                 }
192                 case NODE_TEXCO_CAMERA: {
193                         Transform tfm = kernel_data.cam.worldtocamera;
194
195                         if(sd->object != ~0)
196                                 data = transform_point(&tfm, sd->P + sd->dP.dy);
197                         else
198                                 data = transform_point(&tfm, sd->P + sd->dP.dy + svm_background_offset(kg));
199                         break;
200                 }
201                 case NODE_TEXCO_WINDOW: {
202                         data = svm_world_to_ndc(kg, sd, sd->P + sd->dP.dy);
203                         break;
204                 }
205                 case NODE_TEXCO_REFLECTION: {
206                         if(sd->object != ~0)
207                                 data = 2.0f*dot(sd->N, sd->I)*sd->N - sd->I;
208                         else
209                                 data = sd->I;
210                         break;
211                 }
212                 case NODE_TEXCO_DUPLI_GENERATED: {
213                         data = object_dupli_generated(kg, sd->object);
214                         break;
215                 }
216                 case NODE_TEXCO_DUPLI_UV: {
217                         data = object_dupli_uv(kg, sd->object);
218                         break;
219                 }
220         }
221
222         stack_store_float3(stack, out_offset, data);
223 #else
224         svm_node_tex_coord(kg, sd, stack, type, out_offset);
225 #endif
226 }
227
228 CCL_NAMESPACE_END
229