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
This commit is contained in:
parent
7f4a2fc437
commit
133dfdd704
|
@ -656,7 +656,7 @@ static void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CDa
|
|||
}
|
||||
|
||||
if (attr_random != NULL) {
|
||||
attr_random->add(hash_int_01(num_curves));
|
||||
attr_random->add(hash_uint2_to_float(num_curves, 0));
|
||||
}
|
||||
|
||||
mesh->add_curve(num_keys, CData->psys_shader[sys]);
|
||||
|
|
|
@ -217,7 +217,7 @@ void BlenderSync::sync_light(BL::Object &b_parent,
|
|||
light->random_id = random_id;
|
||||
}
|
||||
else {
|
||||
light->random_id = hash_int_2d(hash_string(b_ob.name().c_str()), 0);
|
||||
light->random_id = hash_uint2(hash_string(b_ob.name().c_str()), 0);
|
||||
}
|
||||
|
||||
if (light->type == LIGHT_AREA)
|
||||
|
@ -490,7 +490,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
|
|||
else {
|
||||
object->dupli_generated = make_float3(0.0f, 0.0f, 0.0f);
|
||||
object->dupli_uv = make_float2(0.0f, 0.0f);
|
||||
object->random_id = hash_int_2d(hash_string(object->name.c_str()), 0);
|
||||
object->random_id = hash_uint2(hash_string(object->name.c_str()), 0);
|
||||
}
|
||||
|
||||
object->tag_update(scene);
|
||||
|
|
|
@ -539,8 +539,8 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
|
|||
/* Make sure all views have different noise patterns. - hardcoded value just to make it random
|
||||
*/
|
||||
if (view_index != 0) {
|
||||
scene->integrator->seed += hash_int_2d(scene->integrator->seed,
|
||||
hash_int(view_index * 0xdeadbeef));
|
||||
scene->integrator->seed += hash_uint2(scene->integrator->seed,
|
||||
hash_uint2(view_index * 0xdeadbeef, 0));
|
||||
scene->integrator->tag_update(scene);
|
||||
}
|
||||
|
||||
|
|
|
@ -844,6 +844,12 @@ static ShaderNode *add_node(Scene *scene,
|
|||
}
|
||||
node = ies;
|
||||
}
|
||||
else if (b_node.is_a(&RNA_ShaderNodeTexWhiteNoise)) {
|
||||
BL::ShaderNodeTexWhiteNoise b_tex_white_noise_node(b_node);
|
||||
WhiteNoiseTextureNode *white_noise_node = new WhiteNoiseTextureNode();
|
||||
white_noise_node->dimensions = b_tex_white_noise_node.dimensions();
|
||||
node = white_noise_node;
|
||||
}
|
||||
else if (b_node.is_a(&RNA_ShaderNodeNormalMap)) {
|
||||
BL::ShaderNodeNormalMap b_normal_map_node(b_node);
|
||||
NormalMapNode *nmap = new NormalMapNode();
|
||||
|
|
|
@ -255,13 +255,13 @@ void BlenderSync::sync_integrator()
|
|||
|
||||
integrator->seed = get_int(cscene, "seed");
|
||||
if (get_boolean(cscene, "use_animated_seed")) {
|
||||
integrator->seed = hash_int_2d(b_scene.frame_current(), get_int(cscene, "seed"));
|
||||
integrator->seed = hash_uint2(b_scene.frame_current(), get_int(cscene, "seed"));
|
||||
if (b_scene.frame_subframe() != 0.0f) {
|
||||
/* TODO(sergey): Ideally should be some sort of hash_merge,
|
||||
* but this is good enough for now.
|
||||
*/
|
||||
integrator->seed += hash_int_2d((int)(b_scene.frame_subframe() * (float)INT_MAX),
|
||||
get_int(cscene, "seed"));
|
||||
integrator->seed += hash_uint2((int)(b_scene.frame_subframe() * (float)INT_MAX),
|
||||
get_int(cscene, "seed"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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!");
|
||||
}
|
||||
}
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -140,6 +140,7 @@ typedef enum ShaderNodeType {
|
|||
NODE_IES,
|
||||
NODE_MAP_RANGE,
|
||||
NODE_CLAMP,
|
||||
NODE_TEX_WHITE_NOISE,
|
||||
} ShaderNodeType;
|
||||
|
||||
typedef enum NodeAttributeType {
|
||||
|
|
|
@ -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
|
|
@ -141,7 +141,7 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
|
|||
kintegrator->caustics_refractive = caustics_refractive;
|
||||
kintegrator->filter_glossy = (filter_glossy == 0.0f) ? FLT_MAX : 1.0f / filter_glossy;
|
||||
|
||||
kintegrator->seed = hash_int(seed);
|
||||
kintegrator->seed = hash_uint2(seed, 0);
|
||||
|
||||
kintegrator->use_ambient_occlusion = ((Pass::contains(scene->film->passes, PASS_AO)) ||
|
||||
dscene->data.background.ao_factor != 0.0f);
|
||||
|
|
|
@ -1110,6 +1110,53 @@ void IESLightNode::compile(OSLCompiler &compiler)
|
|||
compiler.add(this, "node_ies_light");
|
||||
}
|
||||
|
||||
/* White Noise Texture */
|
||||
|
||||
NODE_DEFINE(WhiteNoiseTextureNode)
|
||||
{
|
||||
NodeType *type = NodeType::add("white_noise_texture", create, NodeType::SHADER);
|
||||
|
||||
static NodeEnum dimensions_enum;
|
||||
dimensions_enum.insert("1D", 1);
|
||||
dimensions_enum.insert("2D", 2);
|
||||
dimensions_enum.insert("3D", 3);
|
||||
dimensions_enum.insert("4D", 4);
|
||||
SOCKET_ENUM(dimensions, "Dimensions", dimensions_enum, 3);
|
||||
|
||||
SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f));
|
||||
SOCKET_IN_FLOAT(w, "W", 0.0f);
|
||||
|
||||
SOCKET_OUT_FLOAT(value, "Value");
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
WhiteNoiseTextureNode::WhiteNoiseTextureNode() : ShaderNode(node_type)
|
||||
{
|
||||
}
|
||||
|
||||
void WhiteNoiseTextureNode::compile(SVMCompiler &compiler)
|
||||
{
|
||||
ShaderInput *vector_in = input("Vector");
|
||||
ShaderInput *w_in = input("W");
|
||||
ShaderOutput *value_out = output("Value");
|
||||
|
||||
int vector_stack_offset = compiler.stack_assign(vector_in);
|
||||
int w_stack_offset = compiler.stack_assign(w_in);
|
||||
int value_stack_offset = compiler.stack_assign(value_out);
|
||||
|
||||
compiler.add_node(NODE_TEX_WHITE_NOISE,
|
||||
dimensions,
|
||||
compiler.encode_uchar4(vector_stack_offset, w_stack_offset),
|
||||
value_stack_offset);
|
||||
}
|
||||
|
||||
void WhiteNoiseTextureNode::compile(OSLCompiler &compiler)
|
||||
{
|
||||
compiler.parameter(this, "dimensions");
|
||||
compiler.add(this, "node_white_noise_texture");
|
||||
}
|
||||
|
||||
/* Musgrave Texture */
|
||||
|
||||
NODE_DEFINE(MusgraveTextureNode)
|
||||
|
|
|
@ -370,6 +370,19 @@ class IESLightNode : public TextureNode {
|
|||
void get_slot();
|
||||
};
|
||||
|
||||
class WhiteNoiseTextureNode : public ShaderNode {
|
||||
public:
|
||||
SHADER_NODE_CLASS(WhiteNoiseTextureNode)
|
||||
virtual int get_group()
|
||||
{
|
||||
return NODE_GROUP_LEVEL_2;
|
||||
}
|
||||
|
||||
int dimensions;
|
||||
float3 vector;
|
||||
float w;
|
||||
};
|
||||
|
||||
class MappingNode : public ShaderNode {
|
||||
public:
|
||||
SHADER_NODE_CLASS(MappingNode)
|
||||
|
|
|
@ -21,39 +21,196 @@
|
|||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
ccl_device_inline uint hash_int_2d(uint kx, uint ky)
|
||||
{
|
||||
/* ***** Jenkins Lookup3 Hash Functions ***** */
|
||||
|
||||
/* Source: http://burtleburtle.net/bob/c/lookup3.c */
|
||||
|
||||
#define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
|
||||
|
||||
#define mix(a, b, c) \
|
||||
{ \
|
||||
a -= c; \
|
||||
a ^= rot(c, 4); \
|
||||
c += b; \
|
||||
b -= a; \
|
||||
b ^= rot(a, 6); \
|
||||
a += c; \
|
||||
c -= b; \
|
||||
c ^= rot(b, 8); \
|
||||
b += a; \
|
||||
a -= c; \
|
||||
a ^= rot(c, 16); \
|
||||
c += b; \
|
||||
b -= a; \
|
||||
b ^= rot(a, 19); \
|
||||
a += c; \
|
||||
c -= b; \
|
||||
c ^= rot(b, 4); \
|
||||
b += a; \
|
||||
}
|
||||
|
||||
#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); \
|
||||
}
|
||||
|
||||
ccl_device_inline uint hash_uint(uint kx)
|
||||
{
|
||||
uint a, b, c;
|
||||
a = b = c = 0xdeadbeef + (1 << 2) + 13;
|
||||
|
||||
a = b = c = 0xdeadbeef + (2 << 2) + 13;
|
||||
a += kx;
|
||||
b += ky;
|
||||
|
||||
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);
|
||||
final(a, b, c);
|
||||
|
||||
return c;
|
||||
|
||||
#undef rot
|
||||
}
|
||||
|
||||
ccl_device_inline uint hash_int(uint k)
|
||||
ccl_device_inline uint hash_uint2(uint kx, uint ky)
|
||||
{
|
||||
return hash_int_2d(k, 0);
|
||||
uint a, b, c;
|
||||
a = b = c = 0xdeadbeef + (2 << 2) + 13;
|
||||
|
||||
b += ky;
|
||||
a += kx;
|
||||
final(a, b, c);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
ccl_device_inline uint hash_uint3(uint kx, uint ky, uint kz)
|
||||
{
|
||||
uint a, b, c;
|
||||
a = b = c = 0xdeadbeef + (3 << 2) + 13;
|
||||
|
||||
c += kz;
|
||||
b += ky;
|
||||
a += kx;
|
||||
final(a, b, c);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
ccl_device_inline uint hash_uint4(uint kx, uint ky, uint kz, uint kw)
|
||||
{
|
||||
uint a, b, c;
|
||||
a = b = c = 0xdeadbeef + (4 << 2) + 13;
|
||||
|
||||
a += kx;
|
||||
b += ky;
|
||||
c += kz;
|
||||
mix(a, b, c);
|
||||
|
||||
a += kw;
|
||||
final(a, b, c);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
#undef rot
|
||||
#undef final
|
||||
#undef mix
|
||||
|
||||
/* Hashing uint or uint[234] into a float in the range [0, 1]. */
|
||||
|
||||
ccl_device_inline float hash_uint_to_float(uint kx)
|
||||
{
|
||||
return (float)hash_uint(kx) / (float)0xFFFFFFFFu;
|
||||
}
|
||||
|
||||
ccl_device_inline float hash_uint2_to_float(uint kx, uint ky)
|
||||
{
|
||||
return (float)hash_uint2(kx, ky) / (float)0xFFFFFFFFu;
|
||||
}
|
||||
|
||||
ccl_device_inline float hash_uint3_to_float(uint kx, uint ky, uint kz)
|
||||
{
|
||||
return (float)hash_uint3(kx, ky, kz) / (float)0xFFFFFFFFu;
|
||||
}
|
||||
|
||||
ccl_device_inline float hash_uint4_to_float(uint kx, uint ky, uint kz, uint kw)
|
||||
{
|
||||
return (float)hash_uint4(kx, ky, kz, kw) / (float)0xFFFFFFFFu;
|
||||
}
|
||||
|
||||
/* Hashing float or float[234] into a float in the range [0, 1]. */
|
||||
|
||||
ccl_device_inline float hash_float_to_float(float k)
|
||||
{
|
||||
return hash_uint_to_float(__float_as_uint(k));
|
||||
}
|
||||
|
||||
ccl_device_inline float hash_float2_to_float(float2 k)
|
||||
{
|
||||
return hash_uint2_to_float(__float_as_uint(k.x), __float_as_uint(k.y));
|
||||
}
|
||||
|
||||
ccl_device_inline float hash_float3_to_float(float3 k)
|
||||
{
|
||||
return hash_uint3_to_float(__float_as_uint(k.x), __float_as_uint(k.y), __float_as_uint(k.z));
|
||||
}
|
||||
|
||||
ccl_device_inline float hash_float4_to_float(float4 k)
|
||||
{
|
||||
return hash_uint4_to_float(
|
||||
__float_as_uint(k.x), __float_as_uint(k.y), __float_as_uint(k.z), __float_as_uint(k.w));
|
||||
}
|
||||
|
||||
/* Hashing float[234] into float[234] of components in the range [0, 1]. */
|
||||
|
||||
ccl_device_inline float2 hash_float2_to_float2(float2 k)
|
||||
{
|
||||
return make_float2(hash_float2_to_float(k), hash_float3_to_float(make_float3(k.x, k.y, 1.0)));
|
||||
}
|
||||
|
||||
ccl_device_inline float3 hash_float3_to_float3(float3 k)
|
||||
{
|
||||
return make_float3(hash_float3_to_float(k),
|
||||
hash_float4_to_float(make_float4(k.x, k.y, k.z, 1.0)),
|
||||
hash_float4_to_float(make_float4(k.x, k.y, k.z, 2.0)));
|
||||
}
|
||||
|
||||
ccl_device_inline float4 hash_float4_to_float4(float4 k)
|
||||
{
|
||||
return make_float4(hash_float4_to_float(k),
|
||||
hash_float4_to_float(make_float4(k.w, k.x, k.y, k.z)),
|
||||
hash_float4_to_float(make_float4(k.z, k.w, k.x, k.y)),
|
||||
hash_float4_to_float(make_float4(k.y, k.z, k.w, k.x)));
|
||||
}
|
||||
|
||||
/* Hashing float or float[234] into float3 of components in range [0, 1]. */
|
||||
|
||||
ccl_device_inline float3 hash_float_to_float3(float k)
|
||||
{
|
||||
return make_float3(hash_float_to_float(k),
|
||||
hash_float2_to_float(make_float2(k, 1.0)),
|
||||
hash_float2_to_float(make_float2(k, 2.0)));
|
||||
}
|
||||
|
||||
ccl_device_inline float3 hash_float2_to_float3(float2 k)
|
||||
{
|
||||
return make_float3(hash_float2_to_float(k),
|
||||
hash_float3_to_float(make_float3(k.x, k.y, 1.0)),
|
||||
hash_float3_to_float(make_float3(k.x, k.y, 2.0)));
|
||||
}
|
||||
|
||||
ccl_device_inline float3 hash_float4_to_float3(float4 k)
|
||||
{
|
||||
return make_float3(hash_float4_to_float(k),
|
||||
hash_float4_to_float(make_float4(k.z, k.x, k.w, k.y)),
|
||||
hash_float4_to_float(make_float4(k.w, k.z, k.y, k.x)));
|
||||
}
|
||||
|
||||
#ifndef __KERNEL_GPU__
|
||||
|
@ -68,11 +225,6 @@ static inline uint hash_string(const char *str)
|
|||
}
|
||||
#endif
|
||||
|
||||
ccl_device_inline float hash_int_01(uint k)
|
||||
{
|
||||
return (float)hash_int(k) * (1.0f / (float)0xFFFFFFFF);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* __UTIL_HASH_H__ */
|
||||
|
|
|
@ -237,6 +237,7 @@ shader_node_categories = [
|
|||
NodeItem("ShaderNodeTexBrick"),
|
||||
NodeItem("ShaderNodeTexPointDensity"),
|
||||
NodeItem("ShaderNodeTexIES"),
|
||||
NodeItem("ShaderNodeTexWhiteNoise"),
|
||||
]),
|
||||
ShaderNodeCategory("SH_NEW_OP_COLOR", "Color", items=[
|
||||
NodeItem("ShaderNodeMixRGB"),
|
||||
|
|
|
@ -978,6 +978,7 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree,
|
|||
#define SH_NODE_BSDF_HAIR_PRINCIPLED 701
|
||||
#define SH_NODE_MAP_RANGE 702
|
||||
#define SH_NODE_CLAMP 703
|
||||
#define SH_NODE_TEX_WHITE_NOISE 704
|
||||
|
||||
/* custom defines options for Material node */
|
||||
#define SH_NODE_MAT_DIFF 1
|
||||
|
|
|
@ -3933,6 +3933,7 @@ static void registerShaderNodes(void)
|
|||
register_node_type_sh_tex_brick();
|
||||
register_node_type_sh_tex_pointdensity();
|
||||
register_node_type_sh_tex_ies();
|
||||
register_node_type_sh_tex_white_noise();
|
||||
}
|
||||
|
||||
static void registerTextureNodes(void)
|
||||
|
|
|
@ -1186,6 +1186,11 @@ static void node_shader_buts_ambient_occlusion(uiLayout *layout,
|
|||
uiItemR(layout, ptr, "only_local", 0, NULL, ICON_NONE);
|
||||
}
|
||||
|
||||
static void node_shader_buts_white_noise(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
|
||||
{
|
||||
uiItemR(layout, ptr, "dimensions", 0, "", ICON_NONE);
|
||||
}
|
||||
|
||||
/* only once called */
|
||||
static void node_shader_set_butfunc(bNodeType *ntype)
|
||||
{
|
||||
|
@ -1330,6 +1335,9 @@ static void node_shader_set_butfunc(bNodeType *ntype)
|
|||
case SH_NODE_AMBIENT_OCCLUSION:
|
||||
ntype->draw_buttons = node_shader_buts_ambient_occlusion;
|
||||
break;
|
||||
case SH_NODE_TEX_WHITE_NOISE:
|
||||
ntype->draw_buttons = node_shader_buts_white_noise;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1166,9 +1166,34 @@ float integer_noise(int n)
|
|||
return 0.5 * (float(nn) / 1073741824.0);
|
||||
}
|
||||
|
||||
uint hash(uint kx, uint ky, uint kz)
|
||||
{
|
||||
/* ***** Jenkins Lookup3 Hash Functions ***** */
|
||||
|
||||
/* Source: http://burtleburtle.net/bob/c/lookup3.c */
|
||||
|
||||
#define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
|
||||
|
||||
#define mix(a, b, c) \
|
||||
{ \
|
||||
a -= c; \
|
||||
a ^= rot(c, 4); \
|
||||
c += b; \
|
||||
b -= a; \
|
||||
b ^= rot(a, 6); \
|
||||
a += c; \
|
||||
c -= b; \
|
||||
c ^= rot(b, 8); \
|
||||
b += a; \
|
||||
a -= c; \
|
||||
a ^= rot(c, 16); \
|
||||
c += b; \
|
||||
b -= a; \
|
||||
b ^= rot(a, 19); \
|
||||
a += c; \
|
||||
c -= b; \
|
||||
c ^= rot(b, 4); \
|
||||
b += a; \
|
||||
}
|
||||
|
||||
#define final(a, b, c) \
|
||||
{ \
|
||||
c ^= b; \
|
||||
|
@ -1186,9 +1211,34 @@ uint hash(uint kx, uint ky, uint kz)
|
|||
c ^= b; \
|
||||
c -= rot(b, 24); \
|
||||
}
|
||||
// now hash the data!
|
||||
uint a, b, c, len = 3u;
|
||||
a = b = c = 0xdeadbeefu + (len << 2u) + 13u;
|
||||
|
||||
uint hash_uint(uint kx)
|
||||
{
|
||||
uint a, b, c;
|
||||
a = b = c = 0xdeadbeefu + (1u << 2u) + 13u;
|
||||
|
||||
a += kx;
|
||||
final(a, b, c);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
uint hash_uint2(uint kx, uint ky)
|
||||
{
|
||||
uint a, b, c;
|
||||
a = b = c = 0xdeadbeefu + (2u << 2u) + 13u;
|
||||
|
||||
b += ky;
|
||||
a += kx;
|
||||
final(a, b, c);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
uint hash_uint3(uint kx, uint ky, uint kz)
|
||||
{
|
||||
uint a, b, c;
|
||||
a = b = c = 0xdeadbeefu + (3u << 2u) + 13u;
|
||||
|
||||
c += kz;
|
||||
b += ky;
|
||||
|
@ -1196,15 +1246,157 @@ uint hash(uint kx, uint ky, uint kz)
|
|||
final(a, b, c);
|
||||
|
||||
return c;
|
||||
#undef rot
|
||||
#undef final
|
||||
}
|
||||
|
||||
uint hash(int kx, int ky, int kz)
|
||||
uint hash_uint4(uint kx, uint ky, uint kz, uint kw)
|
||||
{
|
||||
return hash(uint(kx), uint(ky), uint(kz));
|
||||
uint a, b, c;
|
||||
a = b = c = 0xdeadbeefu + (4u << 2u) + 13u;
|
||||
|
||||
a += kx;
|
||||
b += ky;
|
||||
c += kz;
|
||||
mix(a, b, c);
|
||||
|
||||
a += kw;
|
||||
final(a, b, c);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
#undef rot
|
||||
#undef final
|
||||
#undef mix
|
||||
|
||||
uint hash_int(int kx)
|
||||
{
|
||||
return hash_uint(uint(kx));
|
||||
}
|
||||
|
||||
uint hash_int2(int kx, int ky)
|
||||
{
|
||||
return hash_uint2(uint(kx), uint(ky));
|
||||
}
|
||||
|
||||
uint hash_int3(int kx, int ky, int kz)
|
||||
{
|
||||
return hash_uint3(uint(kx), uint(ky), uint(kz));
|
||||
}
|
||||
|
||||
uint hash_int4(int kx, int ky, int kz, int kw)
|
||||
{
|
||||
return hash_uint4(uint(kx), uint(ky), uint(kz), uint(kw));
|
||||
}
|
||||
|
||||
/* Hashing uint or uint[234] into a float in the range [0, 1]. */
|
||||
|
||||
float hash_uint_to_float(uint kx)
|
||||
{
|
||||
return float(hash_uint(kx)) / float(0xFFFFFFFFu);
|
||||
}
|
||||
|
||||
float hash_uint2_to_float(uint kx, uint ky)
|
||||
{
|
||||
return float(hash_uint2(kx, ky)) / float(0xFFFFFFFFu);
|
||||
}
|
||||
|
||||
float hash_uint3_to_float(uint kx, uint ky, uint kz)
|
||||
{
|
||||
return float(hash_uint3(kx, ky, kz)) / float(0xFFFFFFFFu);
|
||||
}
|
||||
|
||||
float hash_uint4_to_float(uint kx, uint ky, uint kz, uint kw)
|
||||
{
|
||||
return float(hash_uint4(kx, ky, kz, kw)) / float(0xFFFFFFFFu);
|
||||
}
|
||||
|
||||
/* Hashing float or vec[234] into a float in the range [0, 1]. */
|
||||
|
||||
float hash_float_to_float(float k)
|
||||
{
|
||||
return hash_uint_to_float(floatBitsToUint(k));
|
||||
}
|
||||
|
||||
float hash_vec2_to_float(vec2 k)
|
||||
{
|
||||
return hash_uint2_to_float(floatBitsToUint(k.x), floatBitsToUint(k.y));
|
||||
}
|
||||
|
||||
float hash_vec3_to_float(vec3 k)
|
||||
{
|
||||
return hash_uint3_to_float(floatBitsToUint(k.x), floatBitsToUint(k.y), floatBitsToUint(k.z));
|
||||
}
|
||||
|
||||
float hash_vec4_to_float(vec4 k)
|
||||
{
|
||||
return hash_uint4_to_float(
|
||||
floatBitsToUint(k.x), floatBitsToUint(k.y), floatBitsToUint(k.z), floatBitsToUint(k.w));
|
||||
}
|
||||
|
||||
/* Hashing vec[234] into vec[234] of components in the range [0, 1]. */
|
||||
|
||||
vec2 hash_vec2_to_vec2(vec2 k)
|
||||
{
|
||||
return vec2(hash_vec2_to_float(k), hash_vec3_to_float(vec3(k, 1.0)));
|
||||
}
|
||||
|
||||
vec3 hash_vec3_to_vec3(vec3 k)
|
||||
{
|
||||
return vec3(
|
||||
hash_vec3_to_float(k), hash_vec4_to_float(vec4(k, 1.0)), hash_vec4_to_float(vec4(k, 2.0)));
|
||||
}
|
||||
|
||||
vec4 hash_vec4_to_vec4(vec4 k)
|
||||
{
|
||||
return vec4(hash_vec4_to_float(k.xyzw),
|
||||
hash_vec4_to_float(k.wxyz),
|
||||
hash_vec4_to_float(k.zwxy),
|
||||
hash_vec4_to_float(k.yzwx));
|
||||
}
|
||||
|
||||
/* Hashing float or vec[234] into vec3 of components in range [0, 1]. */
|
||||
|
||||
vec3 hash_float_to_vec3(float k)
|
||||
{
|
||||
return vec3(
|
||||
hash_float_to_float(k), hash_vec2_to_float(vec2(k, 1.0)), hash_vec2_to_float(vec2(k, 2.0)));
|
||||
}
|
||||
|
||||
vec3 hash_vec2_to_vec3(vec2 k)
|
||||
{
|
||||
return vec3(
|
||||
hash_vec2_to_float(k), hash_vec3_to_float(vec3(k, 1.0)), hash_vec3_to_float(vec3(k, 2.0)));
|
||||
}
|
||||
|
||||
vec3 hash_vec4_to_vec3(vec4 k)
|
||||
{
|
||||
return vec3(hash_vec4_to_float(k.xyzw), hash_vec4_to_float(k.zxwy), hash_vec4_to_float(k.wzyx));
|
||||
}
|
||||
|
||||
/* White Noise */
|
||||
|
||||
void node_white_noise_1d(vec3 vector, float w, out float value)
|
||||
{
|
||||
value = hash_float_to_float(w);
|
||||
}
|
||||
|
||||
void node_white_noise_2d(vec3 vector, float w, out float value)
|
||||
{
|
||||
value = hash_vec2_to_float(vector.xy);
|
||||
}
|
||||
|
||||
void node_white_noise_3d(vec3 vector, float w, out float value)
|
||||
{
|
||||
value = hash_vec3_to_float(vector);
|
||||
}
|
||||
|
||||
void node_white_noise_4d(vec3 vector, float w, out float value)
|
||||
{
|
||||
value = hash_vec4_to_float(vec4(vector, w));
|
||||
}
|
||||
|
||||
/* Cell Noise */
|
||||
|
||||
float bits_to_01(uint bits)
|
||||
{
|
||||
return (float(bits) / 4294967295.0);
|
||||
|
@ -1216,7 +1408,7 @@ float cellnoise(vec3 p)
|
|||
int iy = quick_floor(p.y);
|
||||
int iz = quick_floor(p.z);
|
||||
|
||||
return bits_to_01(hash(uint(ix), uint(iy), uint(iz)));
|
||||
return hash_uint3_to_float(uint(ix), uint(iy), uint(iz));
|
||||
}
|
||||
|
||||
vec3 cellnoise_color(vec3 p)
|
||||
|
@ -2901,22 +3093,24 @@ float noise_perlin(float x, float y, float z)
|
|||
|
||||
float noise_u[2], noise_v[2];
|
||||
|
||||
noise_u[0] = noise_nerp(
|
||||
u, noise_grad(hash(X, Y, Z), fx, fy, fz), noise_grad(hash(X + 1, Y, Z), fx - 1.0, fy, fz));
|
||||
noise_u[0] = noise_nerp(u,
|
||||
noise_grad(hash_int3(X, Y, Z), fx, fy, fz),
|
||||
noise_grad(hash_int3(X + 1, Y, Z), fx - 1.0, fy, fz));
|
||||
|
||||
noise_u[1] = noise_nerp(u,
|
||||
noise_grad(hash(X, Y + 1, Z), fx, fy - 1.0, fz),
|
||||
noise_grad(hash(X + 1, Y + 1, Z), fx - 1.0, fy - 1.0, fz));
|
||||
noise_grad(hash_int3(X, Y + 1, Z), fx, fy - 1.0, fz),
|
||||
noise_grad(hash_int3(X + 1, Y + 1, Z), fx - 1.0, fy - 1.0, fz));
|
||||
|
||||
noise_v[0] = noise_nerp(v, noise_u[0], noise_u[1]);
|
||||
|
||||
noise_u[0] = noise_nerp(u,
|
||||
noise_grad(hash(X, Y, Z + 1), fx, fy, fz - 1.0),
|
||||
noise_grad(hash(X + 1, Y, Z + 1), fx - 1.0, fy, fz - 1.0));
|
||||
noise_grad(hash_int3(X, Y, Z + 1), fx, fy, fz - 1.0),
|
||||
noise_grad(hash_int3(X + 1, Y, Z + 1), fx - 1.0, fy, fz - 1.0));
|
||||
|
||||
noise_u[1] = noise_nerp(u,
|
||||
noise_grad(hash(X, Y + 1, Z + 1), fx, fy - 1.0, fz - 1.0),
|
||||
noise_grad(hash(X + 1, Y + 1, Z + 1), fx - 1.0, fy - 1.0, fz - 1.0));
|
||||
noise_u[1] = noise_nerp(
|
||||
u,
|
||||
noise_grad(hash_int3(X, Y + 1, Z + 1), fx, fy - 1.0, fz - 1.0),
|
||||
noise_grad(hash_int3(X + 1, Y + 1, Z + 1), fx - 1.0, fy - 1.0, fz - 1.0));
|
||||
|
||||
noise_v[1] = noise_nerp(v, noise_u[0], noise_u[1]);
|
||||
|
||||
|
|
|
@ -170,6 +170,14 @@ const EnumPropertyItem rna_enum_node_vec_math_items[] = {
|
|||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
const EnumPropertyItem rna_enum_node_tex_dimensions_items[] = {
|
||||
{1, "1D", 0, "1D", "Use the scalar value W as input"},
|
||||
{2, "2D", 0, "2D", "Use the 2D vector (x, y) as input. The z component is ignored"},
|
||||
{3, "3D", 0, "3D", "Use the 3D vector Vector as input"},
|
||||
{4, "4D", 0, "4D", "Use the 4D vector (x, y, z, w) as input"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
const EnumPropertyItem rna_enum_node_filter_items[] = {
|
||||
{0, "SOFTEN", 0, "Soften", ""},
|
||||
{1, "SHARPEN", 0, "Sharpen", ""},
|
||||
|
@ -4497,6 +4505,18 @@ static void def_sh_tex_wave(StructRNA *srna)
|
|||
RNA_def_property_update(prop, 0, "rna_Node_update");
|
||||
}
|
||||
|
||||
static void def_sh_tex_white_noise(StructRNA *srna)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
prop = RNA_def_property(srna, "dimensions", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "custom1");
|
||||
RNA_def_property_enum_items(prop, rna_enum_node_tex_dimensions_items);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Dimensions", "The number of dimensions to evaluate the noise in");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNode_socket_update");
|
||||
}
|
||||
|
||||
static void def_sh_tex_coord(StructRNA *srna)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
|
|
@ -200,6 +200,7 @@ set(SRC
|
|||
shader/nodes/node_shader_tex_sky.c
|
||||
shader/nodes/node_shader_tex_voronoi.c
|
||||
shader/nodes/node_shader_tex_wave.c
|
||||
shader/nodes/node_shader_tex_white_noise.c
|
||||
shader/nodes/node_shader_uvAlongStroke.c
|
||||
shader/nodes/node_shader_uvmap.c
|
||||
shader/nodes/node_shader_valToRgb.c
|
||||
|
|
|
@ -131,6 +131,7 @@ void register_node_type_sh_tex_noise(void);
|
|||
void register_node_type_sh_tex_checker(void);
|
||||
void register_node_type_sh_bump(void);
|
||||
void register_node_type_sh_tex_ies(void);
|
||||
void register_node_type_sh_tex_white_noise(void);
|
||||
|
||||
void register_node_type_sh_custom_group(bNodeType *ntype);
|
||||
|
||||
|
|
|
@ -127,6 +127,7 @@ DefNode(ShaderNode, SH_NODE_BEVEL, def_sh_bevel, "BEV
|
|||
DefNode(ShaderNode, SH_NODE_DISPLACEMENT, def_sh_displacement, "DISPLACEMENT", Displacement, "Displacement", "" )
|
||||
DefNode(ShaderNode, SH_NODE_VECTOR_DISPLACEMENT,def_sh_vector_displacement,"VECTOR_DISPLACEMENT",VectorDisplacement,"Vector Displacement","" )
|
||||
DefNode(ShaderNode, SH_NODE_TEX_IES, def_sh_tex_ies, "TEX_IES", TexIES, "IES Texture", "" )
|
||||
DefNode(ShaderNode, SH_NODE_TEX_WHITE_NOISE, def_sh_tex_white_noise, "TEX_WHITE_NOISE", TexWhiteNoise, "White Noise", "" )
|
||||
|
||||
DefNode(CompositorNode, CMP_NODE_VIEWER, def_cmp_viewer, "VIEWER", Viewer, "Viewer", "" )
|
||||
DefNode(CompositorNode, CMP_NODE_RGB, 0, "RGB", RGB, "RGB", "" )
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2005 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#include "../node_shader_util.h"
|
||||
|
||||
/* **************** WHITE NOISE **************** */
|
||||
|
||||
static bNodeSocketTemplate sh_node_tex_white_noise_in[] = {
|
||||
{SOCK_VECTOR, 1, N_("Vector"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f, PROP_NONE},
|
||||
{SOCK_FLOAT, 1, N_("W"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f, PROP_NONE},
|
||||
{-1, 0, ""}};
|
||||
|
||||
static bNodeSocketTemplate sh_node_tex_white_noise_out[] = {
|
||||
{SOCK_FLOAT, 0, N_("Value")},
|
||||
{-1, 0, ""},
|
||||
};
|
||||
|
||||
static void node_shader_init_tex_white_noise(bNodeTree *UNUSED(ntree), bNode *node)
|
||||
{
|
||||
node->custom1 = 3;
|
||||
}
|
||||
|
||||
static int gpu_shader_tex_white_noise(GPUMaterial *mat,
|
||||
bNode *node,
|
||||
bNodeExecData *UNUSED(execdata),
|
||||
GPUNodeStack *in,
|
||||
GPUNodeStack *out)
|
||||
{
|
||||
static const char *names[] = {
|
||||
"",
|
||||
"node_white_noise_1d",
|
||||
"node_white_noise_2d",
|
||||
"node_white_noise_3d",
|
||||
"node_white_noise_4d",
|
||||
};
|
||||
|
||||
return GPU_stack_link(mat, node, names[node->custom1], in, out);
|
||||
}
|
||||
|
||||
static void node_shader_update_tex_white_noise(bNodeTree *UNUSED(ntree), bNode *node)
|
||||
{
|
||||
bNodeSocket *sockVector = nodeFindSocket(node, SOCK_IN, "Vector");
|
||||
bNodeSocket *sockW = nodeFindSocket(node, SOCK_IN, "W");
|
||||
|
||||
nodeSetSocketAvailability(sockVector, node->custom1 != 1);
|
||||
nodeSetSocketAvailability(sockW, node->custom1 == 1 || node->custom1 == 4);
|
||||
}
|
||||
|
||||
void register_node_type_sh_tex_white_noise(void)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
sh_node_type_base(&ntype, SH_NODE_TEX_WHITE_NOISE, "White Noise Texture", NODE_CLASS_TEXTURE, 0);
|
||||
node_type_socket_templates(&ntype, sh_node_tex_white_noise_in, sh_node_tex_white_noise_out);
|
||||
node_type_init(&ntype, node_shader_init_tex_white_noise);
|
||||
node_type_gpu(&ntype, gpu_shader_tex_white_noise);
|
||||
node_type_update(&ntype, node_shader_update_tex_white_noise);
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
Loading…
Reference in New Issue