Blender V4.3
kernel/geom/volume.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/* Volume Primitive
6 *
7 * Volumes are just regions inside meshes with the mesh surface as boundaries.
8 * There isn't as much data to access as for surfaces, there is only a position
9 * to do lookups in 3D voxel or procedural textures.
10 *
11 * 3D voxel textures can be assigned as attributes per mesh, which means the
12 * same shader can be used for volume objects with different densities, etc. */
13
14#pragma once
15
17
18#ifdef __VOLUME__
19
20/* Return position normalized to 0..1 in mesh bounds */
21
22ccl_device_inline float3 volume_normalized_position(KernelGlobals kg,
23 ccl_private const ShaderData *sd,
24 float3 P)
25{
26 /* todo: optimize this so it's just a single matrix multiplication when
27 * possible (not motion blur), or perhaps even just translation + scale */
29
31
32 if (desc.offset != ATTR_STD_NOT_FOUND) {
34 P = transform_point(&tfm, P);
35 }
36
37 return P;
38}
39
40ccl_device float volume_attribute_value_to_float(const float4 value)
41{
42 return average(float4_to_float3(value));
43}
44
45ccl_device float volume_attribute_value_to_alpha(const float4 value)
46{
47 return value.w;
48}
49
50ccl_device float3 volume_attribute_value_to_float3(const float4 value)
51{
52 if (value.w > 1e-6f && value.w != 1.0f) {
53 /* For RGBA colors, unpremultiply after interpolation. */
54 return float4_to_float3(value) / value.w;
55 }
56 else {
57 return float4_to_float3(value);
58 }
59}
60
61ccl_device float4 volume_attribute_float4(KernelGlobals kg,
62 ccl_private const ShaderData *sd,
63 const AttributeDescriptor desc)
64{
66 return kernel_data_fetch(attributes_float4, desc.offset);
67 }
68 else if (desc.element == ATTR_ELEMENT_VOXEL) {
69 /* todo: optimize this so we don't have to transform both here and in
70 * kernel_tex_image_interp_3d when possible. Also could optimize for the
71 * common case where transform is translation/scale only. */
72 float3 P = sd->P;
76 return kernel_tex_image_interp_3d(kg, desc.offset, P, interp);
77 }
78 else {
79 return zero_float4();
80 }
81}
82
83#endif
84
ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals kg, int id, float3 P, InterpolationType interp)
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define kernel_data_fetch(name, index)
#define ccl_device
#define ccl_private
#define ccl_device_inline
#define CCL_NAMESPACE_END
ccl_device Transform primitive_attribute_matrix(KernelGlobals kg, const AttributeDescriptor desc)
ccl_device_inline void object_inverse_position_transform(KernelGlobals kg, ccl_private const ShaderData *sd, ccl_private float3 *P)
@ SD_VOLUME_CUBIC
@ ATTR_STD_GENERATED_TRANSFORM
@ ATTR_STD_NOT_FOUND
ShaderData
@ ATTR_ELEMENT_VOXEL
@ ATTR_ELEMENT_OBJECT
@ ATTR_ELEMENT_MESH
ccl_device_inline float average(const float2 a)
ccl_device_inline float2 interp(const float2 a, const float2 b, float t)
CCL_NAMESPACE_BEGIN ccl_device_inline float4 zero_float4()
Definition math_float4.h:15
VecBase< float, 4 > float4
static bool find_attribute(const std::string &attributes, const char *search_attribute)
AttributeElement element
CCL_NAMESPACE_END CCL_NAMESPACE_BEGIN ccl_device_inline float3 transform_point(ccl_private const Transform *t, const float3 a)
Definition transform.h:63
ccl_device_inline float3 float4_to_float3(const float4 a)
Definition util/math.h:535
InterpolationType
@ INTERPOLATION_NONE
@ INTERPOLATION_CUBIC