Blender V5.0
wave.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#include "kernel/svm/util.h"
9
11
12/* Wave */
13
15 NodeWaveBandsDirection bands_dir,
16 NodeWaveRingsDirection rings_dir,
17 NodeWaveProfile profile,
18 float3 p,
19 const float distortion,
20 const float detail,
21 const float dscale,
22 const float droughness,
23 const float phase)
24{
25 /* Prevent precision issues on unit coordinates. */
26 p = (p + 0.000001f) * 0.999999f;
27
28 float n;
29
30 if (type == NODE_WAVE_BANDS) {
31 if (bands_dir == NODE_WAVE_BANDS_DIRECTION_X) {
32 n = p.x * 20.0f;
33 }
34 else if (bands_dir == NODE_WAVE_BANDS_DIRECTION_Y) {
35 n = p.y * 20.0f;
36 }
37 else if (bands_dir == NODE_WAVE_BANDS_DIRECTION_Z) {
38 n = p.z * 20.0f;
39 }
40 else { /* NODE_WAVE_BANDS_DIRECTION_DIAGONAL */
41 n = (p.x + p.y + p.z) * 10.0f;
42 }
43 }
44 else { /* NODE_WAVE_RINGS */
45 float3 rp = p;
46 if (rings_dir == NODE_WAVE_RINGS_DIRECTION_X) {
47 rp *= make_float3(0.0f, 1.0f, 1.0f);
48 }
49 else if (rings_dir == NODE_WAVE_RINGS_DIRECTION_Y) {
50 rp *= make_float3(1.0f, 0.0f, 1.0f);
51 }
52 else if (rings_dir == NODE_WAVE_RINGS_DIRECTION_Z) {
53 rp *= make_float3(1.0f, 1.0f, 0.0f);
54 }
55 /* else: NODE_WAVE_RINGS_DIRECTION_SPHERICAL */
56
57 n = len(rp) * 20.0f;
58 }
59
60 n += phase;
61
62 if (distortion != 0.0f) {
63 n += distortion * (noise_fbm(p * dscale, detail, droughness, 2.0f, true) * 2.0f - 1.0f);
64 }
65
66 if (profile == NODE_WAVE_PROFILE_SIN) {
67 return 0.5f + 0.5f * sinf(n - M_PI_2_F);
68 }
69 if (profile == NODE_WAVE_PROFILE_SAW) {
70 n /= M_2PI_F;
71 return n - floorf(n);
72 }
73 /* NODE_WAVE_PROFILE_TRI */
74 n /= M_2PI_F;
75 return fabsf(n - floorf(n + 0.5f)) * 2.0f;
76}
77
79 ccl_private float *stack,
80 const uint4 node,
81 int offset)
82{
83 const uint4 node2 = read_node(kg, &offset);
84 const uint4 node3 = read_node(kg, &offset);
85
86 /* RNA properties */
87 uint type_offset;
88 uint bands_dir_offset;
89 uint rings_dir_offset;
90 uint profile_offset;
91 /* Inputs, Outputs */
92 uint co_offset;
93 uint scale_offset;
94 uint distortion_offset;
95 uint detail_offset;
96 uint dscale_offset;
97 uint droughness_offset;
98 uint phase_offset;
99 uint color_offset;
100 uint fac_offset;
101
103 node.y, &type_offset, &bands_dir_offset, &rings_dir_offset, &profile_offset);
104 svm_unpack_node_uchar3(node.z, &co_offset, &scale_offset, &distortion_offset);
106 node.w, &detail_offset, &dscale_offset, &droughness_offset, &phase_offset);
107 svm_unpack_node_uchar2(node2.x, &color_offset, &fac_offset);
108
109 const float3 co = stack_load_float3(stack, co_offset);
110 const float scale = stack_load_float_default(stack, scale_offset, node2.y);
111 const float distortion = stack_load_float_default(stack, distortion_offset, node2.z);
112 const float detail = stack_load_float_default(stack, detail_offset, node2.w);
113 const float dscale = stack_load_float_default(stack, dscale_offset, node3.x);
114 const float droughness = stack_load_float_default(stack, droughness_offset, node3.y);
115 const float phase = stack_load_float_default(stack, phase_offset, node3.z);
116
117 const float f = svm_wave((NodeWaveType)type_offset,
118 (NodeWaveBandsDirection)bands_dir_offset,
119 (NodeWaveRingsDirection)rings_dir_offset,
120 (NodeWaveProfile)profile_offset,
121 co * scale,
122 distortion,
123 detail,
124 dscale,
125 droughness,
126 phase);
127
128 if (stack_valid(fac_offset)) {
129 stack_store_float(stack, fac_offset, f);
130 }
131 if (stack_valid(color_offset)) {
132 stack_store_float3(stack, color_offset, make_float3(f, f, f));
133 }
134 return offset;
135}
136
unsigned int uint
ccl_device_inline void stack_store_float(ccl_private float *stack, const uint a, const float f)
ccl_device_inline uint4 read_node(KernelGlobals kg, ccl_private int *const offset)
ccl_device_inline void stack_store_float3(ccl_private float *stack, const uint a, const float3 f)
ccl_device_inline float stack_load_float_default(const ccl_private float *stack, const uint a, const uint value)
ccl_device_forceinline void svm_unpack_node_uchar2(const uint i, ccl_private uint *x, ccl_private uint *y)
ccl_device_forceinline void svm_unpack_node_uchar3(const uint i, ccl_private uint *x, ccl_private uint *y, ccl_private uint *z)
ccl_device_forceinline void svm_unpack_node_uchar4(const uint i, ccl_private uint *x, ccl_private uint *y, ccl_private uint *z, ccl_private uint *w)
ccl_device_inline bool stack_valid(const uint a)
CCL_NAMESPACE_BEGIN ccl_device_inline float3 stack_load_float3(const ccl_private float *stack, const uint a)
#define M_PI_2_F
#define ccl_private
#define ccl_device_noinline_cpu
const ThreadKernelGlobalsCPU * KernelGlobals
#define ccl_device_noinline
#define CCL_NAMESPACE_END
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
CCL_NAMESPACE_BEGIN ccl_device_noinline float noise_fbm(float p, const float detail, const float roughness, const float lacunarity, bool normalize)
NodeWaveBandsDirection
@ NODE_WAVE_BANDS_DIRECTION_Z
@ NODE_WAVE_BANDS_DIRECTION_Y
@ NODE_WAVE_BANDS_DIRECTION_X
NodeWaveType
@ NODE_WAVE_BANDS
NodeWaveProfile
@ NODE_WAVE_PROFILE_SIN
@ NODE_WAVE_PROFILE_SAW
NodeWaveRingsDirection
@ NODE_WAVE_RINGS_DIRECTION_Y
@ NODE_WAVE_RINGS_DIRECTION_X
@ NODE_WAVE_RINGS_DIRECTION_Z
#define floorf
#define fabsf
#define M_2PI_F
#define sinf
float z
Definition sky_math.h:136
float y
Definition sky_math.h:136
float x
Definition sky_math.h:136
uint x
Definition types_uint4.h:13
uint y
Definition types_uint4.h:13
uint z
Definition types_uint4.h:13
uint w
Definition types_uint4.h:13
uint len
ccl_device_noinline int svm_node_tex_wave(KernelGlobals kg, ccl_private float *stack, const uint4 node, int offset)
Definition wave.h:78
CCL_NAMESPACE_BEGIN ccl_device_noinline_cpu float svm_wave(NodeWaveType type, NodeWaveBandsDirection bands_dir, NodeWaveRingsDirection rings_dir, NodeWaveProfile profile, float3 p, const float distortion, const float detail, const float dscale, const float droughness, const float phase)
Definition wave.h:14