diff --git a/intern/cycles/app/cycles_xml.cpp b/intern/cycles/app/cycles_xml.cpp index ac8d1c1..03db6b5 100644 --- a/intern/cycles/app/cycles_xml.cpp +++ b/intern/cycles/app/cycles_xml.cpp @@ -418,6 +418,9 @@ static void xml_read_shader_graph(const XMLReadState& state, Shader *shader, pug else if(string_iequals(node.name(), "noise_texture")) { snode = new NoiseTextureNode(); } + else if(string_iequals(node.name(), "gabor_texture")) { + snode = new GaborTextureNode(); + } else if(string_iequals(node.name(), "checker_texture")) { snode = new CheckerTextureNode(); } diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index f974071..d5be798 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -629,6 +629,12 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen get_tex_mapping(&noise->tex_mapping, b_noise_node.texture_mapping()); node = noise; } + else if (b_node.is_a(&RNA_ShaderNodeTexGabor)) { + BL::ShaderNodeTexGabor b_gabor_node(b_node); + GaborTextureNode *gabor = new GaborTextureNode(); + get_tex_mapping(&gabor->tex_mapping, b_gabor_node.texture_mapping()); + node = gabor; + } else if (b_node.is_a(&RNA_ShaderNodeTexMusgrave)) { BL::ShaderNodeTexMusgrave b_musgrave_node(b_node); MusgraveTextureNode *musgrave = new MusgraveTextureNode(); diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h index 96c7cef..8656c70 100644 --- a/intern/cycles/kernel/svm/svm.h +++ b/intern/cycles/kernel/svm/svm.h @@ -147,6 +147,7 @@ CCL_NAMESPACE_END #include "svm_blackbody.h" #include "svm_closure.h" #include "svm_noisetex.h" +#include "svm_gabortex.h" #include "svm_convert.h" #include "svm_displace.h" #include "svm_fresnel.h" @@ -256,6 +257,9 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, Shade case NODE_TEX_NOISE: svm_node_tex_noise(kg, sd, stack, node, &offset); break; + case NODE_TEX_GABOR: + svm_node_tex_gabor(kg, sd, stack, node, &offset); + break; case NODE_TEX_VORONOI: svm_node_tex_voronoi(kg, sd, stack, node, &offset); break; diff --git a/intern/cycles/kernel/svm/svm_gabortex.h b/intern/cycles/kernel/svm/svm_gabortex.h new file mode 100755 index 0000000..78b7fb0 --- /dev/null +++ b/intern/cycles/kernel/svm/svm_gabortex.h @@ -0,0 +1,98 @@ +/* + * 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 + +/* Gabor */ + +ccl_device_inline void svm_gabor(float3 p, float scale, float seed, float impulses, float *fac, float3 *color) +{ + + /* + * p = co + * scale = scale + * seed = seed + * impulses = impulses + * fac = f + * color = color + */ + + /* p *= scale;*/ + + + + + + + float3 vec = p * scale; + + GaborParams gp; + + setup_gabor_parameters(gp, impulses); + + *fac = gabor_grid(gp, vec, seed); + + int rng; + int cell[3] = {quick_floor(vec.x),quick_floor(vec.y),quick_floor(vec.z)}; + rng_seed(rng, cell, seed); + + *color = make_float3(rng_uniform(rng), rng_uniform(rng), rng_uniform(rng)); + + fprintf(stderr, "svm_gabor p = %f\n", p); + fprintf(stderr, "svm_gabor scale = %f\n", scale); + fprintf(stderr, "svm_gabor seed = %f\n", seed); + fprintf(stderr, "svm_gabor impulses = %f\n", impulses); + fprintf(stderr, "svm_gabor fac* = %f\n", *fac); + fprintf(stderr, "svm_gabor color* = %f\n", *color); + +} + +ccl_device void svm_node_tex_gabor(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) +{ + uint co_offset, scale_offset, seed_offset, impulse_offset, fac_offset, color_offset; + + decode_node_uchar4(node.y, &co_offset, &scale_offset, &seed_offset, &impulse_offset); + + uint4 node2 = read_node(kg, offset); + + float scale = stack_load_float_default(stack, scale_offset, node2.x); + float seed = stack_load_float_default(stack, seed_offset, node2.y); + float impulses = stack_load_float_default(stack, impulse_offset, node2.z); + float3 co = stack_load_float3(stack, co_offset); + + float3 color; + float f; + + svm_gabor(co, scale, seed, impulses, &f, &color); + + + /* fprintf(stderr, "svm_node_tex_gabor p = %f\n", p); */ + fprintf(stderr, "svm_node_tex_gabor scale = %f\n", scale); + fprintf(stderr, "svm_node_tex_gabor seed = %f\n", seed); + fprintf(stderr, "svm_node_tex_gabor impulses = %f\n", impulses); + fprintf(stderr, "svm_node_tex_gabor fac* = %f\n", f); + fprintf(stderr, "svm_node_tex_gabor color* = %f\n", co); + + decode_node_uchar4(node.z, &color_offset, &fac_offset, NULL, NULL); + + if(stack_valid(fac_offset)) + stack_store_float(stack, fac_offset, f); + if(stack_valid(color_offset)) + stack_store_float3(stack, color_offset, color); +} + +CCL_NAMESPACE_END + diff --git a/intern/cycles/kernel/svm/svm_noise.h b/intern/cycles/kernel/svm/svm_noise.h index 282ad19..fead8e1 100644 --- a/intern/cycles/kernel/svm/svm_noise.h +++ b/intern/cycles/kernel/svm/svm_noise.h @@ -384,5 +384,220 @@ ccl_device float psnoise(float3 p, float3 pperiod) } #endif + +/* GABOR NOISE */ + +ccl_device int quick_floor(float x) +{ + return float_to_int(x) - ((x < 0) ? 1 : 0); +} + +#define INT_MAX 2137483647 + +ccl_device uint cellhash(int cell[3], int seed) +{ + // define macros +#define rot(x,k) (((x)<<(k) | ((x)>>(32-(k))))) +#define final(a,b,c) +#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; \ + } + + // hash data + + int a, b, c; + + a = b = c = 3735928588; + + // Put a,b,c in to cell array + a += cell[0]; + b += cell[1]; + c += cell[2]; + mix(a,b,c); + + a+=seed; + + final(a,b,c); + + return c; + +#undef rot +#undef mix +#undef final + + +} + + +ccl_device float rng_seed(int &rng, int cell[3], int seed) +{ + int chash = cellhash(cell, seed); + if(chash == 0) + chash = 1; + rng = chash * 3039177861; + + return rng; +} + +ccl_device float rng_next(int rng) +{ + rng *= 3039177861; + return rng; + +} + +ccl_device float rng_uniform(int &rng) +{ + float res = rng/float (INT_MAX) * 0.5 +0.5 ; + return res; + +} + +ccl_device int rng_poisson(int &rng, float mean) +{ + float g = exp(-mean); + int em = 0; + float t = rng_uniform(rng); + + while (t > g) + { + ++em; + t *=rng_uniform(rng); + } + + return em; + + +} + + +struct GaborParams { + float weight; + float impulses; + float radius, radius2, radius3, radius_inv; + float a; + float bandwidth; + float lambda, sqrt_lambda_inv; +}; + + +ccl_device void setup_gabor_parameters(GaborParams &gp, float impulses) +{ + float SQRT_PI_OVER_LN2 = sqrtf(M_PI / M_LN2); + + float Gabor_Frequency = 2.0; + float Gabor_Impulse_Weight = 1; + + float Gabor_Truncate = 0.02; + + gp.weight = Gabor_Impulse_Weight; + gp.impulses = impulses; + gp.bandwidth = 1.0; + + float TWO_to_Bandwidth = pow(2.0, gp.bandwidth); + + gp.a = Gabor_Frequency * ((TWO_to_Bandwidth - 1.0) / (TWO_to_Bandwidth + 1.0)) * SQRT_PI_OVER_LN2; + + gp.radius = sqrt(-log(Gabor_Truncate) / float(M_PI)) / gp.a; + gp.radius2 = gp.radius * gp.radius; + gp.radius3 = gp.radius2 * gp.radius; + gp.radius_inv = 1.0 / gp.radius; + + gp.lambda = impulses / (float(1.33333 * M_PI) * gp.radius3); + gp.sqrt_lambda_inv = 1.0 / sqrt(gp.lambda); + + +} + +ccl_device float gabor_kernel(float Weight, float3 omega, float &phi, float Bandwidth, float3 Vector) +{ + float g = exp(-M_PI * Bandwidth*Bandwidth * dot(Vector, Vector)); + float h = cos(M_2PI_F * dot(omega, Vector) + phi); + return Weight * g * h; +} + +ccl_device void getsincos(float omega_t, float& sin_omega_t, float& cos_omega_t) +{ + sin_omega_t = sin(omega_t); + cos_omega_t = cos(omega_t); + +} + +ccl_device void gabor_sample(GaborParams gp, int &rng, float3 &omega, float &phi) +{ + float omega_t = M_2PI_F * rng_uniform(rng); + float cos_omega_p = rng_uniform(rng) * 2.0 - 1.0; + float sin_omega_p = sqrt(1.0 - cos_omega_p*cos_omega_p); + float sin_omega_t, cos_omega_t; + + + getsincos(omega_t, sin_omega_t, cos_omega_t); + + + omega = normalize(make_float3(cos_omega_t*sin_omega_p, sin_omega_t*sin_omega_p, cos_omega_p)); + + phi = M_2PI_F * rng_uniform(rng); +} + + +ccl_device float gabor_cell(GaborParams gp, int c_i[3], float3 x_c_i, int seed) +{ + int rng; + rng_seed(rng, c_i, seed); + + int num_impulses = rng_poisson(rng, gp.impulses); + float sum = 0.0; + + for (int i = 0; i < num_impulses; ++i) { + float xrand = rng_uniform(rng); + float yrand = rng_uniform(rng); + float zrand = rng_uniform(rng); + + float3 x_k_i = (x_c_i - make_float3(xrand, yrand, zrand)) * gp.radius; + + float3 omega; + float phi; + + gabor_sample(gp, rng, omega, phi); + + if (dot(x_k_i, x_k_i) < gp.radius2) { + sum += gabor_kernel(gp.weight, omega, phi, gp.a, x_k_i); + } + } + return sum; +} + + +ccl_device float gabor_grid(GaborParams gp, float3 x_g, int seed) +{ + + float x_g_0 = x_g.x - floorf(x_g.x); + float x_g_1 = x_g.y - floorf(x_g.y); + float x_g_2 = x_g.z - floorf(x_g.z); + + float3 x_c = {x_g_0,x_g_1,x_g_2}; + + int cell[3] = { quick_floor(x_g.x), quick_floor(x_g.y), quick_floor(x_g.z) }; + float sum = 0.0; + + for (int k = -1; k <= 1; k++) { + for (int j = -1; j <= 1; j++) { + for (int i = -1; i <= 1; i++) { + int c_i[3] = { cell[0] + i, cell[1] + j, cell[2] + k }; + float3 x_c_i = x_c - make_float3(i,j,k); + sum += gabor_cell(gp, c_i, x_c_i, seed); + } + } + } + return sum * gp.sqrt_lambda_inv; +} + + CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index 52bea15..a35f2e7 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -59,6 +59,7 @@ typedef enum NodeType { NODE_TEX_WAVE, NODE_TEX_MAGIC, NODE_TEX_NOISE, + NODE_TEX_GABOR, NODE_SHADER_JUMP, NODE_SET_DISPLACEMENT, NODE_GEOMETRY_BUMP_DX, diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 7bd370f..d7e026f 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -783,6 +783,66 @@ void NoiseTextureNode::compile(OSLCompiler& compiler) compiler.add(this, "node_noise_texture"); } +/* Gabor Texture */ + +GaborTextureNode::GaborTextureNode() +: TextureNode("gabor_texture") +{ + add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_GENERATED); + add_input("Scale", SHADER_SOCKET_FLOAT, 1.0f); + add_input("Seed", SHADER_SOCKET_FLOAT, 2.0f); + add_input("Impulse", SHADER_SOCKET_FLOAT, 0.0f); + + add_output("Color", SHADER_SOCKET_COLOR); + add_output("Value", SHADER_SOCKET_FLOAT); +} + +void GaborTextureNode::compile(SVMCompiler& compiler) +{ + ShaderInput *impulse_in = input("Impulse"); + ShaderInput *seed_in = input("Seed"); + ShaderInput *scale_in = input("Scale"); + ShaderInput *vector_in = input("Vector"); + ShaderOutput *color_out = output("Color"); + ShaderOutput *fac_out = output("Value"); + + if(vector_in->link) compiler.stack_assign(vector_in); + if(scale_in->link) compiler.stack_assign(scale_in); + if(seed_in->link) compiler.stack_assign(seed_in); + if(impulse_in->link) compiler.stack_assign(impulse_in); + + int vector_offset = vector_in->stack_offset; + + if(!tex_mapping.skip()) { + vector_offset = compiler.stack_find_offset(SHADER_SOCKET_VECTOR); + tex_mapping.compile(compiler, vector_in->stack_offset, vector_offset); + } + + if(!fac_out->links.empty()) + compiler.stack_assign(fac_out); + if(!color_out->links.empty()) + compiler.stack_assign(color_out); + + compiler.add_node(NODE_TEX_GABOR, + compiler.encode_uchar4(vector_offset, scale_in->stack_offset, seed_in->stack_offset, impulse_in->stack_offset), + compiler.encode_uchar4(color_out->stack_offset, fac_out->stack_offset)); + compiler.add_node( + __float_as_int(scale_in->value.x), + __float_as_int(seed_in->value.x), + __float_as_int(impulse_in->value.x)); + + if(vector_offset != vector_in->stack_offset) + compiler.stack_clear_offset(vector_in->type, vector_offset); +} + +void GaborTextureNode::compile(OSLCompiler& compiler) +{ + tex_mapping.compile(compiler); + + compiler.add(this, "node_gabor_texture"); +} + + /* Voronoi Texture */ static ShaderEnum voronoi_coloring_init() diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 86c4f49..9cdeea6 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -134,6 +134,11 @@ public: SHADER_NODE_CLASS(NoiseTextureNode) }; +class GaborTextureNode : public TextureNode { +public: + SHADER_NODE_CLASS(GaborTextureNode) +}; + class VoronoiTextureNode : public TextureNode { public: SHADER_NODE_CLASS(VoronoiTextureNode) diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index 7f0c249..fdb6e03 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -201,6 +201,7 @@ shader_node_categories = [ NodeItem("ShaderNodeTexEnvironment"), NodeItem("ShaderNodeTexSky"), NodeItem("ShaderNodeTexNoise"), + NodeItem("ShaderNodeTexGabor"), NodeItem("ShaderNodeTexWave"), NodeItem("ShaderNodeTexVoronoi"), NodeItem("ShaderNodeTexMusgrave"), diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 3a11172..ad7d32f 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -744,6 +744,7 @@ struct ShadeResult; #define SH_NODE_COMBHSV 184 #define SH_NODE_BSDF_HAIR 185 #define SH_NODE_LAMP 186 +#define SH_NODE_TEX_GABOR 187 /* custom defines options for Material node */ #define SH_NODE_MAT_DIFF 1 diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index f058bbc..a3cd797 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -3536,6 +3536,7 @@ static void registerShaderNodes(void) register_node_type_sh_tex_environment(); register_node_type_sh_tex_sky(); register_node_type_sh_tex_noise(); + register_node_type_sh_tex_gabor(); register_node_type_sh_tex_wave(); register_node_type_sh_tex_voronoi(); register_node_type_sh_tex_musgrave(); diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 4f7c49a..d20fad7 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -752,6 +752,10 @@ typedef struct NodeTexNoise { NodeTexBase base; } NodeTexNoise; +typedef struct NodeTexGabor { + NodeTexBase base; +} NodeTexGabor; + typedef struct NodeTexVoronoi { NodeTexBase base; int coloring; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index b6a031f..987c916 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3485,6 +3485,12 @@ static void def_sh_tex_noise(StructRNA *srna) def_sh_tex(srna); } +static void def_sh_tex_gabor(StructRNA *srna) +{ + RNA_def_struct_sdna_from(srna, "NodeTexGabor", "storage"); + def_sh_tex(srna); +} + static void def_sh_tex_checker(StructRNA *srna) { RNA_def_struct_sdna_from(srna, "NodeTexChecker", "storage"); diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 16671e8..e911c9b 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -194,6 +194,7 @@ set(SRC shader/nodes/node_shader_tex_magic.c shader/nodes/node_shader_tex_musgrave.c shader/nodes/node_shader_tex_noise.c + shader/nodes/node_shader_tex_gabor.c shader/nodes/node_shader_tex_sky.c shader/nodes/node_shader_tex_voronoi.c shader/nodes/node_shader_tex_wave.c diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h index 0f388a8..072fa1b 100644 --- a/source/blender/nodes/NOD_shader.h +++ b/source/blender/nodes/NOD_shader.h @@ -125,6 +125,7 @@ void register_node_type_sh_tex_magic(void); void register_node_type_sh_tex_wave(void); void register_node_type_sh_tex_musgrave(void); void register_node_type_sh_tex_noise(void); +void register_node_type_sh_tex_gabor (void); void register_node_type_sh_tex_checker(void); void register_node_type_sh_bump(void); diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index f7f7118..60c631c 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -109,6 +109,7 @@ DefNode( ShaderNode, SH_NODE_TEX_ENVIRONMENT, def_sh_tex_environment, "TE DefNode( ShaderNode, SH_NODE_TEX_SKY, def_sh_tex_sky, "TEX_SKY", TexSky, "Sky Texture", "" ) DefNode( ShaderNode, SH_NODE_TEX_GRADIENT, def_sh_tex_gradient, "TEX_GRADIENT", TexGradient, "Gradient Texture", "" ) DefNode( ShaderNode, SH_NODE_TEX_NOISE, def_sh_tex_noise, "TEX_NOISE", TexNoise, "Noise Texture", "" ) +DefNode( ShaderNode, SH_NODE_TEX_GABOR, def_sh_tex_gabor, "TEX_GABOR", TexGabor, "Gabor Texture", "" ) DefNode( ShaderNode, SH_NODE_TEX_MAGIC, def_sh_tex_magic, "TEX_MAGIC", TexMagic, "Magic Texture", "" ) DefNode( ShaderNode, SH_NODE_TEX_WAVE, def_sh_tex_wave, "TEX_WAVE", TexWave, "Wave Texture", "" ) DefNode( ShaderNode, SH_NODE_TEX_MUSGRAVE, def_sh_tex_musgrave, "TEX_MUSGRAVE", TexMusgrave, "Musgrave Texture", "" ) diff --git a/source/blender/nodes/shader/nodes/node_shader_squeeze.c b/source/blender/nodes/shader/nodes/node_shader_squeeze.c deleted file mode 100644 index c884f2c..0000000 --- a/source/blender/nodes/shader/nodes/node_shader_squeeze.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * 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. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/nodes/shader/nodes/node_shader_squeeze.c - * \ingroup shdnodes - */ - - -#include "node_shader_util.h" - -/* **************** VALUE SQUEEZE ******************** */ -static bNodeSocketTemplate sh_node_squeeze_in[] = { - { SOCK_FLOAT, 1, N_("Value"), 0.0f, 0.0f, 0.0f, 0.0f, -100.0f, 100.0f, PROP_NONE}, - { SOCK_FLOAT, 1, N_("Width"), 1.0f, 0.0f, 0.0f, 0.0f, -100.0f, 100.0f, PROP_NONE}, - { SOCK_FLOAT, 1, N_("Center"), 0.0f, 0.0f, 0.0f, 0.0f, -100.0f, 100.0f, PROP_NONE}, - { -1, 0, "" } -}; - -static bNodeSocketTemplate sh_node_squeeze_out[] = { - { SOCK_FLOAT, 0, N_("Value")}, - { -1, 0, "" } -}; - -static void node_shader_exec_squeeze(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out) -{ - float vec[3]; - - nodestack_get_vec(vec, SOCK_FLOAT, in[0]); - nodestack_get_vec(vec + 1, SOCK_FLOAT, in[1]); - nodestack_get_vec(vec + 2, SOCK_FLOAT, in[2]); - - out[0]->vec[0] = 1.0f / (1.0f + powf(M_E, -((vec[0] - vec[2]) * vec[1]))); -} - -static int gpu_shader_squeeze(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) -{ - return GPU_stack_link(mat, "squeeze", in, out); -} - -void register_node_type_sh_squeeze(void) -{ - static bNodeType ntype; - - sh_node_type_base(&ntype, SH_NODE_SQUEEZE, "Squeeze Value", NODE_CLASS_CONVERTOR, 0); - node_type_compatibility(&ntype, NODE_OLD_SHADING); - node_type_socket_templates(&ntype, sh_node_squeeze_in, sh_node_squeeze_out); - node_type_storage(&ntype, "node_squeeze", NULL, NULL); - node_type_exec(&ntype, NULL, NULL, node_shader_exec_squeeze); - node_type_gpu(&ntype, gpu_shader_squeeze); - - nodeRegisterType(&ntype); -} diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_gabor.c b/source/blender/nodes/shader/nodes/node_shader_tex_gabor.c new file mode 100644 index 0000000..b8e37c0 --- /dev/null +++ b/source/blender/nodes/shader/nodes/node_shader_tex_gabor.c @@ -0,0 +1,79 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "../node_shader_util.h" + +/* **************** Gabor ******************** */ + +static bNodeSocketTemplate sh_node_tex_gabor_in[] = { + { SOCK_VECTOR, 1, N_("Vector"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, + { SOCK_FLOAT, 1, N_("Scale"), 5.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f}, + { SOCK_FLOAT, 1, N_("Seed"), 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 16.0f}, + { SOCK_FLOAT, 1, N_("Impulse"), 0.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f}, + { -1, 0, "" } +}; + +static bNodeSocketTemplate sh_node_tex_gabor_out[] = { + { SOCK_RGBA, 0, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 0, N_("Value"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static void node_shader_init_tex_gabor(bNodeTree *UNUSED(ntree), bNode *node) +{ + NodeTexGabor *tex = MEM_callocN(sizeof(NodeTexGabor), "NodeTexGabor"); + default_tex_mapping(&tex->base.tex_mapping, TEXMAP_TYPE_POINT); + default_color_mapping(&tex->base.color_mapping); + + node->storage = tex; +} + +static int node_shader_gpu_tex_gabor(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, + GPUNodeStack *out) +{ + if (!in[0].link) + in[0].link = GPU_attribute(CD_ORCO, ""); + + node_shader_gpu_tex_mapping(mat, node, in, out); + + return GPU_stack_link(mat, "node_tex_gabor", in, out); +} + +/* node type definition */ +void register_node_type_sh_tex_gabor(void) +{ + static bNodeType ntype; + + sh_node_type_base(&ntype, SH_NODE_TEX_GABOR, "Gabor Texture", NODE_CLASS_TEXTURE, 0); + node_type_compatibility(&ntype, NODE_NEW_SHADING); + node_type_socket_templates(&ntype, sh_node_tex_gabor_in, sh_node_tex_gabor_out); + node_type_init(&ntype, node_shader_init_tex_gabor); + node_type_storage(&ntype, "NodeTexGabor", node_free_standard_storage, node_copy_standard_storage); + node_type_gpu(&ntype, node_shader_gpu_tex_gabor); + + nodeRegisterType(&ntype); +}