Blender V5.0
noisetex.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/* The following offset functions generate random offsets to be added to texture
13 * coordinates to act as a seed since the noise functions don't have seed values.
14 * A seed value is needed for generating distortion textures and color outputs.
15 * The offset's components are in the range [100, 200], not too high to cause
16 * bad precision and not too small to be noticeable. We use float seed because
17 * OSL only support float hashes.
18 */
19
21{
22 return 100.0f + hash_float_to_float(seed) * 100.0f;
23}
24
26{
27 return make_float2(100.0f + hash_float2_to_float(make_float2(seed, 0.0f)) * 100.0f,
28 100.0f + hash_float2_to_float(make_float2(seed, 1.0f)) * 100.0f);
29}
30
32{
33 return make_float3(100.0f + hash_float2_to_float(make_float2(seed, 0.0f)) * 100.0f,
34 100.0f + hash_float2_to_float(make_float2(seed, 1.0f)) * 100.0f,
35 100.0f + hash_float2_to_float(make_float2(seed, 2.0f)) * 100.0f);
36}
37
39{
40 return make_float4(100.0f + hash_float2_to_float(make_float2(seed, 0.0f)) * 100.0f,
41 100.0f + hash_float2_to_float(make_float2(seed, 1.0f)) * 100.0f,
42 100.0f + hash_float2_to_float(make_float2(seed, 2.0f)) * 100.0f,
43 100.0f + hash_float2_to_float(make_float2(seed, 3.0f)) * 100.0f);
44}
45
46template<typename T>
48 const float detail,
49 const float roughness,
50 const float lacunarity,
51 const float offset,
52 const float gain,
53 const int type,
54 bool normalize)
55{
56 switch ((NodeNoiseType)type) {
58 return noise_multi_fractal(p, detail, roughness, lacunarity);
59 }
60 case NODE_NOISE_FBM: {
61 return noise_fbm(p, detail, roughness, lacunarity, normalize);
62 }
64 return noise_hybrid_multi_fractal(p, detail, roughness, lacunarity, offset, gain);
65 }
67 return noise_ridged_multi_fractal(p, detail, roughness, lacunarity, offset, gain);
68 }
70 return noise_hetero_terrain(p, detail, roughness, lacunarity, offset);
71 }
72 default: {
74 return 0.0;
75 }
76 }
77}
78
79ccl_device void noise_texture_1d(const float co,
80 const float detail,
81 const float roughness,
82 const float lacunarity,
83 const float offset,
84 const float gain,
85 const float distortion,
86 const int type,
87 bool normalize,
88 bool color_is_needed,
89 ccl_private float *value,
90 ccl_private float3 *color)
91{
92 float p = co;
93 if (distortion != 0.0f) {
94 p += snoise_1d(p + random_float_offset(0.0f)) * distortion;
95 }
96
97 *value = noise_select(p, detail, roughness, lacunarity, offset, gain, type, normalize);
98 if (color_is_needed) {
99 *color = make_float3(*value,
101 detail,
102 roughness,
103 lacunarity,
104 offset,
105 gain,
106 type,
107 normalize),
109 detail,
110 roughness,
111 lacunarity,
112 offset,
113 gain,
114 type,
115 normalize));
116 }
117}
118
120 const float detail,
121 const float roughness,
122 const float lacunarity,
123 const float offset,
124 const float gain,
125 const float distortion,
126 const int type,
127 const bool normalize,
128 const bool color_is_needed,
129 ccl_private float *value,
130 ccl_private float3 *color)
131{
132 float2 p = co;
133 if (distortion != 0.0f) {
134 p += make_float2(snoise_2d(p + random_float2_offset(0.0f)) * distortion,
135 snoise_2d(p + random_float2_offset(1.0f)) * distortion);
136 }
137
138 *value = noise_select(p, detail, roughness, lacunarity, offset, gain, type, normalize);
139 if (color_is_needed) {
140 *color = make_float3(*value,
142 detail,
143 roughness,
144 lacunarity,
145 offset,
146 gain,
147 type,
148 normalize),
150 detail,
151 roughness,
152 lacunarity,
153 offset,
154 gain,
155 type,
156 normalize));
157 }
158}
159
161 const float detail,
162 const float roughness,
163 const float lacunarity,
164 const float offset,
165 const float gain,
166 const float distortion,
167 const int type,
168 const bool normalize,
169 const bool color_is_needed,
170 ccl_private float *value,
171 ccl_private float3 *color)
172{
173 float3 p = co;
174 if (distortion != 0.0f) {
175 p += make_float3(snoise_3d(p + random_float3_offset(0.0f)) * distortion,
176 snoise_3d(p + random_float3_offset(1.0f)) * distortion,
177 snoise_3d(p + random_float3_offset(2.0f)) * distortion);
178 }
179
180 *value = noise_select(p, detail, roughness, lacunarity, offset, gain, type, normalize);
181 if (color_is_needed) {
182 *color = make_float3(*value,
184 detail,
185 roughness,
186 lacunarity,
187 offset,
188 gain,
189 type,
190 normalize),
192 detail,
193 roughness,
194 lacunarity,
195 offset,
196 gain,
197 type,
198 normalize));
199 }
200}
201
203 const float detail,
204 const float roughness,
205 const float lacunarity,
206 const float offset,
207 const float gain,
208 const float distortion,
209 const int type,
210 const bool normalize,
211 const bool color_is_needed,
212 ccl_private float *value,
213 ccl_private float3 *color)
214{
215 float4 p = co;
216 if (distortion != 0.0f) {
217 p += make_float4(snoise_4d(p + random_float4_offset(0.0f)) * distortion,
218 snoise_4d(p + random_float4_offset(1.0f)) * distortion,
219 snoise_4d(p + random_float4_offset(2.0f)) * distortion,
220 snoise_4d(p + random_float4_offset(3.0f)) * distortion);
221 }
222
223 *value = noise_select(p, detail, roughness, lacunarity, offset, gain, type, normalize);
224 if (color_is_needed) {
225 *color = make_float3(*value,
227 detail,
228 roughness,
229 lacunarity,
230 offset,
231 gain,
232 type,
233 normalize),
235 detail,
236 roughness,
237 lacunarity,
238 offset,
239 gain,
240 type,
241 normalize));
242 }
243}
244
246 ccl_private float *stack,
247 const uint offsets1,
248 const uint offsets2,
249 const uint offsets3,
250 int node_offset)
251{
252 uint vector_stack_offset;
253 uint w_stack_offset;
254 uint scale_stack_offset;
255 uint detail_stack_offset;
256 uint roughness_stack_offset;
257 uint lacunarity_stack_offset;
258 uint offset_stack_offset;
259 uint gain_stack_offset;
260 uint distortion_stack_offset;
261 uint value_stack_offset;
262 uint color_stack_offset;
263
265 offsets1, &vector_stack_offset, &w_stack_offset, &scale_stack_offset, &detail_stack_offset);
266 svm_unpack_node_uchar4(offsets2,
267 &roughness_stack_offset,
268 &lacunarity_stack_offset,
269 &offset_stack_offset,
270 &gain_stack_offset);
272 offsets3, &distortion_stack_offset, &value_stack_offset, &color_stack_offset);
273
274 const uint4 defaults1 = read_node(kg, &node_offset);
275 const uint4 defaults2 = read_node(kg, &node_offset);
276 const uint4 properties = read_node(kg, &node_offset);
277
278 const uint dimensions = properties.x;
279 const uint type = properties.y;
280 const uint normalize = properties.z;
281
282 float3 vector = stack_load_float3(stack, vector_stack_offset);
283 float w = stack_load_float_default(stack, w_stack_offset, defaults1.x);
284 const float scale = stack_load_float_default(stack, scale_stack_offset, defaults1.y);
285 float detail = stack_load_float_default(stack, detail_stack_offset, defaults1.z);
286 float roughness = stack_load_float_default(stack, roughness_stack_offset, defaults1.w);
287 const float lacunarity = stack_load_float_default(stack, lacunarity_stack_offset, defaults2.x);
288 const float offset = stack_load_float_default(stack, offset_stack_offset, defaults2.y);
289 const float gain = stack_load_float_default(stack, gain_stack_offset, defaults2.z);
290 const float distortion = stack_load_float_default(stack, distortion_stack_offset, defaults2.w);
291
292 detail = clamp(detail, 0.0f, 15.0f);
293 roughness = fmaxf(roughness, 0.0f);
294
295 vector *= scale;
296 w *= scale;
297
298 float value;
299 float3 color;
300 switch (dimensions) {
301 case 1:
303 detail,
304 roughness,
305 lacunarity,
306 offset,
307 gain,
308 distortion,
309 type,
310 normalize,
311 stack_valid(color_stack_offset),
312 &value,
313 &color);
314 break;
315 case 2:
317 detail,
318 roughness,
319 lacunarity,
320 offset,
321 gain,
322 distortion,
323 type,
324 normalize,
325 stack_valid(color_stack_offset),
326 &value,
327 &color);
328 break;
329 case 3:
331 detail,
332 roughness,
333 lacunarity,
334 offset,
335 gain,
336 distortion,
337 type,
338 normalize,
339 stack_valid(color_stack_offset),
340 &value,
341 &color);
342 break;
343 case 4:
345 detail,
346 roughness,
347 lacunarity,
348 offset,
349 gain,
350 distortion,
351 type,
352 normalize,
353 stack_valid(color_stack_offset),
354 &value,
355 &color);
356 break;
357 default:
358 kernel_assert(0);
359 }
360
361 if (stack_valid(value_stack_offset)) {
362 stack_store_float(stack, value_stack_offset, value);
363 }
364 if (stack_valid(color_stack_offset)) {
365 stack_store_float3(stack, color_stack_offset, color);
366 }
367 return node_offset;
368}
369
unsigned int uint
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
static unsigned long seed
Definition btSoftBody.h:39
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_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 kernel_assert(cond)
#define ccl_private
const ThreadKernelGlobalsCPU * KernelGlobals
#define ccl_device_inline
#define ccl_device_noinline
#define CCL_NAMESPACE_END
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
ccl_device_noinline float noise_hetero_terrain(float p, const float detail, const float roughness, const float lacunarity, const float offset)
CCL_NAMESPACE_BEGIN ccl_device_noinline float noise_fbm(float p, const float detail, const float roughness, const float lacunarity, bool normalize)
ccl_device_noinline float noise_ridged_multi_fractal(float p, const float detail, const float roughness, const float lacunarity, const float offset, const float gain)
ccl_device_noinline float noise_multi_fractal(float p, const float detail, const float roughness, const float lacunarity)
ccl_device_noinline float noise_hybrid_multi_fractal(float p, const float detail, const float roughness, const float lacunarity, const float offset, const float gain)
VecBase< float, D > normalize(VecOp< float, D >) RET
constexpr T clamp(T, U, U) RET
ccl_device_inline float hash_float2_to_float(const float2 k)
Definition hash.h:222
NodeNoiseType
@ NODE_NOISE_FBM
@ NODE_NOISE_HYBRID_MULTIFRACTAL
@ NODE_NOISE_RIDGED_MULTIFRACTAL
@ NODE_NOISE_HETERO_TERRAIN
@ NODE_NOISE_MULTIFRACTAL
#define T
float hash_float_to_float(float k)
Definition node_hash.h:70
ccl_device_inline float snoise_1d(float p)
Definition noise.h:691
ccl_device_inline float snoise_2d(float2 p)
Definition noise.h:707
ccl_device_inline float snoise_3d(float3 p)
Definition noise.h:725
ccl_device_inline float snoise_4d(float4 p)
Definition noise.h:743
CCL_NAMESPACE_BEGIN ccl_device_inline float random_float_offset(const float seed)
Definition noisetex.h:20
ccl_device_inline float2 random_float2_offset(const float seed)
Definition noisetex.h:25
ccl_device void noise_texture_2d(const float2 co, const float detail, const float roughness, const float lacunarity, const float offset, const float gain, const float distortion, const int type, const bool normalize, const bool color_is_needed, ccl_private float *value, ccl_private float3 *color)
Definition noisetex.h:119
ccl_device void noise_texture_4d(const float4 co, const float detail, const float roughness, const float lacunarity, const float offset, const float gain, const float distortion, const int type, const bool normalize, const bool color_is_needed, ccl_private float *value, ccl_private float3 *color)
Definition noisetex.h:202
ccl_device void noise_texture_1d(const float co, const float detail, const float roughness, const float lacunarity, const float offset, const float gain, const float distortion, const int type, bool normalize, bool color_is_needed, ccl_private float *value, ccl_private float3 *color)
Definition noisetex.h:79
ccl_device void noise_texture_3d(const float3 co, const float detail, const float roughness, const float lacunarity, const float offset, const float gain, const float distortion, const int type, const bool normalize, const bool color_is_needed, ccl_private float *value, ccl_private float3 *color)
Definition noisetex.h:160
ccl_device float noise_select(T p, const float detail, const float roughness, const float lacunarity, const float offset, const float gain, const int type, bool normalize)
Definition noisetex.h:47
ccl_device_inline float4 random_float4_offset(const float seed)
Definition noisetex.h:38
ccl_device_noinline int svm_node_tex_noise(KernelGlobals kg, ccl_private float *stack, const uint offsets1, const uint offsets2, const uint offsets3, int node_offset)
Definition noisetex.h:245
ccl_device_inline float3 random_float3_offset(const float seed)
Definition noisetex.h:31
#define ccl_device
#define fmaxf
#define make_float2
#define make_float4
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