diff options
author | OmarSquircleArt <omar.squircleart@gmail.com> | 2019-08-21 21:04:09 +0300 |
---|---|---|
committer | OmarSquircleArt <omar.squircleart@gmail.com> | 2019-08-21 21:04:09 +0300 |
commit | 133dfdd704b6a2a4d46337696773b331a44304ea (patch) | |
tree | e7465681db5a8783614fa2617ecb2455f1bef623 /intern/cycles/kernel | |
parent | 7f4a2fc437cf9a6decbda152bd7d36ce7a08929f (diff) |
Shading: Add White Noise node.
The White Noise node hashes the input and returns a random number in the
range [0, 1]. The input can be a 1D, 2D, 3D, or a 4D vector.
Reviewers: brecht, JacquesLucke
Differential Revision: https://developer.blender.org/D5550
Diffstat (limited to 'intern/cycles/kernel')
-rw-r--r-- | intern/cycles/kernel/CMakeLists.txt | 1 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_random.h | 2 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/osl_services.cpp | 2 | ||||
-rw-r--r-- | intern/cycles/kernel/shaders/CMakeLists.txt | 1 | ||||
-rw-r--r-- | intern/cycles/kernel/shaders/node_white_noise_texture.osl | 39 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm.h | 4 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_geometry.h | 2 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_noise.h | 60 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_types.h | 1 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_white_noise.h | 53 |
10 files changed, 115 insertions, 50 deletions
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index ab05d6ee1e9..48439a8b68f 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -221,6 +221,7 @@ set(SRC_SVM_HEADERS svm/svm_voronoi.h svm/svm_voxel.h svm/svm_wave.h + svm/svm_white_noise.h ) set(SRC_GEOM_HEADERS diff --git a/intern/cycles/kernel/kernel_random.h b/intern/cycles/kernel/kernel_random.h index 78eafbfe3cb..a5ae427c2d3 100644 --- a/intern/cycles/kernel/kernel_random.h +++ b/intern/cycles/kernel/kernel_random.h @@ -130,7 +130,7 @@ ccl_device_inline void path_rng_init(KernelGlobals *kg, float *fy) { /* load state */ - *rng_hash = hash_int_2d(x, y); + *rng_hash = hash_uint2(x, y); *rng_hash ^= kernel_data.integrator.seed; #ifdef __DEBUG_CORRELATION__ diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index 316d24b0954..3850d0fe94b 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -697,7 +697,7 @@ bool OSLRenderServices::get_object_standard_attribute( } else if (name == u_particle_random) { int particle_id = object_particle_id(kg, sd->object); - float f = hash_int_01(particle_index(kg, particle_id)); + float f = hash_uint2_to_float(particle_index(kg, particle_id), 0); return set_attribute_float(f, type, derivatives, val); } diff --git a/intern/cycles/kernel/shaders/CMakeLists.txt b/intern/cycles/kernel/shaders/CMakeLists.txt index 63cef6e841b..c50bffe27b2 100644 --- a/intern/cycles/kernel/shaders/CMakeLists.txt +++ b/intern/cycles/kernel/shaders/CMakeLists.txt @@ -85,6 +85,7 @@ set(SRC_OSL node_wavelength.osl node_blackbody.osl node_wave_texture.osl + node_white_noise_texture.osl node_wireframe.osl node_hair_bsdf.osl node_principled_hair_bsdf.osl diff --git a/intern/cycles/kernel/shaders/node_white_noise_texture.osl b/intern/cycles/kernel/shaders/node_white_noise_texture.osl new file mode 100644 index 00000000000..f026fb4ab39 --- /dev/null +++ b/intern/cycles/kernel/shaders/node_white_noise_texture.osl @@ -0,0 +1,39 @@ +/* + * Copyright 2011-2013 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "stdosl.h" + +shader node_white_noise_texture(string dimensions = "3D", + point Vector = point(0.0, 0.0, 0.0), + float W = 0.0, + output float Value = 0.0) +{ + if (dimensions == "1D") { + Value = noise("hash", W); + } + else if (dimensions == "2D") { + Value = noise("hash", Vector[0], Vector[1]); + } + else if (dimensions == "3D") { + Value = noise("hash", Vector); + } + else if (dimensions == "4D") { + Value = noise("hash", Vector, W); + } + else { + warning("%s", "Unknown dimension!"); + } +} diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h index 0d731d62e94..8f8451b364d 100644 --- a/intern/cycles/kernel/svm/svm.h +++ b/intern/cycles/kernel/svm/svm.h @@ -194,6 +194,7 @@ CCL_NAMESPACE_END #include "kernel/svm/svm_bump.h" #include "kernel/svm/svm_map_range.h" #include "kernel/svm/svm_clamp.h" +#include "kernel/svm/svm_white_noise.h" #ifdef __SHADER_RAYTRACE__ # include "kernel/svm/svm_ao.h" @@ -432,6 +433,9 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, case NODE_TEX_BRICK: svm_node_tex_brick(kg, sd, stack, node, &offset); break; + case NODE_TEX_WHITE_NOISE: + svm_node_tex_white_noise(kg, sd, stack, node.y, node.z, node.w, &offset); + break; # endif /* __TEXTURES__ */ # ifdef __EXTRA_NODES__ case NODE_NORMAL: diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h index a9104643299..4abe0831858 100644 --- a/intern/cycles/kernel/svm/svm_geometry.h +++ b/intern/cycles/kernel/svm/svm_geometry.h @@ -149,7 +149,7 @@ ccl_device void svm_node_particle_info( } case NODE_INFO_PAR_RANDOM: { int particle_id = object_particle_id(kg, sd->object); - float random = hash_int_01(particle_index(kg, particle_id)); + float random = hash_uint2_to_float(particle_index(kg, particle_id), 0); stack_store_float(stack, out_offset, random); break; } diff --git a/intern/cycles/kernel/svm/svm_noise.h b/intern/cycles/kernel/svm/svm_noise.h index 322579ccfe3..0bf3dfda4df 100644 --- a/intern/cycles/kernel/svm/svm_noise.h +++ b/intern/cycles/kernel/svm/svm_noise.h @@ -41,42 +41,6 @@ ccl_device_inline ssei quick_floor_sse(const ssef &x) } #endif -ccl_device uint hash(uint kx, uint ky, uint kz) -{ - // define some handy macros -#define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k)))) -#define final(a, b, c) \ - { \ - c ^= b; \ - c -= rot(b, 14); \ - a ^= c; \ - a -= rot(c, 11); \ - b ^= a; \ - b -= rot(a, 25); \ - c ^= b; \ - c -= rot(b, 16); \ - a ^= c; \ - a -= rot(c, 4); \ - b ^= a; \ - b -= rot(a, 14); \ - c ^= b; \ - c -= rot(b, 24); \ - } - // now hash the data! - uint a, b, c, len = 3; - a = b = c = 0xdeadbeef + (len << 2) + 13; - - c += kz; - b += ky; - a += kx; - final(a, b, c); - - return c; - // macros not needed anymore -#undef rot -#undef final -} - #ifdef __KERNEL_SSE2__ ccl_device_inline ssei hash_sse(const ssei &kx, const ssei &ky, const ssei &kz) { @@ -236,17 +200,19 @@ ccl_device_noinline float perlin(float x, float y, float z) result = nerp( w, nerp(v, - nerp(u, grad(hash(X, Y, Z), fx, fy, fz), grad(hash(X + 1, Y, Z), fx - 1.0f, fy, fz)), nerp(u, - grad(hash(X, Y + 1, Z), fx, fy - 1.0f, fz), - grad(hash(X + 1, Y + 1, Z), fx - 1.0f, fy - 1.0f, fz))), + grad(hash_uint3(X, Y, Z), fx, fy, fz), + grad(hash_uint3(X + 1, Y, Z), fx - 1.0f, fy, fz)), + nerp(u, + grad(hash_uint3(X, Y + 1, Z), fx, fy - 1.0f, fz), + grad(hash_uint3(X + 1, Y + 1, Z), fx - 1.0f, fy - 1.0f, fz))), nerp(v, nerp(u, - grad(hash(X, Y, Z + 1), fx, fy, fz - 1.0f), - grad(hash(X + 1, Y, Z + 1), fx - 1.0f, fy, fz - 1.0f)), + grad(hash_uint3(X, Y, Z + 1), fx, fy, fz - 1.0f), + grad(hash_uint3(X + 1, Y, Z + 1), fx - 1.0f, fy, fz - 1.0f)), nerp(u, - grad(hash(X, Y + 1, Z + 1), fx, fy - 1.0f, fz - 1.0f), - grad(hash(X + 1, Y + 1, Z + 1), fx - 1.0f, fy - 1.0f, fz - 1.0f)))); + grad(hash_uint3(X, Y + 1, Z + 1), fx, fy - 1.0f, fz - 1.0f), + grad(hash_uint3(X + 1, Y + 1, Z + 1), fx - 1.0f, fy - 1.0f, fz - 1.0f)))); float r = scale3(result); /* can happen for big coordinates, things even out to 0.0 then anyway */ @@ -312,16 +278,16 @@ ccl_device float snoise(float3 p) ccl_device float cellnoise(float3 p) { int3 ip = quick_floor_to_int3(p); - return bits_to_01(hash(ip.x, ip.y, ip.z)); + return hash_uint3_to_float(ip.x, ip.y, ip.z); } ccl_device float3 cellnoise3(float3 p) { int3 ip = quick_floor_to_int3(p); #ifndef __KERNEL_SSE__ - float r = bits_to_01(hash(ip.x, ip.y, ip.z)); - float g = bits_to_01(hash(ip.y, ip.x, ip.z)); - float b = bits_to_01(hash(ip.y, ip.z, ip.x)); + float r = hash_uint3_to_float(ip.x, ip.y, ip.z); + float g = hash_uint3_to_float(ip.y, ip.x, ip.z); + float b = hash_uint3_to_float(ip.y, ip.z, ip.x); return make_float3(r, g, b); #else ssei ip_yxz = shuffle<1, 0, 2, 3>(ssei(ip.m128)); diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index 884ad76a9b7..6f412074125 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -140,6 +140,7 @@ typedef enum ShaderNodeType { NODE_IES, NODE_MAP_RANGE, NODE_CLAMP, + NODE_TEX_WHITE_NOISE, } ShaderNodeType; typedef enum NodeAttributeType { diff --git a/intern/cycles/kernel/svm/svm_white_noise.h b/intern/cycles/kernel/svm/svm_white_noise.h new file mode 100644 index 00000000000..77cbb88a8e2 --- /dev/null +++ b/intern/cycles/kernel/svm/svm_white_noise.h @@ -0,0 +1,53 @@ +/* + * Copyright 2011-2013 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +CCL_NAMESPACE_BEGIN + +ccl_device void svm_node_tex_white_noise(KernelGlobals *kg, + ShaderData *sd, + float *stack, + uint dimensions, + uint inputs_stack_offsets, + uint value_stack_offset, + int *offset) +{ + uint vector_stack_offset, w_stack_offset; + decode_node_uchar4(inputs_stack_offsets, &vector_stack_offset, &w_stack_offset, NULL, NULL); + + float3 vector = stack_load_float3(stack, vector_stack_offset); + float w = stack_load_float(stack, w_stack_offset); + + float value; + switch (dimensions) { + case 1: + value = hash_float_to_float(w); + break; + case 2: + value = hash_float2_to_float(make_float2(vector.x, vector.y)); + break; + case 3: + value = hash_float3_to_float(vector); + break; + case 4: + value = hash_float4_to_float(make_float4(vector.x, vector.y, vector.z, w)); + break; + default: + kernel_assert(0); + } + stack_store_float(stack, value_stack_offset, value); +} + +CCL_NAMESPACE_END |