diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index f63f94ab37..44bc28a093 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -762,6 +762,13 @@ static ShaderNode *add_node(Scene *scene,
 		get_tex_mapping(&musgrave->tex_mapping, b_texture_mapping);
 		node = musgrave;
 	}
+	else if (b_node.is_a(&RNA_ShaderNodeTexLyapunov)) {
+		BL::ShaderNodeTexLyapunov b_lyapunov_node(b_node);
+		LyapunovTextureNode *lyapunov = new LyapunovTextureNode();
+		BL::TexMapping b_texture_mapping(b_lyapunov_node.texture_mapping());
+		get_tex_mapping(&lyapunov->tex_mapping, b_texture_mapping);
+		node = lyapunov;
+	}
 	else if(b_node.is_a(&RNA_ShaderNodeTexCoord)) {
 		BL::ShaderNodeTexCoord b_tex_coord_node(b_node);
 		TextureCoordinateNode *tex_coord = new TextureCoordinateNode();
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index 56bcafbce3..bfcd26483b 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -134,6 +134,7 @@ set(SRC_SVM_HEADERS
 	svm/svm_image.h
 	svm/svm_invert.h
 	svm/svm_light_path.h
+	svm/svm_lyapunov.h
 	svm/svm_magic.h
 	svm/svm_mapping.h
 	svm/svm_math.h
diff --git a/intern/cycles/kernel/shaders/CMakeLists.txt b/intern/cycles/kernel/shaders/CMakeLists.txt
index b43f8402d4..02522c20a8 100644
--- a/intern/cycles/kernel/shaders/CMakeLists.txt
+++ b/intern/cycles/kernel/shaders/CMakeLists.txt
@@ -40,6 +40,7 @@ set(SRC_OSL
 	node_layer_weight.osl
 	node_light_falloff.osl
 	node_light_path.osl
+	node_lyapunov_texture.osl
 	node_magic_texture.osl
 	node_mapping.osl
 	node_math.osl
diff --git a/intern/cycles/kernel/shaders/node_lyapunov_texture.osl b/intern/cycles/kernel/shaders/node_lyapunov_texture.osl
new file mode 100644
index 0000000000..8348d25cf2
--- /dev/null
+++ b/intern/cycles/kernel/shaders/node_lyapunov_texture.osl
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * 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.
+ */
+
+ 
+/* 
+ * Lyapunov Shader - in memory of great mathematician Aleksandr Mikhailovich Lyapunov
+ * Original code: Sylvio Sell - maitag.de - Rostock Germany 2013
+ * recoded 2015 for better node integration and artists control
+ * devel task: https://developer.blender.org/T32305
+ * thanks to Thomas Dinges for initial OSL port
+ */
+
+
+#include "stdosl.h"
+#include "node_texture.h"
+
+ 
+/* ------- function that describes behavior of dynamic system ------- */
+
+float func(float x, float p, float p1, float p2)
+{
+    return p1*sin(x+p)*sin(x+p)+p2;
+}
+float deriv(float x, float p, float p1, float p2)
+{
+    return p1*sin(2.0*(x+p));
+}
+
+
+/* ------- sequence (todo: customizing by parameter;) ------- */
+
+void pre_step(output float x, point p, float p1, float p2)
+{
+    for(int i = 0; i < 3; i++) {
+        x = func(x,p[i],p1,p2);
+    }
+}
+
+void main_step(output float index, output int iter, output float x, point p, float p1, float p2, float balance)
+{
+    for(int i = 0; i < 3; i++) {
+        x = func(x,p[i],p1,p2);
+        index += (  log(fabs(deriv(x,p[i],p1,p2)))*balance + deriv(x,p[i],p1,p2)*(1.0-balance)  ) / 2.0;
+        iter++;
+    }
+}
+
+
+/* ------- calculates Lyapunov index ------- */
+
+float lyapunov(point p, float x_start, float iteration_pre, float iteration_main, float p1, float p2, float balance)
+{
+    float x = x_start;
+	int iter_pre =  (int)floor(iteration_pre);
+	int iter_main = (int)floor(iteration_main);
+	float nabla_pre = iteration_pre - (float)iter_pre;
+	float nabla_main = iteration_main - (float)iter_main;
+
+	float index = 0.0;
+	float ableitung = 0.0;
+	int iter = 0;
+
+	/* Pre-iteration */
+	for(int i = 0; i < iter_pre; i++) {
+		pre_step(x,p,p1,p2);
+	}
+
+	if (nabla_pre != 0.0) {
+		float x_pre = x;
+		pre_step(x,p,p1,p2);
+		x = x*nabla_pre + x_pre*(1.0-nabla_pre);
+	}
+
+	/* Main-iteration */
+	for(int i = 0; i < iter_main; i++) {
+		main_step(index, iter, x, p, p1, p2, balance);
+	}
+
+	if (nabla_main == 0.0) {
+		index = (iter != 0) ? index/(float)(iter) : 0.0;
+	}
+	else {
+		float index_pre = (iter != 0) ? index/(float)(iter) : 0.0;
+
+		main_step(index, iter, x, p, p1, p2, balance);
+
+		index = (iter != 0) ? index/(float)(iter) : 0.0;
+		index = index*nabla_main + index_pre*(1.0-nabla_main);
+	}
+
+	return index;
+}
+
+
+/* ------------------ SHADER MAIN ---------------------- */
+
+shader node_lyapunov_texture(
+	float Shift = 0.0,
+	float Balance = 0.0,
+	float Pre_Iteration = 0.0,
+	float Main_Iteration = 1.0,
+	float Param1 = 2.0,
+	float Param2 = 2.0,
+	float Scale = 1.0,
+	point Pos = P,
+	output float Fac = 0.0,
+	output float Positiv = 0.0,
+	output float Negativ = 0.0)
+{
+	/* Calculate Lyapunov Index */
+	float index = lyapunov(Pos*Scale, Shift, Pre_Iteration, Main_Iteration, Param1, Param2, Balance);
+
+	/* separate output */
+	if (index > 0.0) {
+		Positiv = index;
+	}
+	else {
+		Negativ = -index;
+	}
+
+    Fac = 0.5 + index; 
+
+}
+
diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h
index 88ec7fe6fc..07feba3133 100644
--- a/intern/cycles/kernel/svm/svm.h
+++ b/intern/cycles/kernel/svm/svm.h
@@ -163,6 +163,7 @@ CCL_NAMESPACE_END
 #include "svm_brightness.h"
 #include "svm_invert.h"
 #include "svm_light_path.h"
+#include "svm_lyapunov.h"
 #include "svm_magic.h"
 #include "svm_mapping.h"
 #include "svm_normal.h"
@@ -401,6 +402,9 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ccl_a
 			case NODE_TEX_BRICK:
 				svm_node_tex_brick(kg, sd, stack, node, &offset);
 				break;
+			case NODE_TEX_LYAPUNOV:
+				svm_node_tex_lyapunov(kg, sd, stack, node, &offset);
+				break;
 #  endif  /* __TEXTURES__ */
 #  ifdef __EXTRA_NODES__
 			case NODE_NORMAL:
diff --git a/intern/cycles/kernel/svm/svm_lyapunov.h b/intern/cycles/kernel/svm/svm_lyapunov.h
new file mode 100644
index 0000000000..78449c1901
--- /dev/null
+++ b/intern/cycles/kernel/svm/svm_lyapunov.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * 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.
+ */
+
+/* 
+ * Lyapunov Shader - in memory of great mathematician Aleksandr Mikhailovich Lyapunov
+ * coded by Sylvio Sell - maitag.de - Rostock Germany 2013
+ * devel task: https://developer.blender.org/T32305
+ * for blender internal renderer equivalent look at: source/blender/render/intern/source/render_texture.c
+ */
+
+CCL_NAMESPACE_BEGIN
+
+/* Lyapunov */
+
+//__device_noinline float svm_lyapunov(float3 p, float lyap_iteration_pre, float lyap_iteration_main, float lyap_param1, float lyap_param2)
+ccl_device float svm_lyapunov(float3 p, float lyap_iteration_pre, float lyap_iteration_main, float lyap_param1, float lyap_param2, float x, float balance)
+{
+	float a = p.x;
+	float b = p.y;
+	float c = p.z;
+
+	int iter_pre =  floor_to_int(lyap_iteration_pre);
+	int iter_main = floor_to_int(lyap_iteration_main);
+	float nabla_pre = lyap_iteration_pre - (float)iter_pre;
+	float nabla_main = lyap_iteration_main - (float)iter_main;
+	float p1 = lyap_param1;
+	float p2 = lyap_param2;
+	//float x = shift;
+	float x_pre;
+	float index = 0.0f;
+	float index_pre;
+	float ableitung;
+
+	int i;
+	int iter = 0;
+
+	/* pre-iteration */
+	for(i = 0; i < iter_pre; i++)
+	{
+			x = p1*sinf(x+a)*sinf(x+a)+p2;
+			x = p1*sinf(x+b)*sinf(x+b)+p2;
+			x = p1*sinf(x+c)*sinf(x+c)+p2;
+	}
+
+	if (nabla_pre != 0.0f)
+	{
+		x_pre = x;
+		x = p1*sinf(x+a)*sinf(x+a)+p2;
+		x = p1*sinf(x+b)*sinf(x+b)+p2;
+		x = p1*sinf(x+c)*sinf(x+c)+p2;
+		x = x*nabla_pre + x_pre*(1.0f-nabla_pre);
+	}
+
+	/* main-iteration */
+	for(i = 0; i < iter_main; i++)
+	{
+		x = p1*sinf(x+a)*sinf(x+a)+p2;
+		ableitung = 2.0f*p1*sinf(x+a)*cosf(x+a);
+		if (ableitung != 0.0f) { index += ( logf(fabsf(ableitung))*balance + ableitung*(1.0-balance) )/2.0f; iter++; }
+
+		x = p1*sinf(x+b)*sinf(x+b)+p2;
+		ableitung = 2.0f*p1*sinf(x+b)*cosf(x+b);
+		if (ableitung != 0.0f) { index += ( logf(fabsf(ableitung))*balance + ableitung*(1.0-balance) )/2.0f; iter++; }
+
+		x = p1*sinf(x+c)*sinf(x+c)+p2;
+		ableitung = 2.0f*p1*sinf(x+c)*cosf(x+c);
+		if (ableitung != 0.0f) { index +=  (logf(fabsf(ableitung))*balance + ableitung*(1.0-balance) )/2.0f; iter++; }
+	}
+
+
+	if (nabla_main == 0.0f)
+	{
+		index = (iter != 0) ? index/(float)(iter) : 0.0f;
+	}
+	else
+	{
+		index_pre = (iter != 0) ? index/(float)(iter) : 0.0f;
+
+		x = p1*sinf(x+a)*sinf(x+a)+p2;
+		ableitung = 2.0f*p1*sinf(x+a)*cosf(x+a);
+		if (ableitung != 0.0f) { index += logf(fabsf(ableitung)); iter++; }
+
+		x = p1*sinf(x+b)*sinf(x+b)+p2;
+		ableitung = 2.0f*p1*sinf(x+b)*cosf(x+b);
+		if (ableitung != 0.0f) { index += logf(fabsf(ableitung)); iter++; }
+
+		x = p1*sinf(x+c)*sinf(x+c)+p2;
+		ableitung = 2.0f*p1*sinf(x+c)*cosf(x+c);
+		if (ableitung != 0.0f) { index += logf(fabsf(ableitung)); iter++; }
+
+		index = (iter != 0) ? index/(float)(iter) : 0.0f;
+		index = index*nabla_main + index_pre*(1.0f-nabla_main);
+	}
+
+	return(index);
+}
+
+ccl_device void svm_node_tex_lyapunov(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
+{
+	uint4 node2 = read_node(kg, offset);
+	uint4 node3 = read_node(kg, offset);
+
+	/* Input and Output Sockets */
+	uint co_offset, fac_offset, positiv_offset, negativ_offset;
+	uint scale_offset, shift_offset, balance_offset, iteration_pre_offset;
+	uint iteration_main_offset, param1_offset, param2_offset;
+
+	decode_node_uchar4(node.y, &co_offset, &fac_offset, &positiv_offset, &negativ_offset);
+	decode_node_uchar4(node.z, &scale_offset, &shift_offset, &balance_offset, &iteration_pre_offset);
+	decode_node_uchar4(node.w, &iteration_main_offset, &param1_offset, &param2_offset, NULL);
+
+	float3 co = stack_load_float3(stack, co_offset);
+	
+	float scale = stack_load_float_default(stack, scale_offset, node2.x);
+	float shift = stack_load_float_default(stack, shift_offset, node2.y);
+	float balance = stack_load_float_default(stack, balance_offset, node2.z);
+	float iteration_pre = stack_load_float_default(stack, iteration_pre_offset, node2.w);
+
+	float iteration_main = stack_load_float_default(stack, iteration_main_offset, node3.x);
+	float param1 = stack_load_float_default(stack, param1_offset, node3.y);
+	float param2 = stack_load_float_default(stack, param2_offset, node3.z);
+
+	float positiv = 0.0f;
+	float negativ = 0.0f;
+	float index = svm_lyapunov(co*scale*4, iteration_pre, iteration_main, param1, param2, shift, balance);
+	if (index > 0.0) positiv = index; else negativ = -index;
+
+	if(stack_valid(fac_offset))
+		stack_store_float(stack, fac_offset, 0.5 + index);
+	if(stack_valid(positiv_offset))
+		stack_store_float(stack, positiv_offset, positiv);
+	if(stack_valid(negativ_offset))
+		stack_store_float(stack, negativ_offset, negativ);
+}
+
+CCL_NAMESPACE_END
+
diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h
index 5adf7d34f7..c09408cf1d 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -84,6 +84,7 @@ typedef enum ShaderNodeType {
 	NODE_TEX_VORONOI,
 	NODE_TEX_MUSGRAVE,
 	NODE_TEX_WAVE,
+	NODE_TEX_LYAPUNOV,
 	NODE_TEX_MAGIC,
 	NODE_TEX_NOISE,
 	NODE_SHADER_JUMP,
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index c7f37a13fb..bc803181dd 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -1180,6 +1180,87 @@ void MagicTextureNode::compile(OSLCompiler& compiler)
 	compiler.add(this, "node_magic_texture");
 }
 
+/* Lyapunov Texture */
+
+NODE_DEFINE(LyapunovTextureNode)
+{
+	NodeType* type = NodeType::add("lyapunov_texture", create, NodeType::SHADER);
+
+	TEXTURE_MAPPING_DEFINE(LyapunovTextureNode);
+
+	SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
+	SOCKET_IN_FLOAT(shift, "Shift", 0.0f);
+	SOCKET_IN_FLOAT(balance, "Balance", 0.0f);
+	SOCKET_IN_FLOAT(iteration_pre, "Pre Iterations", 0.0f);
+	SOCKET_IN_FLOAT(iteration_main, "Main Iterations", 1.0f);
+	SOCKET_IN_FLOAT(param1, "Param1", 2.0f);
+	SOCKET_IN_FLOAT(param2, "Param2", 2.0f);
+	SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED);
+
+	SOCKET_OUT_FLOAT(fac, "Fac");
+	SOCKET_OUT_FLOAT(positiv, "Positiv");
+	SOCKET_OUT_FLOAT(negativ, "Negativ");
+
+	return type;
+}
+
+LyapunovTextureNode::LyapunovTextureNode()
+: TextureNode(node_type)
+{
+}
+
+void LyapunovTextureNode::compile(SVMCompiler& compiler)
+{
+	ShaderInput *vector_in = input("Vector");
+	ShaderInput *scale_in = input("Scale");
+	ShaderInput *shift_in = input("Shift");
+	ShaderInput *balance_in = input("Balance");
+	ShaderInput *iteration_pre_in = input("Pre Iterations");
+	ShaderInput *iteration_main_in = input("Main Iterations");
+	ShaderInput *param1_in = input("Param1");
+	ShaderInput *param2_in = input("Param2");
+
+	//ShaderOutput *color_out = output("Color");
+	ShaderOutput *fac_out = output("Fac");
+	ShaderOutput *positiv_out = output("Positiv");
+	ShaderOutput *negativ_out = output("Negativ");
+
+	int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
+
+	compiler.add_node(NODE_TEX_LYAPUNOV,
+		compiler.encode_uchar4(
+			vector_offset,
+			compiler.stack_assign_if_linked(fac_out),
+			compiler.stack_assign_if_linked(positiv_out),
+			compiler.stack_assign_if_linked(negativ_out)),
+		compiler.encode_uchar4(
+			compiler.stack_assign_if_linked(scale_in),
+			compiler.stack_assign_if_linked(shift_in),
+			compiler.stack_assign_if_linked(balance_in),
+			compiler.stack_assign_if_linked(iteration_pre_in)),
+		compiler.encode_uchar4(
+			compiler.stack_assign_if_linked(iteration_main_in),
+			compiler.stack_assign_if_linked(param1_in),
+			compiler.stack_assign_if_linked(param2_in)));
+	compiler.add_node(
+		__float_as_int(scale),
+		__float_as_int(shift),
+		__float_as_int(balance),
+		__float_as_int(iteration_pre));
+	compiler.add_node(
+		__float_as_int(iteration_main),
+		__float_as_int(param1),
+		__float_as_int(param2));
+
+	tex_mapping.compile_end(compiler, vector_in, vector_offset);
+}
+
+void LyapunovTextureNode::compile(OSLCompiler& compiler)
+{
+	tex_mapping.compile(compiler);
+	compiler.add(this, "node_lyapunov_texture");
+}
+
 /* Checker Texture */
 
 NODE_DEFINE(CheckerTextureNode)
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index eb0f7977dd..86d67d34aa 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -225,6 +225,16 @@ public:
 	float scale, distortion;
 };
 
+class LyapunovTextureNode : public TextureNode {
+public:
+	SHADER_NODE_CLASS(LyapunovTextureNode)
+
+	virtual int get_group() { return NODE_GROUP_LEVEL_2; }
+
+	float shift, balance, iteration_pre, iteration_main, param1, param2, scale;
+	float3 vector;	
+};
+
 class CheckerTextureNode : public TextureNode {
 public:
 	SHADER_NODE_CLASS(CheckerTextureNode)
diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py
index caf19a9e46..a7659785c3 100644
--- a/release/scripts/startup/bl_ui/properties_texture.py
+++ b/release/scripts/startup/bl_ui/properties_texture.py
@@ -386,6 +386,58 @@ class TEXTURE_PT_marble(TextureTypePanel, Panel):
         col.prop(tex, "nabla")
 
 
+class TEXTURE_PT_lyapunov(TextureTypePanel, Panel):
+    bl_label = "Lyapunov"
+    tex_type = 'LYAPUNOV'
+    COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+
+    def draw(self, context):
+        layout = self.layout
+        tex = context.texture
+
+        layout.prop(tex, "lyap_color_type", expand=True)
+
+        row = layout.row()
+        if tex.lyap_color_type in {'RGB', 'RGBA'}:
+            row.prop(tex, "lyap_neg_color_r", text="")
+            row.prop(tex, "lyap_mid_color_r", text="")
+            row.prop(tex, "lyap_pos_color_r", text="")
+        else:
+            row.prop(tex, "lyap_intensity_spreading")
+
+        split = layout.split()
+        row = split.row()
+
+        sub = row.row()
+        sub.active = tex.lyap_render_type in {'ALL', 'NEG'}
+        sub.prop(tex, "lyap_neg_invert")
+        sub.prop(tex, "lyap_neg_scale")
+
+        sub1 = row.row()
+        sub1.active = tex.lyap_render_type in {'ALL', 'POS'}
+        sub1.prop(tex, "lyap_pos_invert")
+        sub1.prop(tex, "lyap_pos_scale")
+
+        layout.prop(tex, "lyap_render_type", expand=True)
+
+        split = layout.split()
+        col = split.column()
+
+        col.prop(tex, "lyap_iteration_pre")
+        col.prop(tex, "lyap_iteration_main")
+
+        col = split.column()
+
+        col.prop(tex, "lyap_param1")
+        col.prop(tex, "lyap_param2")
+
+        split = layout.split()
+        row = split.row()
+
+        row.prop(tex, "noise_scale", text="Size")
+        row.prop(tex, "nabla")
+
+
 class TEXTURE_PT_magic(TextureTypePanel, Panel):
     bl_label = "Magic"
     tex_type = 'MAGIC'
diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index 6935830278..8c0f46f176 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -245,6 +245,7 @@ shader_node_categories = [
         NodeItem("ShaderNodeTexWave"),
         NodeItem("ShaderNodeTexVoronoi"),
         NodeItem("ShaderNodeTexMusgrave"),
+        NodeItem("ShaderNodeTexLyapunov"),
         NodeItem("ShaderNodeTexGradient"),
         NodeItem("ShaderNodeTexMagic"),
         NodeItem("ShaderNodeTexChecker"),
@@ -442,6 +443,7 @@ texture_node_categories = [
         NodeItem("TextureNodeTexWood"),
         NodeItem("TextureNodeTexMusgrave"),
         NodeItem("TextureNodeTexStucci"),
+        NodeItem("TextureNodeTexLyapunov"),
         ]),
     TextureNodeCategory("TEX_CONVERTOR", "Converter", items=[
         NodeItem("TextureNodeMath"),
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 546f0d97c2..b2fd04cacb 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -747,6 +747,7 @@ struct ShadeResult;
 #define SH_NODE_TEX_WAVE				149
 #define SH_NODE_TEX_NOISE				150
 #define SH_NODE_TEX_MUSGRAVE			152
+#define SH_NODE_TEX_LYAPUNOV			153
 #define SH_NODE_TEX_COORD				155
 #define SH_NODE_ADD_SHADER				156
 #define SH_NODE_TEX_ENVIRONMENT			157
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index f16e8f328d..4fe461df8a 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -3598,6 +3598,7 @@ static void registerShaderNodes(void)
 	register_node_type_sh_tex_musgrave();
 	register_node_type_sh_tex_gradient();
 	register_node_type_sh_tex_magic();
+	register_node_type_sh_tex_lyapunov();
 	register_node_type_sh_tex_checker();
 	register_node_type_sh_tex_brick();
 	register_node_type_sh_tex_pointdensity();
@@ -3648,6 +3649,7 @@ static void registerTextureNodes(void)
 	register_node_type_tex_proc_clouds();
 	register_node_type_tex_proc_wood();
 	register_node_type_tex_proc_musgrave();
+	register_node_type_tex_proc_lyapunov();
 	register_node_type_tex_proc_noise();
 	register_node_type_tex_proc_stucci();
 	register_node_type_tex_proc_distnoise();
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 2d3ecad19a..810ec9abdd 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -643,6 +643,35 @@ void BKE_texture_default(Tex *tex)
 	tex->vn_mexp = 2.5;
 	tex->vn_distm = 0;
 	tex->vn_coltype = 0;
+	/* lyapunov */
+	tex->lyap_render_type = TEX_LYAP_ALL;
+	tex->lyap_color_type = TEX_LYAP_INT;
+	tex->lyap_iteration_pre = 0.0f;
+	tex->lyap_iteration_main = 1.0f;
+
+	tex->lyap_neg_scale = 0.5f;
+	tex->lyap_pos_scale = 0.5f;
+
+	tex->lyap_flag = 1;
+
+	tex->lyap_param1 = 2.0f;
+	tex->lyap_param2 = 2.0f;
+
+	tex->lyap_neg_color_r = 0.0f;
+	tex->lyap_neg_color_g = 0.0f;
+	tex->lyap_neg_color_b = 1.0f;
+	tex->lyap_neg_color_a = 1.0f;
+
+	tex->lyap_mid_color_r = 0.0f;
+	tex->lyap_mid_color_g = 0.0f;
+	tex->lyap_mid_color_b = 0.0f;
+	tex->lyap_mid_color_a = 1.0f;
+
+	tex->lyap_pos_color_r = 1.0f;
+	tex->lyap_pos_color_g = 0.0f;
+	tex->lyap_pos_color_b = 0.0f;
+	tex->lyap_pos_color_a = 1.0f;
+	/* -------- */
 
 	if (tex->env) {
 		tex->env->stype = ENV_ANIM;
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 7b08b8368b..2734e45fb0 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -928,6 +928,20 @@ static void node_shader_buts_tex_magic(uiLayout *layout, bContext *UNUSED(C), Po
 	uiItemR(layout, ptr, "turbulence_depth", 0, NULL, ICON_NONE);
 }
 
+static void node_shader_buts_tex_lyapunov(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+/*	uiLayout *col, *row;
+	
+	col = uiLayoutColumn(layout, true);
+
+	row = uiLayoutRow(col, false);
+	uiItemR(row, ptr, "lyap_fac_type", 0, NULL, ICON_NONE);
+	row = uiLayoutRow(col, false);
+	uiItemR(row, ptr, "lyap_render_type", 0, NULL, ICON_NONE);
+*/
+//	uiItemR(layout, ptr, "shift", 0, NULL, ICON_NONE);
+}
+
 static void node_shader_buts_tex_brick(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
 {
 	uiLayout *col;
@@ -1204,6 +1218,9 @@ static void node_shader_set_butfunc(bNodeType *ntype)
 		case SH_NODE_TEX_MAGIC:
 			ntype->draw_buttons = node_shader_buts_tex_magic;
 			break;
+		case SH_NODE_TEX_LYAPUNOV:
+			ntype->draw_buttons = node_shader_buts_tex_lyapunov;
+			break;
 		case SH_NODE_TEX_BRICK:
 			ntype->draw_buttons = node_shader_buts_tex_brick;
 			break;
@@ -2778,6 +2795,19 @@ static void node_texture_buts_proc(uiLayout *layout, bContext *UNUSED(C), Pointe
 			uiItemR(row, &tex_ptr, "noise_basis_2", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
 			break;
 
+		case TEX_LYAPUNOV:
+			row = uiLayoutRow(col, false);
+			uiItemR(row, &tex_ptr, "lyap_color_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+			row = uiLayoutRow(col, false);
+			uiItemR(row, &tex_ptr, "lyap_intensity_spreading", UI_ITEM_R_EXPAND, IFACE_("spread"), ICON_NONE);
+			row = uiLayoutRow(col, false);
+			uiItemR(row, &tex_ptr, "lyap_pos_invert", UI_ITEM_R_EXPAND, IFACE_("invert pos"), ICON_NONE);
+			row = uiLayoutRow(col, false);
+			uiItemR(row, &tex_ptr, "lyap_neg_invert", UI_ITEM_R_EXPAND, IFACE_("invert neg"), ICON_NONE);
+			row = uiLayoutRow(col, false);
+			uiItemR(row, &tex_ptr, "lyap_render_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+			break;
+
 		case TEX_MAGIC:
 			uiItemR(col, &tex_ptr, "noise_depth", 0, NULL, ICON_NONE);
 			break;
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 4416b6494f..aabf6cb9d9 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -3406,6 +3406,99 @@ void node_tex_musgrave(vec3 co,
 	color = vec4(fac, fac, fac, 1.0);
 }
 
+#ifdef BIT_OPERATIONS
+float lyapunov_func(float x, float p, float p1, float p2)
+{
+    return p1*sin(x+p)*sin(x+p)+p2;
+}
+
+float lyapunov_deriv(float x, float p, float p1, float p2)
+{
+    return p1*sin(2.0*(x+p));
+}
+
+void lyapunov_pre_step(inout float x, vec3 p, float p1, float p2)
+{
+    x = lyapunov_func(x,p.x,p1,p2);
+    x = lyapunov_func(x,p.y,p1,p2);
+    x = lyapunov_func(x,p.z,p1,p2);
+}
+
+void lyapunov_main_step(inout float index, inout int iter, inout float x, vec3 p, float p1, float p2, float balance)
+{
+    x = lyapunov_func(x,p.x,p1,p2);
+    index += (  log(abs(lyapunov_deriv(x,p.x,p1,p2)))*balance + lyapunov_deriv(x,p.x,p1,p2)*(1.0-balance)  ) / 2.0;
+    x = lyapunov_func(x,p.y,p1,p2);
+    index += (  log(abs(lyapunov_deriv(x,p.y,p1,p2)))*balance + lyapunov_deriv(x,p.y,p1,p2)*(1.0-balance)  ) / 2.0;
+    x = lyapunov_func(x,p.z,p1,p2);
+    index += (  log(abs(lyapunov_deriv(x,p.z,p1,p2)))*balance + lyapunov_deriv(x,p.z,p1,p2)*(1.0-balance)  ) / 2.0;
+    iter = iter + 3;
+}
+#endif  // BIT_OPERATIONS
+
+void node_tex_lyapunov(vec3 co, float shift, float balance, float iteration_pre, float iteration_main, float param1, float param2, float scale, out float fac, out float positiv, out float negativ)
+{
+#ifdef BIT_OPERATIONS
+	float x = shift;
+	vec3 p = co * scale*4;
+	int iter_pre =  int(floor(iteration_pre));
+	int iter_main = int(floor(iteration_main));
+	float nabla_pre = iteration_pre - float(iter_pre);
+	float nabla_main = iteration_main - float(iter_main);
+	
+	float index = 0.0;
+	int iter = 0;
+	
+	// pre-iteration
+	for (int i = 0; i < 21; i++) {
+		if (i < iter_pre)
+		{
+			lyapunov_pre_step(x, p, param1, param2);
+		}
+	}
+	if (nabla_pre != 0.0) {
+		float x_pre = x;
+		lyapunov_pre_step(x, p, param1, param2);
+		x = x*nabla_pre + x_pre*(1.0-nabla_pre);
+	}
+		
+	// main-iteration
+	for (int i = 0; i < 201; i++) {
+		if (i < iter_main)
+		{
+			lyapunov_main_step(index, iter, x, p, param1, param2, balance);
+		}
+	}
+	
+	if (nabla_main == 0.0) {
+		index = (iter != 0) ? index/float(iter) : 0.0;
+	}
+	else {
+		float index_pre = (iter != 0) ? index/float(iter) : 0.0;
+
+		lyapunov_main_step(index, iter, x, p, param1, param2, balance);
+
+		index = (iter != 0) ? index/float(iter) : 0.0;
+		index = index*nabla_main + index_pre*(1.0-nabla_main);
+	}
+
+	if (index > 0.0) {
+		positiv = index;
+		negativ = 0.0;
+	}
+	else {
+		negativ = -index;
+		positiv = 0.0;
+	}
+	fac = 0.5 + index;
+
+#else  // BIT_OPERATIONS
+	fac = 1.0;
+	positiv = 1.0;
+	negativ = 1.0;
+#endif  // BIT_OPERATIONS
+}
+
 void node_tex_sky(vec3 co, out vec4 color)
 {
 	color = vec4(1.0);
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 3a7e2b6f7f..7928d5d7a3 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -789,6 +789,10 @@ typedef struct NodeTexMagic {
 	int depth;
 	int pad;
 } NodeTexMagic;
+ 
+typedef struct NodeTexLyapunov {
+	NodeTexBase base;
+} NodeTexLyapunov;
 
 typedef struct NodeShaderAttribute {
 	char name[64];
@@ -975,7 +979,7 @@ typedef struct NodeSunBeams {
 #define SHD_MUSGRAVE_HYBRID_MULTIFRACTAL	2
 #define SHD_MUSGRAVE_RIDGED_MULTIFRACTAL	3
 #define SHD_MUSGRAVE_HETERO_TERRAIN			4
-
+ 
 /* wave texture */
 #define SHD_WAVE_BANDS		0
 #define SHD_WAVE_RINGS		1
diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h
index 995d7645dc..32ee482f87 100644
--- a/source/blender/makesdna/DNA_texture_types.h
+++ b/source/blender/makesdna/DNA_texture_types.h
@@ -263,6 +263,30 @@ typedef struct Tex {
 	char use_nodes;
 	char pad[7];
 	
+	
+	/* Lyapunov parameters */
+	short lyap_render_type , lyap_color_type, lyap_flag, pad4;
+	float lyap_iteration_pre, lyap_iteration_main;
+
+	float lyap_neg_scale, lyap_pos_scale;
+
+	float lyap_param1, lyap_param2;
+
+	float lyap_neg_color_r;
+	float lyap_neg_color_g;
+	float lyap_neg_color_b;
+	float lyap_neg_color_a;
+
+	float lyap_mid_color_r;
+	float lyap_mid_color_g;
+	float lyap_mid_color_b;
+	float lyap_mid_color_a;
+
+	float lyap_pos_color_r;
+	float lyap_pos_color_g;
+	float lyap_pos_color_b;
+	float lyap_pos_color_a;
+	
 } Tex;
 
 /* used for mapping and texture nodes. note: rot is now in radians */
@@ -323,6 +347,7 @@ typedef struct ColorMapping {
 #define TEX_POINTDENSITY	14
 #define TEX_VOXELDATA		15
 #define TEX_OCEAN		16
+#define TEX_LYAPUNOV	17
 
 /* musgrave stype */
 #define TEX_MFRACTAL		0
@@ -661,7 +686,15 @@ enum {
 /* flag */
 #define TEX_OCN_GENERATE_NORMALS	1	
 #define TEX_OCN_XZ				2	
-	
+
+/******************** Lyapunov **************************/
+#define TEX_LYAP_ALL			0
+#define TEX_LYAP_POS			1
+#define TEX_LYAP_NEG			2
+
+#define TEX_LYAP_INT			0
+#define TEX_LYAP_RGB			1
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index f97a5735c9..f794dc64b9 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -367,6 +367,7 @@ extern StructRNA RNA_LineStyleThicknessModifier_Material;
 extern StructRNA RNA_LineStyleThicknessModifier_Noise;
 extern StructRNA RNA_LineStyleThicknessModifier_Tangent;
 extern StructRNA RNA_LockedTrackConstraint;
+extern StructRNA RNA_LyapunovTexture;
 extern StructRNA RNA_Macro;
 extern StructRNA RNA_MagicTexture;
 extern StructRNA RNA_MarbleTexture;
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index a9e7842821..b078ff0297 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -3883,6 +3883,42 @@ static void def_sh_tex_magic(StructRNA *srna)
 	RNA_def_property_update(prop, 0, "rna_Node_update");
 }
 
+static void def_sh_tex_lyapunov(StructRNA *srna)
+{
+/*	static EnumPropertyItem prop_fac_type[] = {
+	    {SHD_LYAPUNOV_SPREAD, "SPREAD", 0, "spread", "spread indices for fac output"},
+		{SHD_LYAPUNOV_ABS, "ABS", 0, "abs", "absolute values from indices"},
+		{SHD_LYAPUNOV_REAL, "REAL", 0, "real", "real indices"},
+		{SHD_LYAPUNOV_COLOR, "COLOR", 0, "color", "get fac output from used colors"},
+		{0, NULL, 0, NULL, NULL}
+	};
+
+	static EnumPropertyItem prop_render_type[] = {
+	    {SHD_LYAPUNOV_NEG, "NEG", 0, "negative", "Negative Lyapunov indices only"},
+	    {SHD_LYAPUNOV_ALL, "ALL", 0, "both", "Positive and negative indices"},
+	    {SHD_LYAPUNOV_POS, "POS", 0, "positive", "Positive Lyapunov indices only"},
+		{0, NULL, 0, NULL, NULL}
+	};
+
+	PropertyRNA *prop;
+*/
+	RNA_def_struct_sdna_from(srna, "NodeTexLyapunov", "storage");
+	def_sh_tex(srna);
+/*
+	prop = RNA_def_property(srna, "lyap_fac_type", PROP_ENUM, PROP_NONE);
+	RNA_def_property_enum_sdna(prop, NULL, "lyap_fac_type");
+	RNA_def_property_enum_items(prop, prop_fac_type);
+	RNA_def_property_ui_text(prop, "Fac Type", "");
+	RNA_def_property_update(prop, 0, "rna_Node_update");
+
+	prop = RNA_def_property(srna, "lyap_render_type", PROP_ENUM, PROP_NONE);
+	RNA_def_property_enum_sdna(prop, NULL, "lyap_render_type");
+	RNA_def_property_enum_items(prop, prop_render_type);
+	RNA_def_property_ui_text(prop, "Render Type", "");
+	RNA_def_property_update(prop, 0, "rna_Node_update");
+*/
+}
+
 static void def_sh_tex_musgrave(StructRNA *srna)
 {
 	static EnumPropertyItem prop_musgrave_type[] = {
diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c
index 1e88585a28..005b0a2856 100644
--- a/source/blender/makesrna/intern/rna_texture.c
+++ b/source/blender/makesrna/intern/rna_texture.c
@@ -73,6 +73,7 @@ EnumPropertyItem rna_enum_texture_type_items[] = {
 	{TEX_MAGIC, "MAGIC", ICON_TEXTURE, "Magic", "Procedural - color texture based on trigonometric functions"},
 	{TEX_MARBLE, "MARBLE", ICON_TEXTURE, "Marble", "Procedural - marble-like noise texture with wave generated bands"},
 	{TEX_MUSGRAVE, "MUSGRAVE", ICON_TEXTURE, "Musgrave", "Procedural - highly flexible fractal noise texture"},
+    {TEX_LYAPUNOV, "LYAPUNOV", ICON_TEXTURE, "Lyapunov", "Procedural - color texture based on Lyapunovs fat fractals"},
 	{TEX_NOISE, "NOISE", ICON_TEXTURE, "Noise",
 	            "Procedural - random noise, gives a different result every time, for every frame, for every pixel"},
 	{TEX_OCEAN, "OCEAN", ICON_TEXTURE, "Ocean", "Use a texture generated by an Ocean modifier"},
@@ -156,6 +157,8 @@ static StructRNA *rna_Texture_refine(struct PointerRNA *ptr)
 			return &RNA_WoodTexture;
 		case TEX_OCEAN:
 			return &RNA_OceanTexture;
+		case TEX_LYAPUNOV:
+			return &RNA_LyapunovTexture;
 		default:
 			return &RNA_Texture;
 	}
@@ -1576,6 +1579,119 @@ static void rna_def_texture_voronoi(BlenderRNA *brna)
 	RNA_def_property_update(prop, 0, "rna_Texture_update");
 }
 
+static void rna_def_texture_lyapunov(BlenderRNA *brna)
+{
+	StructRNA *srna;
+	PropertyRNA *prop;
+
+	static EnumPropertyItem prop_render_type[] = {
+	    {TEX_LYAP_NEG, "NEG", 0, "negativ", "Negative Lyapunov indices only"},
+	    {TEX_LYAP_ALL, "ALL", 0, "both", "Positive and negative indices"},
+	    {TEX_LYAP_POS, "POS", 0, "positive", "Positive Lyapunov indices only"},
+		{0, NULL, 0, NULL, NULL}
+	};
+
+	static EnumPropertyItem prop_color_type[] = {
+	    {TEX_LYAP_INT, "INTENSITY", 0, "intensity", "Intensity only, you can use a color ramp to colorize"},
+		{TEX_LYAP_RGB, "RGB", 0, "colors", "Renders RGBA values"},
+		{0, NULL, 0, NULL, NULL}
+	};
+
+	srna = RNA_def_struct(brna, "LyapunovTexture", "Texture");
+	RNA_def_struct_ui_text(srna, "Lyapunov Texture", "semmi's procedural fat fractal texture");
+	RNA_def_struct_sdna(srna, "Tex");
+
+	prop = RNA_def_property(srna, "lyap_render_type", PROP_ENUM, PROP_NONE);
+	RNA_def_property_enum_items(prop, prop_render_type);
+	RNA_def_property_ui_text(prop, "Render Type", "");
+	RNA_def_property_update(prop, 0, "rna_Texture_update");
+
+	prop = RNA_def_property(srna, "lyap_color_type", PROP_ENUM, PROP_NONE);
+	RNA_def_property_enum_items(prop, prop_color_type);
+	RNA_def_property_ui_text(prop, "Color Type", "");
+	RNA_def_property_update(prop, 0, "rna_Texture_update");
+
+	prop = RNA_def_property(srna, "lyap_iteration_pre", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_range(prop, 0, 10);
+	RNA_def_property_ui_range(prop, 0, 100, 1, 4);
+	RNA_def_property_ui_text(prop, "Pre Iteration ", "How many steps the dynamic system iterate it's start value");
+	RNA_def_property_update(prop, 0, "rna_Texture_update");
+
+	prop = RNA_def_property(srna, "lyap_iteration_main", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_range(prop, 1, 100);
+	RNA_def_property_ui_range(prop, 1, 100, 10, 4);
+	RNA_def_property_ui_text(prop, "Main Iteration", "How many steps the dynamic system iterate (keep small to reduce rendertime)");
+	RNA_def_property_update(prop, 0, "rna_Texture_update");
+
+
+	prop = RNA_def_property(srna, "lyap_neg_color_r", PROP_FLOAT, PROP_COLOR);
+	RNA_def_property_array(prop, 4);
+	RNA_def_property_ui_text(prop, "Neg Color", "Color for negative Lyapunov indices");
+	RNA_def_property_update(prop, 0, "rna_Texture_update");
+
+	prop = RNA_def_property(srna, "lyap_mid_color_r", PROP_FLOAT, PROP_COLOR);
+	RNA_def_property_array(prop, 4);
+	RNA_def_property_ui_text(prop, "Mid Color", "Color for Lyapunov indices near Zero");
+	RNA_def_property_update(prop, 0, "rna_Texture_update");
+
+	prop = RNA_def_property(srna, "lyap_pos_color_r", PROP_FLOAT, PROP_COLOR);
+	RNA_def_property_array(prop, 4);
+	RNA_def_property_ui_text(prop, "Pos Color", "Color for positive Lyapunov indices");
+	RNA_def_property_update(prop, 0, "rna_Texture_update");
+
+	prop = RNA_def_property(srna, "lyap_neg_scale", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_range(prop, 0, 2);
+	RNA_def_property_ui_range(prop, 0, 2, 1, 2);
+	RNA_def_property_ui_text(prop, "neg scale", "Scale negative Lyapunov indices");
+	RNA_def_property_update(prop, 0, "rna_Texture_update");
+
+	prop = RNA_def_property(srna, "lyap_pos_scale", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_range(prop, 0, 2);
+	RNA_def_property_ui_range(prop, 0, 2, 1, 2);
+	RNA_def_property_ui_text(prop, "pos scale", "Scale positive Lyapunov indices");
+	RNA_def_property_update(prop, 0, "rna_Texture_update");
+
+	prop = RNA_def_property(srna, "lyap_intensity_spreading", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "lyap_flag", 1);
+	RNA_def_property_ui_text(prop, "spread Lyapunov indices", "Negative indices to intensity<0.5, positive indices to intensity>0.5 (good for col.ramps)");
+	RNA_def_property_update(prop, 0, "rna_Texture_update");
+
+	prop = RNA_def_property(srna, "lyap_pos_invert", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "lyap_flag", 2);
+	RNA_def_property_ui_text(prop, "", "Reverse positive Lyapunov indices");
+	RNA_def_property_update(prop, 0, "rna_Texture_update");
+
+	prop = RNA_def_property(srna, "lyap_neg_invert", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "lyap_flag", 4);
+	RNA_def_property_ui_text(prop, "", "Reverse nagative Lyapunov indices");
+	RNA_def_property_update(prop, 0, "rna_Texture_update");
+
+	prop = RNA_def_property(srna, "lyap_param1", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_range(prop, -100, 100);
+	RNA_def_property_ui_range(prop, -100, 100, 1, 2);
+	RNA_def_property_ui_text(prop, "1.Param", "First parameter for function of dynamic system");
+	RNA_def_property_update(prop, 0, "rna_Texture_update");
+
+	prop = RNA_def_property(srna, "lyap_param2", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_range(prop, -100, 100);
+	RNA_def_property_ui_range(prop, -100, 100, 1, 2);
+	RNA_def_property_ui_text(prop, "2.Param", "Second parameter for function of dynamic system");
+	RNA_def_property_update(prop, 0, "rna_Texture_update");
+
+	prop = RNA_def_property(srna, "noise_scale", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "noisesize");
+	RNA_def_property_range(prop, 0.0001, FLT_MAX);
+	RNA_def_property_ui_range(prop, 0.0001, 2, 10, 2);
+	RNA_def_property_ui_text(prop, "Size", "Scaling the Lyapunov fractal set");
+	RNA_def_property_update(prop, 0, "rna_Texture_update");
+
+	prop = RNA_def_property(srna, "nabla", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_range(prop, 0.001, 0.1);
+	RNA_def_property_ui_range(prop, 0.001, 0.1, 1, 2);
+	RNA_def_property_ui_text(prop, "Nabla", "Size of derivative offset used for calculating normal");
+	RNA_def_property_update(prop, 0, "rna_Texture_update");
+}
+
 static void rna_def_texture_distorted_noise(BlenderRNA *brna)
 {
 	StructRNA *srna;
@@ -2125,6 +2241,7 @@ static void rna_def_texture(BlenderRNA *brna)
 	rna_def_texture_pointdensity(brna);
 	rna_def_texture_voxeldata(brna);
 	rna_def_texture_ocean(brna);
+	rna_def_texture_lyapunov(brna);
 	/* XXX add more types here .. */
 
 	RNA_api_texture(srna);
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index d20881df15..a2d2ee33e0 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -197,6 +197,7 @@ set(SRC
 	shader/nodes/node_shader_tex_environment.c
 	shader/nodes/node_shader_tex_gradient.c
 	shader/nodes/node_shader_tex_image.c
+	shader/nodes/node_shader_tex_lyapunov.c
 	shader/nodes/node_shader_tex_magic.c
 	shader/nodes/node_shader_tex_musgrave.c
 	shader/nodes/node_shader_tex_noise.c
diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h
index 4c0047f1d5..4defefc72a 100644
--- a/source/blender/nodes/NOD_shader.h
+++ b/source/blender/nodes/NOD_shader.h
@@ -130,6 +130,7 @@ void register_node_type_sh_tex_gradient(void);
 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_lyapunov(void);
 void register_node_type_sh_tex_noise(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 171d5313c1..ac129285cb 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -114,6 +114,7 @@ DefNode( ShaderNode,     SH_NODE_TEX_MAGIC,          def_sh_tex_magic,       "TE
 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",  ""       )
 DefNode( ShaderNode,     SH_NODE_TEX_VORONOI,        def_sh_tex_voronoi,     "TEX_VORONOI",        TexVoronoi,       "Voronoi Texture",   ""       )
+DefNode( ShaderNode,     SH_NODE_TEX_LYAPUNOV,       def_sh_tex_lyapunov,    "TEX_LYAPUNOV",       TexLyapunov,      "Lyapunov Texture",  ""       )
 DefNode( ShaderNode,     SH_NODE_TEX_CHECKER,        def_sh_tex_checker,     "TEX_CHECKER",        TexChecker,       "Checker Texture",   ""       )
 DefNode( ShaderNode,     SH_NODE_TEX_BRICK,          def_sh_tex_brick,       "TEX_BRICK",          TexBrick,         "Brick Texture",     ""       )
 DefNode( ShaderNode,     SH_NODE_TEX_POINTDENSITY,   def_sh_tex_pointdensity,"TEX_POINTDENSITY",   TexPointDensity,  "Point Density",     ""       )
@@ -245,6 +246,7 @@ DefNode( TextureNode,    TEX_NODE_PROC+TEX_MARBLE, 0,                     "TEX_M
 DefNode( TextureNode,    TEX_NODE_PROC+TEX_CLOUDS, 0,                     "TEX_CLOUDS",     TexClouds,        "Clouds",            ""              )
 DefNode( TextureNode,    TEX_NODE_PROC+TEX_WOOD, 0,                       "TEX_WOOD",       TexWood,          "Wood",              ""              )
 DefNode( TextureNode,    TEX_NODE_PROC+TEX_MUSGRAVE, 0,                   "TEX_MUSGRAVE",   TexMusgrave,      "Musgrave",          ""              )
+DefNode( TextureNode,    TEX_NODE_PROC+TEX_LYAPUNOV, 0,                   "TEX_LYAPUNOV",   TexLyapunov,      "Lyapunov",          ""              )
 DefNode( TextureNode,    TEX_NODE_PROC+TEX_NOISE, 0,                      "TEX_NOISE",      TexNoise,         "Noise",             ""              )
 DefNode( TextureNode,    TEX_NODE_PROC+TEX_STUCCI, 0,                     "TEX_STUCCI",     TexStucci,        "Stucci",            ""              )
 DefNode( TextureNode,    TEX_NODE_PROC+TEX_DISTNOISE, 0,                  "TEX_DISTNOISE",  TexDistNoise,     "Distorted Noise",   ""              )
diff --git a/source/blender/nodes/NOD_texture.h b/source/blender/nodes/NOD_texture.h
index 378c96d588..3c3580bccc 100644
--- a/source/blender/nodes/NOD_texture.h
+++ b/source/blender/nodes/NOD_texture.h
@@ -76,6 +76,7 @@ void register_node_type_tex_proc_marble(void);
 void register_node_type_tex_proc_clouds(void);
 void register_node_type_tex_proc_wood(void);
 void register_node_type_tex_proc_musgrave(void);
+void register_node_type_tex_proc_lyapunov(void);
 void register_node_type_tex_proc_noise(void);
 void register_node_type_tex_proc_stucci(void);
 void register_node_type_tex_proc_distnoise(void);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_lyapunov.c b/source/blender/nodes/shader/nodes/node_shader_tex_lyapunov.c
new file mode 100644
index 0000000000..1c5a9956c8
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_lyapunov.c
@@ -0,0 +1,94 @@
+/*
+ * ***** 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"
+
+/* **************** OUTPUT ******************** */
+
+static bNodeSocketTemplate sh_node_tex_lyapunov_in[] = {
+	{	SOCK_VECTOR, 1, N_("Vector"),			0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
+/*	{ 	SOCK_RGBA,   1, N_("Color pos"),		1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+	{ 	SOCK_RGBA,   1, N_("Color mid"),		0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+	{ 	SOCK_RGBA,   1, N_("Color neg"),		0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f},
+	{	SOCK_FLOAT,  1, N_("Pos Scale"),		0.5f, 0.0f, 0.0f, 0.0f,      0.0f,    2.0f},
+	{	SOCK_FLOAT,  1, N_("Neg Scale"),		0.5f, 0.0f, 0.0f, 0.0f,      0.0f,    2.0f},
+*/
+	{	SOCK_FLOAT,  1, N_("Shift"),			0.0f, 0.0f, 0.0f, 0.0f,      0.0f,   1.0f},
+	{	SOCK_FLOAT,  1, N_("Balance"),			0.0f, 0.0f, 0.0f, 0.0f,      0.0f,   1.0f},
+	{	SOCK_FLOAT,  1, N_("Pre Iterations"),	0.0f, 0.0f, 0.0f, 0.0f,      0.0f,   10.0f},
+	{	SOCK_FLOAT,  1, N_("Main Iterations"),	1.0f, 0.0f, 0.0f, 0.0f,      1.0f,  300.0f},
+	{	SOCK_FLOAT,  1, N_("Param1"),			2.0f, 0.0f, 0.0f, 0.0f,   -100.0f,  100.0f},
+	{	SOCK_FLOAT,  1, N_("Param2"),			2.0f, 0.0f, 0.0f, 0.0f,   -100.0f,  100.0f},
+	{	SOCK_FLOAT,  1, N_("Scale"),			1.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f},
+	{	-1, 0, ""	}
+};
+
+static bNodeSocketTemplate sh_node_tex_lyapunov_out[] = {
+//	{	SOCK_RGBA, 0, N_("Color"),		0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+	{	SOCK_FLOAT, 0, N_("Fac"),		0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR, SOCK_NO_INTERNAL_LINK},
+	{	SOCK_FLOAT, 0, N_("Positiv"),	0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR, SOCK_NO_INTERNAL_LINK},
+	{	SOCK_FLOAT, 0, N_("Negativ"),	0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR, SOCK_NO_INTERNAL_LINK},
+	{	-1, 0, ""	}
+};
+
+static void node_shader_init_tex_lyapunov(bNodeTree *UNUSED(ntree), bNode *node)
+{
+	NodeTexLyapunov *tex = MEM_callocN(sizeof(NodeTexLyapunov), "NodeTexLyapunov");
+	BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
+	BKE_texture_colormapping_default(&tex->base.color_mapping);
+
+	node->storage = tex;
+}
+
+static int node_shader_gpu_tex_lyapunov(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+	if (!in[0].link) {
+		in[0].link = GPU_attribute(CD_ORCO, "");
+		GPU_link(mat, "generated_from_orco", in[0].link, &in[0].link);
+	}
+
+	node_shader_gpu_tex_mapping(mat, node, in, out);
+	
+	return GPU_stack_link(mat, "node_tex_lyapunov", in, out);
+}
+
+/* node type definition */
+void register_node_type_sh_tex_lyapunov(void)
+{
+	static bNodeType ntype;
+
+	node_type_base(&ntype, SH_NODE_TEX_LYAPUNOV, "Lyapunov Texture", NODE_CLASS_TEXTURE, 0);
+	node_type_compatibility(&ntype, NODE_NEW_SHADING);
+	node_type_socket_templates(&ntype, sh_node_tex_lyapunov_in, sh_node_tex_lyapunov_out);
+	//node_type_size(&ntype, 150, 60, 200);
+	node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
+	node_type_init(&ntype, node_shader_init_tex_lyapunov);
+	node_type_storage(&ntype, "NodeTexLyapunov", node_free_standard_storage, node_copy_standard_storage);
+	node_type_gpu(&ntype, node_shader_gpu_tex_lyapunov);
+
+	nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/texture/nodes/node_texture_proc.c b/source/blender/nodes/texture/nodes/node_texture_proc.c
index 0be5f875a2..b8956575e4 100644
--- a/source/blender/nodes/texture/nodes/node_texture_proc.c
+++ b/source/blender/nodes/texture/nodes/node_texture_proc.c
@@ -257,6 +257,53 @@ static void musgrave_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short t
 }
 ProcDef(musgrave)
 
+/* -- LYAPUNOV -- */
+static bNodeSocketTemplate lyapunov_inputs[]= {
+	COMMON_INPUTS,
+	{ SOCK_RGBA, 1, "Neg Color", 0.0f, 0.0f, 1.0f, 1.0f },
+	{ SOCK_RGBA, 1, "Mid Color", 0.0f, 0.0f, 0.0f, 1.0f },
+	{ SOCK_RGBA, 1, "Pos Color", 1.0f, 0.0f, 0.0f, 1.0f },
+	{ SOCK_FLOAT, 1, N_("Neg Scale"), 0.5f, 0.0f, 0.0f, 0.0f,   0.0f, 2.0f, PROP_UNSIGNED },
+	{ SOCK_FLOAT, 1, N_("Pos Scale"), 0.5f, 0.0f, 0.0f, 0.0f,   0.0f, 2.0f, PROP_UNSIGNED },
+	{ SOCK_FLOAT, 1, N_("Prev Iter"), 0.0f, 0.0f, 0.0f, 0.0f,   0.0f, 10.0f, PROP_UNSIGNED },
+	{ SOCK_FLOAT, 1, N_("Main Iter"), 1.0f, 0.0f, 0.0f, 0.0f,   1.0f, 100.0f, PROP_UNSIGNED },
+	{ SOCK_FLOAT, 1, N_("1.Param"), 2.0f, 0.0f, 0.0f, 0.0f,   -100.0f, 100.0f, PROP_NONE },
+	{ SOCK_FLOAT, 1, N_("2.Param"), 2.0f, 0.0f, 0.0f, 0.0f,   -100.0f, 100.0f, PROP_NONE },
+	{ SOCK_FLOAT, 1, N_("Size"),   0.25f, 0.0f, 0.0f, 0.0f,   0.0001f, 2.0f, PROP_UNSIGNED },
+	{ -1, 0, "" }
+};
+
+static void lyapunov_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
+{
+	float out[4];
+	tex_input_rgba(out, in[I+0], p, thread);
+	tex->lyap_neg_color_r = out[0];
+	tex->lyap_neg_color_g = out[1];
+	tex->lyap_neg_color_b = out[2];
+	tex->lyap_neg_color_a = out[3];
+
+	tex_input_rgba(out, in[I+1], p, thread);
+	tex->lyap_mid_color_r = out[0];
+	tex->lyap_mid_color_g = out[1];
+	tex->lyap_mid_color_b = out[2];
+	tex->lyap_mid_color_a = out[3];
+
+	tex_input_rgba(out, in[I+2], p, thread);
+	tex->lyap_pos_color_r = out[0];
+	tex->lyap_pos_color_g = out[1];
+	tex->lyap_pos_color_b = out[2];
+	tex->lyap_pos_color_a = out[3];
+
+	tex->lyap_neg_scale = tex_input_value(in[I+3], p, thread);
+	tex->lyap_pos_scale = tex_input_value(in[I+4], p, thread);
+	tex->lyap_iteration_pre = tex_input_value(in[I+5], p, thread);
+	tex->lyap_iteration_main = tex_input_value(in[I+6], p, thread);
+	tex->lyap_param1 = tex_input_value(in[I+7], p, thread);
+	tex->lyap_param2 = tex_input_value(in[I+8], p, thread);
+	tex->noisesize = tex_input_value(in[I+9], p, thread);
+}
+ProcDef(lyapunov)
+
 /* --- NOISE --- */
 static bNodeSocketTemplate noise_inputs[] = {
 	COMMON_INPUTS,
@@ -323,3 +370,4 @@ TexDef(TEX_MUSGRAVE,  CV, musgrave,  "Musgrave" )
 TexDef(TEX_NOISE,     C,  noise,     "Noise"    )
 TexDef(TEX_STUCCI,    CV, stucci,    "Stucci"   )
 TexDef(TEX_DISTNOISE, CV, distnoise, "Distorted Noise" )
+TexDef(TEX_LYAPUNOV,  CV, lyapunov,  "Lyapunov" )
diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c
index b4a14f5337..03db294bc6 100644
--- a/source/blender/render/intern/source/render_texture.c
+++ b/source/blender/render/intern/source/render_texture.c
@@ -482,6 +482,170 @@ static int magic(Tex *tex, const float texvec[3], TexResult *texres)
 }
 
 /* ------------------------------------------------------------------------- */
+/* Lyapunov Index */
+static float lyap_index(Tex *tex, float a, float b, float c)
+{
+	int iter_pre =  (int)floor(tex->lyap_iteration_pre);
+	int iter_main = (int)floor(tex->lyap_iteration_main);
+	float nabla_pre = tex->lyap_iteration_pre - (float)iter_pre;
+	float nabla_main = tex->lyap_iteration_main - (float)iter_main;
+	float p1 = tex->lyap_param1;
+	float p2 = tex->lyap_param2;
+	float x = 0.0f;
+	float x_pre;
+	float index = 0.0f;
+	float index_pre;
+	float ableitung;
+
+	int i;
+	int iter = 0;
+
+	/* pre-iteration */
+	for(i = 0; i < iter_pre; i++)
+	{
+			x = p1*sin(x+a)*sin(x+a)+p2;
+			x = p1*sin(x+b)*sin(x+b)+p2;
+			x = p1*sin(x+c)*sin(x+c)+p2;
+	}
+
+	if (nabla_pre != 0.0f)
+	{
+		x_pre = x;
+		x = p1*sin(x+a)*sin(x+a)+p2;
+		x = p1*sin(x+b)*sin(x+b)+p2;
+		x = p1*sin(x+c)*sin(x+c)+p2;
+		x = x*nabla_pre + x_pre*(1.0f-nabla_pre);
+	}
+
+	/* main-iteration */
+	for(i = 0; i < iter_main; i++)
+	{
+		x = p1*sin(x+a)*sin(x+a)+p2;
+		ableitung = 2.0f*p1*sin(x+a)*cos(x+a);
+		if (ableitung != 0.0f) { index += log(fabs(ableitung)); iter++; }
+
+		x = p1*sin(x+b)*sin(x+b)+p2;
+		ableitung = 2.0f*p1*sin(x+b)*cos(x+b);
+		if (ableitung != 0.0f) { index += log(fabs(ableitung)); iter++; }
+
+		x = p1*sin(x+c)*sin(x+c)+p2;
+		ableitung = 2.0f*p1*sin(x+c)*cos(x+c);
+		if (ableitung != 0.0f) { index += log(fabs(ableitung)); iter++; }
+	}
+
+
+	if (nabla_main == 0.0f)
+	{
+		index = (iter != 0) ? index/(float)(iter) : 0.0f;
+	}
+	else
+	{
+		index_pre = (iter != 0) ? index/(float)(iter) : 0.0f;
+
+		x = p1*sin(x+a)*sin(x+a)+p2;
+		ableitung = 2.0f*p1*sin(x+a)*cos(x+a);
+		if (ableitung != 0.0f) { index += log(fabs(ableitung)); iter++; }
+
+		x = p1*sin(x+b)*sin(x+b)+p2;
+		ableitung = 2.0f*p1*sin(x+b)*cos(x+b);
+		if (ableitung != 0.0f) { index += log(fabs(ableitung)); iter++; }
+
+		x = p1*sin(x+c)*sin(x+c)+p2;
+		ableitung = 2.0f*p1*sin(x+c)*cos(x+c);
+		if (ableitung != 0.0f) { index += log(fabs(ableitung)); iter++; }
+
+		index = (iter != 0) ? index/(float)(iter) : 0.0f;
+		index = index*nabla_main + index_pre*(1.0f-nabla_main);
+	}
+
+	return(index);
+}
+
+static int lyapunov(Tex *tex, float *texvec, TexResult *texres)
+{
+	int rv = TEX_INT;
+	float index;
+
+	index = lyap_index(tex, texvec[0]*tex->noisesize*4,texvec[1]*tex->noisesize*4,texvec[2]*tex->noisesize*4);
+
+	if ( index > 0.0f && (tex->lyap_render_type != TEX_LYAP_NEG) )	{
+		index *= tex->lyap_pos_scale;
+		if (tex->lyap_flag & 2) {
+			if (index > 1.0f) { index = 1.0f; }
+			index = 1.0f - index;
+		}
+		if (tex->lyap_flag & 1) {
+			texres->tin = 0.5f + index/2.0f;
+		}
+		else {
+			texres->tin = fabs(index);
+		}
+	}
+	else if ( index < 0.0f && (tex->lyap_render_type != TEX_LYAP_POS) ) {
+		index *= tex->lyap_neg_scale;
+		if (tex->lyap_flag & 4) {
+			if (index < -1.0f) { index = -1.0f; }
+			index = -1.0f - index;
+		}
+		if (tex->lyap_flag & 1) {
+			texres->tin = 0.5f + index/2.0f;
+		}
+		else {
+			texres->tin = fabs(index);
+		}
+	}
+	else {
+		if (tex->lyap_flag & 1) {
+			texres->tin = 0.5f;
+		}
+		else {
+			texres->tin = 0.0f;
+		}
+	}
+
+
+	if (tex->lyap_color_type == TEX_LYAP_RGB) {
+		// calculate RGBA Values
+		if ( index > 0.0f && (tex->lyap_render_type != TEX_LYAP_NEG)) {
+
+			if (index > 1.0f) { index = 1.0f; }
+			texres->tr = (tex->lyap_pos_color_r - tex->lyap_mid_color_r)*index+tex->lyap_mid_color_r;
+			texres->tg = (tex->lyap_pos_color_g - tex->lyap_mid_color_g)*index+tex->lyap_mid_color_g;
+			texres->tb = (tex->lyap_pos_color_b - tex->lyap_mid_color_b)*index+tex->lyap_mid_color_b;
+			texres->ta = (tex->lyap_pos_color_a - tex->lyap_mid_color_a)*index+tex->lyap_mid_color_a;
+		}
+		else if ( index < 0.0f && (tex->lyap_render_type != TEX_LYAP_POS)) {
+
+			if (index < -1.0f) { index = -1.0f; }			
+			texres->tr = (tex->lyap_mid_color_r - tex->lyap_neg_color_r)*index+tex->lyap_mid_color_r;
+			texres->tg = (tex->lyap_mid_color_g - tex->lyap_neg_color_g)*index+tex->lyap_mid_color_g;
+			texres->tb = (tex->lyap_mid_color_b - tex->lyap_neg_color_b)*index+tex->lyap_mid_color_b;
+			texres->ta = (tex->lyap_mid_color_a - tex->lyap_neg_color_a)*index+tex->lyap_mid_color_a;
+		}
+		else {
+			texres->tr = tex->lyap_mid_color_r;
+			texres->tg = tex->lyap_mid_color_g;
+			texres->tb = tex->lyap_mid_color_b;
+			texres->ta = tex->lyap_mid_color_a;
+		}
+
+		rv |= TEX_RGB;
+	}
+
+	if (texres->nor!=NULL) {
+		// calculate bumpnormal
+		texres->nor[0] =  0.5f + lyap_index(tex, (texvec[0] + tex->nabla*tex->noisesize), texvec[1]*tex->noisesize, texvec[2]*tex->noisesize)/2.0f;
+		texres->nor[1] =  0.5f + lyap_index(tex, texvec[0]*tex->noisesize, (texvec[1] + tex->nabla)*tex->noisesize, texvec[2]*tex->noisesize)/2.0f;
+		texres->nor[2] =  0.5f + lyap_index(tex, texvec[0]*tex->noisesize, texvec[1]*tex->noisesize, (texvec[2] + tex->nabla)*tex->noisesize)/2.0f;
+		tex_normal_derivate(tex, texres);
+		rv |= TEX_NOR;
+	}
+
+	BRICONT;
+	return rv;
+}
+
+/* ------------------------------------------------------------------------- */
 
 /* newnoise: stucci also modified to use different noisebasis */
 static int stucci(Tex *tex, const float texvec[3], TexResult *texres)
