diff options
author | Ton Roosendaal <ton@blender.org> | 2008-11-12 22:03:50 +0300 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2008-11-12 22:03:50 +0300 |
commit | 8030cb03fd41673b7d687128782a0e21417baaea (patch) | |
tree | b2e25d9a91ecf3713c45a4263f88a934e973e593 /source/blender/nodes/intern/TEX_nodes/TEX_proc.c | |
parent | 3fd3a13efc81ce3eafadd5ab31a154bbc25d6e58 (diff) |
Patch #7897 Texture Nodes!
Robin (Frrr) Allen did a decent job on this, so we can also welcome him
as a member in the svn committers team to maintain it!
I do the first commit with some minor fixes:
- get Makefiles work
- fix rounding issue with tiles on unit faces
- removed UI includes from tex node
A nice doc in wiki is here:
http://wiki.blender.org/index.php/User:Frr/TexnodeManual
On the todo for Robin is:
- When using one or more Texture-input nodes, you cannot edit them by activating
(as works now for Material nodes).
- The new "output node" option fails on the default case, when only one
output node is active. It then shows often a blank menu. Will get fixed asap.
- When using a NodeTree-Texture as input node, the menu for 'active output'
should not show. NodeTree should ignore other nodetrees to keep things sane
for now.
- On a future todo is proper usage of "Dxt" and "Dyt" texture vectors for
superior antialising of checkers/bricks.
General note; I know people are dying to get a full integrated shader system
with nodes. In theory we could merge this with Material Nodetrees... but I
rather wait for a solid and very well thought out design proposal for this,
also including design ideas for unifying with a shader language (GPU, CPU).
For the time being this is a nice extension of current textures. :)
Diffstat (limited to 'source/blender/nodes/intern/TEX_nodes/TEX_proc.c')
-rw-r--r-- | source/blender/nodes/intern/TEX_nodes/TEX_proc.c | 310 |
1 files changed, 310 insertions, 0 deletions
diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_proc.c b/source/blender/nodes/intern/TEX_nodes/TEX_proc.c new file mode 100644 index 00000000000..9078dd1be21 --- /dev/null +++ b/source/blender/nodes/intern/TEX_nodes/TEX_proc.c @@ -0,0 +1,310 @@ +/** + * + * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 "../TEX_util.h" +#include "RE_shader_ext.h" + +/* + In this file: wrappers to use procedural textures as nodes +*/ + + +static bNodeSocketType outputs_both[]= { + { SOCK_RGBA, 0, "Color", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, + { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f }, + { -1, 0, "" } +}; +static bNodeSocketType outputs_color_only[]= { + { SOCK_RGBA, 0, "Color", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, + { -1, 0, "" } +}; + +/* Inputs common to all, #defined because nodes will need their own inputs too */ +#define I 2 /* count */ +#define COMMON_INPUTS \ + { SOCK_RGBA, 1, "Color 1", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, \ + { SOCK_RGBA, 1, "Color 2", 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f } + +/* Calls multitex and copies the result to the outputs. Called by xxx_exec, which handles inputs. */ +static void do_proc(float *result, float *coord, float *col1, float *col2, char is_normal, Tex *tex, short thread) +{ + TexResult texres; + int textype; + + if(is_normal) { + texres.nor = result; + } + else + texres.nor = NULL; + + textype = multitex_thread(tex, coord, 0, 0, 0, &texres, thread, 0); + + if(is_normal) + return; + + if(textype & TEX_RGB) { + QUATCOPY(result, &texres.tr); + } + else { + QUATCOPY(result, col1); + ramp_blend(MA_RAMP_BLEND, result, result+1, result+2, texres.tin, col2); + } +} + +typedef void (*MapFn) (Tex *tex, bNodeStack **in, float *coord, short thread); + +static void texfn( + float *result, + float *coord, + bNode *node, + bNodeStack **in, + char is_normal, + MapFn map_inputs, + short thread) +{ + Tex tex = *((Tex*)(node->storage)); + float col1[4], col2[4]; + tex_input_rgba(col1, in[0], coord, thread); + tex_input_rgba(col2, in[1], coord, thread); + + map_inputs(&tex, in, coord, thread); + + do_proc(result, coord, col1, col2, is_normal, &tex, thread); +} + +static int count_outputs(bNode *node) +{ + bNodeSocket *sock; + int num = 0; + for(sock= node->outputs.first; sock; sock= sock->next) { + num++; + } + return num; +} + +/* Boilerplate generators */ + +#define ProcNoInputs(name) \ + static void name##_map_inputs(Tex *tex, bNodeStack **in, float *coord, short thread) \ + {} + +#define ProcDef(name) \ + static void name##_colorfn(float *result, float *coord, bNode *node, bNodeStack **in, short thread) \ + { \ + texfn(result, coord, node, in, 0, &name##_map_inputs, thread); \ + } \ + static void name##_normalfn(float *result, float *coord, bNode *node, bNodeStack **in, short thread) \ + { \ + texfn(result, coord, node, in, 1, &name##_map_inputs, thread); \ + } \ + static void name##_exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) \ + { \ + int outs = count_outputs(node); \ + if(outs >= 1) tex_output(node, in, out[0], &name##_colorfn); \ + if(outs >= 2) tex_output(node, in, out[1], &name##_normalfn); \ + if(outs >= 1) tex_do_preview(node, out[0], data); \ + } + + +/* --- VORONOI -- */ +static bNodeSocketType voronoi_inputs[]= { + COMMON_INPUTS, + { SOCK_VALUE, 1, "W1", 1.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f }, + { SOCK_VALUE, 1, "W2", 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f }, + { SOCK_VALUE, 1, "W3", 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f }, + { SOCK_VALUE, 1, "W4", 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f }, + + { SOCK_VALUE, 1, "iScale", 1.0f, 0.0f, 0.0f, 0.0f, 0.01f, 10.0f }, + { SOCK_VALUE, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 4.0f }, + + { -1, 0, "" } +}; +static void voronoi_map_inputs(Tex *tex, bNodeStack **in, float *coord, short thread) +{ + tex->vn_w1 = tex_input_value(in[I+0], coord, thread); + tex->vn_w2 = tex_input_value(in[I+1], coord, thread); + tex->vn_w3 = tex_input_value(in[I+2], coord, thread); + tex->vn_w4 = tex_input_value(in[I+3], coord, thread); + + tex->ns_outscale = tex_input_value(in[I+4], coord, thread); + tex->noisesize = tex_input_value(in[I+5], coord, thread); +} +ProcDef(voronoi) + +/* --- BLEND -- */ +static bNodeSocketType blend_inputs[]= { + COMMON_INPUTS, + { -1, 0, "" } +}; +ProcNoInputs(blend) +ProcDef(blend) + +/* -- MAGIC -- */ +static bNodeSocketType magic_inputs[]= { + COMMON_INPUTS, + { SOCK_VALUE, 1, "Turbulence", 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f }, + { -1, 0, "" } +}; +static void magic_map_inputs(Tex *tex, bNodeStack **in, float *coord, short thread) +{ + tex->turbul = tex_input_value(in[I+0], coord, thread); +} +ProcDef(magic) + +/* --- MARBLE --- */ +static bNodeSocketType marble_inputs[]= { + COMMON_INPUTS, + { SOCK_VALUE, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f }, + { SOCK_VALUE, 1, "Turbulence", 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f }, + { -1, 0, "" } +}; +static void marble_map_inputs(Tex *tex, bNodeStack **in, float *coord, short thread) +{ + tex->noisesize = tex_input_value(in[I+0], coord, thread); + tex->turbul = tex_input_value(in[I+1], coord, thread); +} +ProcDef(marble) + +/* --- CLOUDS --- */ +static bNodeSocketType clouds_inputs[]= { + COMMON_INPUTS, + { SOCK_VALUE, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f }, + { -1, 0, "" } +}; +static void clouds_map_inputs(Tex *tex, bNodeStack **in, float *coord, short thread) +{ + tex->noisesize = tex_input_value(in[I+0], coord, thread); +} +ProcDef(clouds) + +/* --- DISTORTED NOISE --- */ +static bNodeSocketType distnoise_inputs[]= { + COMMON_INPUTS, + { SOCK_VALUE, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f }, + { SOCK_VALUE, 1, "Distortion", 1.00f, 0.0f, 0.0f, 0.0f, 0.0000f, 10.0f }, + { -1, 0, "" } +}; +static void distnoise_map_inputs(Tex *tex, bNodeStack **in, float *coord, short thread) +{ + tex->noisesize = tex_input_value(in[I+0], coord, thread); + tex->dist_amount = tex_input_value(in[I+1], coord, thread); +} +ProcDef(distnoise) + +/* --- WOOD --- */ +static bNodeSocketType wood_inputs[]= { + COMMON_INPUTS, + { SOCK_VALUE, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f }, + { SOCK_VALUE, 1, "Turbulence", 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f }, + { -1, 0, "" } +}; +static void wood_map_inputs(Tex *tex, bNodeStack **in, float *coord, short thread) +{ + tex->noisesize = tex_input_value(in[I+0], coord, thread); + tex->turbul = tex_input_value(in[I+1], coord, thread); +} +ProcDef(wood) + +/* --- MUSGRAVE --- */ +static bNodeSocketType musgrave_inputs[]= { + COMMON_INPUTS, + { SOCK_VALUE, 1, "H", 1.0f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f }, + { SOCK_VALUE, 1, "Lacunarity", 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 6.0f }, + { SOCK_VALUE, 1, "Octaves", 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 8.0f }, + + { SOCK_VALUE, 1, "iScale", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 10.0f }, + { SOCK_VALUE, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f }, + { -1, 0, "" } +}; +static void musgrave_map_inputs(Tex *tex, bNodeStack **in, float *coord, short thread) +{ + tex->mg_H = tex_input_value(in[I+0], coord, thread); + tex->mg_lacunarity = tex_input_value(in[I+1], coord, thread); + tex->mg_octaves = tex_input_value(in[I+2], coord, thread); + tex->ns_outscale = tex_input_value(in[I+3], coord, thread); + tex->noisesize = tex_input_value(in[I+4], coord, thread); +} +ProcDef(musgrave) + +/* --- NOISE --- */ +static bNodeSocketType noise_inputs[]= { + COMMON_INPUTS, + { -1, 0, "" } +}; +ProcNoInputs(noise) +ProcDef(noise) + +/* --- STUCCI --- */ +static bNodeSocketType stucci_inputs[]= { + COMMON_INPUTS, + { SOCK_VALUE, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f }, + { SOCK_VALUE, 1, "Turbulence", 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f }, + { -1, 0, "" } +}; +static void stucci_map_inputs(Tex *tex, bNodeStack **in, float *coord, short thread) +{ + tex->noisesize = tex_input_value(in[I+0], coord, thread); + tex->turbul = tex_input_value(in[I+1], coord, thread); +} +ProcDef(stucci) + +/* --- */ + +static void init(bNode *node) +{ + Tex *tex = MEM_callocN(sizeof(Tex), "Tex"); + node->storage= tex; + + default_tex(tex); + tex->type = node->type - TEX_NODE_PROC; + + if(tex->type == TEX_WOOD) + tex->stype = TEX_BANDNOISE; + +} + +/* Node type definitions */ +#define TexDef(TEXTYPE, outputs, name, Name) \ + { NULL, NULL, TEX_NODE_PROC+TEXTYPE, Name, 140,80,140, NODE_CLASS_TEXTURE, \ + NODE_OPTIONS | NODE_PREVIEW, name##_inputs, outputs, "Tex", name##_exec, NULL, init, \ + node_free_standard_storage, node_copy_standard_storage, NULL } + +#define C outputs_color_only +#define CV outputs_both + +bNodeType tex_node_proc_voronoi = TexDef(TEX_VORONOI, CV, voronoi, "Voronoi" ); +bNodeType tex_node_proc_blend = TexDef(TEX_BLEND, C, blend, "Blend" ); +bNodeType tex_node_proc_magic = TexDef(TEX_MAGIC, C, magic, "Magic" ); +bNodeType tex_node_proc_marble = TexDef(TEX_MARBLE, CV, marble, "Marble" ); +bNodeType tex_node_proc_clouds = TexDef(TEX_CLOUDS, CV, clouds, "Clouds" ); +bNodeType tex_node_proc_wood = TexDef(TEX_WOOD, CV, wood, "Wood" ); +bNodeType tex_node_proc_musgrave = TexDef(TEX_MUSGRAVE, CV, musgrave, "Musgrave" ); +bNodeType tex_node_proc_noise = TexDef(TEX_NOISE, C, noise, "Noise" ); +bNodeType tex_node_proc_stucci = TexDef(TEX_STUCCI, CV, stucci, "Stucci" ); +bNodeType tex_node_proc_distnoise = TexDef(TEX_DISTNOISE, CV, distnoise, "Distorted Noise" ); + |