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 /* Light Path Node */
20 
svm_node_light_path(ShaderData * sd,ccl_addr_space PathState * state,float * stack,uint type,uint out_offset,int path_flag)21 ccl_device void svm_node_light_path(ShaderData *sd,
22                                     ccl_addr_space PathState *state,
23                                     float *stack,
24                                     uint type,
25                                     uint out_offset,
26                                     int path_flag)
27 {
28   float info = 0.0f;
29 
30   switch (type) {
31     case NODE_LP_camera:
32       info = (path_flag & PATH_RAY_CAMERA) ? 1.0f : 0.0f;
33       break;
34     case NODE_LP_shadow:
35       info = (path_flag & PATH_RAY_SHADOW) ? 1.0f : 0.0f;
36       break;
37     case NODE_LP_diffuse:
38       info = (path_flag & PATH_RAY_DIFFUSE) ? 1.0f : 0.0f;
39       break;
40     case NODE_LP_glossy:
41       info = (path_flag & PATH_RAY_GLOSSY) ? 1.0f : 0.0f;
42       break;
43     case NODE_LP_singular:
44       info = (path_flag & PATH_RAY_SINGULAR) ? 1.0f : 0.0f;
45       break;
46     case NODE_LP_reflection:
47       info = (path_flag & PATH_RAY_REFLECT) ? 1.0f : 0.0f;
48       break;
49     case NODE_LP_transmission:
50       info = (path_flag & PATH_RAY_TRANSMIT) ? 1.0f : 0.0f;
51       break;
52     case NODE_LP_volume_scatter:
53       info = (path_flag & PATH_RAY_VOLUME_SCATTER) ? 1.0f : 0.0f;
54       break;
55     case NODE_LP_backfacing:
56       info = (sd->flag & SD_BACKFACING) ? 1.0f : 0.0f;
57       break;
58     case NODE_LP_ray_length:
59       info = sd->ray_length;
60       break;
61     case NODE_LP_ray_depth:
62       info = (float)state->bounce;
63       break;
64     case NODE_LP_ray_diffuse:
65       info = (float)state->diffuse_bounce;
66       break;
67     case NODE_LP_ray_glossy:
68       info = (float)state->glossy_bounce;
69       break;
70     case NODE_LP_ray_transparent:
71       info = (float)state->transparent_bounce;
72       break;
73     case NODE_LP_ray_transmission:
74       info = (float)state->transmission_bounce;
75       break;
76   }
77 
78   stack_store_float(stack, out_offset, info);
79 }
80 
81 /* Light Falloff Node */
82 
svm_node_light_falloff(ShaderData * sd,float * stack,uint4 node)83 ccl_device void svm_node_light_falloff(ShaderData *sd, float *stack, uint4 node)
84 {
85   uint strength_offset, out_offset, smooth_offset;
86 
87   svm_unpack_node_uchar3(node.z, &strength_offset, &smooth_offset, &out_offset);
88 
89   float strength = stack_load_float(stack, strength_offset);
90   uint type = node.y;
91 
92   switch (type) {
93     case NODE_LIGHT_FALLOFF_QUADRATIC:
94       break;
95     case NODE_LIGHT_FALLOFF_LINEAR:
96       strength *= sd->ray_length;
97       break;
98     case NODE_LIGHT_FALLOFF_CONSTANT:
99       strength *= sd->ray_length * sd->ray_length;
100       break;
101   }
102 
103   float smooth = stack_load_float(stack, smooth_offset);
104 
105   if (smooth > 0.0f) {
106     float squared = sd->ray_length * sd->ray_length;
107     /* Distant lamps set the ray length to FLT_MAX, which causes squared to overflow. */
108     if (isfinite(squared)) {
109       strength *= squared / (smooth + squared);
110     }
111   }
112 
113   stack_store_float(stack, out_offset, strength);
114 }
115 
116 CCL_NAMESPACE_END
117