Blender V4.3
kernel/svm/attribute.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#pragma once
6
8
9/* Attribute Node */
10
13 uint4 node,
15 ccl_private uint *out_offset)
16{
17 *out_offset = node.z;
18 *type = (NodeAttributeOutputType)node.w;
19
21
22 if (sd->object != OBJECT_NONE) {
23 desc = find_attribute(kg, sd, node.y);
24 if (desc.offset == ATTR_STD_NOT_FOUND) {
25 desc = attribute_not_found();
26 desc.offset = 0;
27 desc.type = (NodeAttributeType)node.w;
28 }
29 }
30 else {
31 /* background */
32 desc = attribute_not_found();
33 desc.offset = 0;
34 desc.type = (NodeAttributeType)node.w;
35 }
36
37 return desc;
38}
39
40template<uint node_feature_mask>
43 ccl_private float *stack,
44 uint4 node)
45{
47 uint out_offset = 0;
48 AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset);
49
50#ifdef __VOLUME__
52 {
53 /* Volumes
54 * NOTE: moving this into its own node type might help improve performance. */
55 if (primitive_is_volume_attribute(sd, desc)) {
56 const float4 value = volume_attribute_float4(kg, sd, desc);
57
58 if (type == NODE_ATTR_OUTPUT_FLOAT) {
59 const float f = volume_attribute_value_to_float(value);
60 stack_store_float(stack, out_offset, f);
61 }
62 else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
63 const float3 f = volume_attribute_value_to_float3(value);
64 stack_store_float3(stack, out_offset, f);
65 }
66 else {
67 const float f = volume_attribute_value_to_alpha(value);
68 stack_store_float(stack, out_offset, f);
69 }
70 return;
71 }
72 }
73#endif
74
75 if (sd->type == PRIMITIVE_LAMP && node.y == ATTR_STD_UV) {
76 stack_store_float3(stack, out_offset, make_float3(1.0f - sd->u - sd->v, sd->u, 0.0f));
77 return;
78 }
79
80 if (node.y == ATTR_STD_GENERATED && desc.element == ATTR_ELEMENT_NONE) {
81 /* No generated attribute, fall back to object coordinates. */
82 float3 f = sd->P;
83 if (sd->object != OBJECT_NONE) {
85 }
86 if (type == NODE_ATTR_OUTPUT_FLOAT) {
87 stack_store_float(stack, out_offset, average(f));
88 }
89 else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
90 stack_store_float3(stack, out_offset, f);
91 }
92 else {
93 stack_store_float(stack, out_offset, 1.0f);
94 }
95 return;
96 }
97
98 /* Surface. */
99 if (desc.type == NODE_ATTR_FLOAT) {
100 float f = primitive_surface_attribute_float(kg, sd, desc, NULL, NULL);
101 if (type == NODE_ATTR_OUTPUT_FLOAT) {
102 stack_store_float(stack, out_offset, f);
103 }
104 else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
105 stack_store_float3(stack, out_offset, make_float3(f, f, f));
106 }
107 else {
108 stack_store_float(stack, out_offset, 1.0f);
109 }
110 }
111 else if (desc.type == NODE_ATTR_FLOAT2) {
113 if (type == NODE_ATTR_OUTPUT_FLOAT) {
114 stack_store_float(stack, out_offset, f.x);
115 }
116 else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
117 stack_store_float3(stack, out_offset, make_float3(f.x, f.y, 0.0f));
118 }
119 else {
120 stack_store_float(stack, out_offset, 1.0f);
121 }
122 }
123 else if (desc.type == NODE_ATTR_FLOAT4 || desc.type == NODE_ATTR_RGBA) {
124 float4 f = primitive_surface_attribute_float4(kg, sd, desc, NULL, NULL);
125 if (type == NODE_ATTR_OUTPUT_FLOAT) {
126 stack_store_float(stack, out_offset, average(float4_to_float3(f)));
127 }
128 else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
129 stack_store_float3(stack, out_offset, float4_to_float3(f));
130 }
131 else {
132 stack_store_float(stack, out_offset, f.w);
133 }
134 }
135 else {
137 if (type == NODE_ATTR_OUTPUT_FLOAT) {
138 stack_store_float(stack, out_offset, average(f));
139 }
140 else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
141 stack_store_float3(stack, out_offset, f);
142 }
143 else {
144 stack_store_float(stack, out_offset, 1.0f);
145 }
146 }
147}
148
153
158
161 ccl_private float *stack,
162 uint4 node)
163{
165 uint out_offset = 0;
166 AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset);
167
168#ifdef __VOLUME__
169 /* Volume */
170 if (primitive_is_volume_attribute(sd, desc)) {
171 if (type == NODE_ATTR_OUTPUT_FLOAT) {
172 stack_store_float(stack, out_offset, 0.0f);
173 }
174 else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
175 stack_store_float3(stack, out_offset, make_float3(0.0f, 0.0f, 0.0f));
176 }
177 else {
178 stack_store_float(stack, out_offset, 1.0f);
179 }
180 return;
181 }
182#endif
183
184 if (node.y == ATTR_STD_GENERATED && desc.element == ATTR_ELEMENT_NONE) {
185 /* No generated attribute, fall back to object coordinates. */
187 if (sd->object != OBJECT_NONE) {
189 }
190 if (type == NODE_ATTR_OUTPUT_FLOAT) {
191 stack_store_float(stack, out_offset, average(f));
192 }
193 else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
194 stack_store_float3(stack, out_offset, f);
195 }
196 else {
197 stack_store_float(stack, out_offset, 1.0f);
198 }
199 return;
200 }
201
202 /* Surface */
203 if (desc.type == NODE_ATTR_FLOAT) {
204 float dx;
205 float f = primitive_surface_attribute_float(kg, sd, desc, &dx, NULL);
206 if (type == NODE_ATTR_OUTPUT_FLOAT) {
207 stack_store_float(stack, out_offset, f + dx);
208 }
209 else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
210 stack_store_float3(stack, out_offset, make_float3(f + dx, f + dx, f + dx));
211 }
212 else {
213 stack_store_float(stack, out_offset, 1.0f);
214 }
215 }
216 else if (desc.type == NODE_ATTR_FLOAT2) {
217 float2 dx;
218 float2 f = primitive_surface_attribute_float2(kg, sd, desc, &dx, NULL);
219 if (type == NODE_ATTR_OUTPUT_FLOAT) {
220 stack_store_float(stack, out_offset, f.x + dx.x);
221 }
222 else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
223 stack_store_float3(stack, out_offset, make_float3(f.x + dx.x, f.y + dx.y, 0.0f));
224 }
225 else {
226 stack_store_float(stack, out_offset, 1.0f);
227 }
228 }
229 else if (desc.type == NODE_ATTR_FLOAT4 || desc.type == NODE_ATTR_RGBA) {
230 float4 dx;
231 float4 f = primitive_surface_attribute_float4(kg, sd, desc, &dx, NULL);
232 if (type == NODE_ATTR_OUTPUT_FLOAT) {
233 stack_store_float(stack, out_offset, average(float4_to_float3(f + dx)));
234 }
235 else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
236 stack_store_float3(stack, out_offset, float4_to_float3(f + dx));
237 }
238 else {
239 stack_store_float(stack, out_offset, f.w + dx.w);
240 }
241 }
242 else {
243 float3 dx;
244 float3 f = primitive_surface_attribute_float3(kg, sd, desc, &dx, NULL);
245 if (type == NODE_ATTR_OUTPUT_FLOAT) {
246 stack_store_float(stack, out_offset, average(f + dx));
247 }
248 else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
249 stack_store_float3(stack, out_offset, f + dx);
250 }
251 else {
252 stack_store_float(stack, out_offset, 1.0f);
253 }
254 }
255}
256
259 ccl_private float *stack,
260 uint4 node)
261{
263 uint out_offset = 0;
264 AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset);
265
266#ifdef __VOLUME__
267 /* Volume */
268 if (primitive_is_volume_attribute(sd, desc)) {
269 if (type == NODE_ATTR_OUTPUT_FLOAT) {
270 stack_store_float(stack, out_offset, 0.0f);
271 }
272 else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
273 stack_store_float3(stack, out_offset, make_float3(0.0f, 0.0f, 0.0f));
274 }
275 else {
276 stack_store_float(stack, out_offset, 1.0f);
277 }
278 return;
279 }
280#endif
281
282 if (node.y == ATTR_STD_GENERATED && desc.element == ATTR_ELEMENT_NONE) {
283 /* No generated attribute, fall back to object coordinates. */
285 if (sd->object != OBJECT_NONE) {
287 }
288 if (type == NODE_ATTR_OUTPUT_FLOAT) {
289 stack_store_float(stack, out_offset, average(f));
290 }
291 else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
292 stack_store_float3(stack, out_offset, f);
293 }
294 else {
295 stack_store_float(stack, out_offset, 1.0f);
296 }
297 return;
298 }
299
300 /* Surface */
301 if (desc.type == NODE_ATTR_FLOAT) {
302 float dy;
303 float f = primitive_surface_attribute_float(kg, sd, desc, NULL, &dy);
304 if (type == NODE_ATTR_OUTPUT_FLOAT) {
305 stack_store_float(stack, out_offset, f + dy);
306 }
307 else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
308 stack_store_float3(stack, out_offset, make_float3(f + dy, f + dy, f + dy));
309 }
310 else {
311 stack_store_float(stack, out_offset, 1.0f);
312 }
313 }
314 else if (desc.type == NODE_ATTR_FLOAT2) {
315 float2 dy;
316 float2 f = primitive_surface_attribute_float2(kg, sd, desc, NULL, &dy);
317 if (type == NODE_ATTR_OUTPUT_FLOAT) {
318 stack_store_float(stack, out_offset, f.x + dy.x);
319 }
320 else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
321 stack_store_float3(stack, out_offset, make_float3(f.x + dy.x, f.y + dy.y, 0.0f));
322 }
323 else {
324 stack_store_float(stack, out_offset, 1.0f);
325 }
326 }
327 else if (desc.type == NODE_ATTR_FLOAT4 || desc.type == NODE_ATTR_RGBA) {
328 float4 dy;
329 float4 f = primitive_surface_attribute_float4(kg, sd, desc, NULL, &dy);
330 if (type == NODE_ATTR_OUTPUT_FLOAT) {
331 stack_store_float(stack, out_offset, average(float4_to_float3(f + dy)));
332 }
333 else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
334 stack_store_float3(stack, out_offset, float4_to_float3(f + dy));
335 }
336 else {
337 stack_store_float(stack, out_offset, f.w + dy.w);
338 }
339 }
340 else {
341 float3 dy;
342 float3 f = primitive_surface_attribute_float3(kg, sd, desc, NULL, &dy);
343 if (type == NODE_ATTR_OUTPUT_FLOAT) {
344 stack_store_float(stack, out_offset, average(f + dy));
345 }
346 else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
347 stack_store_float3(stack, out_offset, f + dy);
348 }
349 else {
350 stack_store_float(stack, out_offset, 1.0f);
351 }
352 }
353}
354
unsigned int uint
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define ccl_device_forceinline
#define ccl_device
#define ccl_private
#define ccl_device_noinline
#define CCL_NAMESPACE_END
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
#define NULL
ccl_device_forceinline differential3 differential_from_compact(const float3 D, const float dD)
ccl_device_inline AttributeDescriptor attribute_not_found()
ccl_device_inline void object_inverse_position_transform(KernelGlobals kg, ccl_private const ShaderData *sd, ccl_private float3 *P)
ccl_device_forceinline float3 svm_node_bump_P_dx(const ccl_private ShaderData *sd)
ccl_device_noinline void svm_node_attr_bump_dx(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node)
ccl_device_noinline void svm_node_attr(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node)
ccl_device_forceinline float3 svm_node_bump_P_dy(const ccl_private ShaderData *sd)
CCL_NAMESPACE_BEGIN ccl_device AttributeDescriptor svm_node_attr_init(KernelGlobals kg, ccl_private ShaderData *sd, uint4 node, ccl_private NodeAttributeOutputType *type, ccl_private uint *out_offset)
ccl_device_noinline void svm_node_attr_bump_dy(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node)
ccl_device_inline void stack_store_float3(ccl_private float *stack, uint a, float3 f)
ccl_device_inline void stack_store_float(ccl_private float *stack, uint a, float f)
NodeAttributeOutputType
@ NODE_ATTR_OUTPUT_FLOAT
@ NODE_ATTR_OUTPUT_FLOAT3
NodeAttributeType
@ NODE_ATTR_FLOAT
@ NODE_ATTR_RGBA
@ NODE_ATTR_FLOAT2
@ NODE_ATTR_FLOAT4
@ PRIMITIVE_LAMP
@ ATTR_STD_UV
@ ATTR_STD_NOT_FOUND
@ ATTR_STD_GENERATED
#define IF_KERNEL_NODES_FEATURE(feature)
#define OBJECT_NONE
ShaderData
@ ATTR_ELEMENT_NONE
ccl_device_inline float average(const float2 a)
ccl_device_forceinline float3 primitive_surface_attribute_float3(KernelGlobals kg, ccl_private const ShaderData *sd, const AttributeDescriptor desc, ccl_private float3 *dx, ccl_private float3 *dy)
Definition primitive.h:84
ccl_device_forceinline float2 primitive_surface_attribute_float2(KernelGlobals kg, ccl_private const ShaderData *sd, const AttributeDescriptor desc, ccl_private float2 *dx, ccl_private float2 *dy)
Definition primitive.h:53
ccl_device_forceinline float4 primitive_surface_attribute_float4(KernelGlobals kg, ccl_private const ShaderData *sd, const AttributeDescriptor desc, ccl_private float4 *dx, ccl_private float4 *dy)
Definition primitive.h:115
CCL_NAMESPACE_BEGIN ccl_device_forceinline float primitive_surface_attribute_float(KernelGlobals kg, ccl_private const ShaderData *sd, const AttributeDescriptor desc, ccl_private float *dx, ccl_private float *dy)
Definition primitive.h:22
static bool find_attribute(const std::string &attributes, const char *search_attribute)
AttributeElement element
NodeAttributeType type
float x
float y
ccl_device_inline float3 float4_to_float3(const float4 a)
Definition util/math.h:535