commit 2fce34f4faa05b2817b9e1ba91a55cebee1b9474
Author: Leszek Koltunski <leszek@distoretedandroid.org>
Date:   Thu Jun 16 14:50:30 2016 +0100

    Major push towards simplifying DistortedObject's public API.
    All Fragment effects are using the new API - the 'DataND' marker interfaces.

diff --git a/src/main/java/org/distorted/library/DistortedObject.java b/src/main/java/org/distorted/library/DistortedObject.java
index 86ffc9f..598561a 100644
--- a/src/main/java/org/distorted/library/DistortedObject.java
+++ b/src/main/java/org/distorted/library/DistortedObject.java
@@ -493,6 +493,18 @@ public abstract class DistortedObject
     return mM.add(EffectNames.SCALE,scale);
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Scales the Object by one uniform factor in all 3 dimensions. Convenience function.
+ *
+ * @param scale The factor to scale all 3 dimensions with.
+ * @return      ID of the effect added, or -1 if we failed to add one.
+ */
+public long scale(float scale)
+  {
+  return mM.add(EffectNames.SCALE, new Static3D(scale,scale,scale));
+  }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
  * Rotates the Object by 'angle' degrees around the center.
@@ -511,7 +523,7 @@ public abstract class DistortedObject
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
  * Rotates the Object by 'angle' degrees around the center.
- * Static axis of rotation is given by the last parameter.
+ * Here both angle and axis can dynamically change.
  *
  * @param center    Coordinates of the Point we are rotating around.
  * @param angleaxis Combined 4-tuple representing the (angle,axisX,axisY,axisZ).
@@ -551,1231 +563,202 @@ public abstract class DistortedObject
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Fragment-based effects  
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// MACROBLOCK
 /**
- * Creates macroblocks at and around point defined by the Dynamic2D and the Region.
- * Size of the macroblocks at any given time is returned by the Dynamic1D.
+ * Creates macroblocks at and around point defined by the Region.
  * 
  * @param size   1-dimensional Dynamic which, at any given time, returns the size of the macroblocks.
  * @param region Region this Effect is limited to.
- *               Null here means 'apply the effect to the whole Object'.
- * @param center 2-dimensional Dynamic which, at any given time, returns a Static2D representing the
- *               current center of the effect.
- * @return       ID of the effect added, or -1 if we failed to add one. 
- */
-  public long macroblock(Dynamic1D size, Static4D region, Dynamic2D center)
-    {
-    return mF.add(EffectNames.MACROBLOCK, size, region, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Creates macroblocks at and around point defined by the Point2D and the Region. 
- * Size of the macroblocks at any given time is returned by the Dynamic1D.
- * <p>
- * The difference between this and the previous method is that here the center of the Effect stays constant.
- *    
- * @param size   1-dimensional Dynamic which, at any given time, returns the size of the macroblocks.
- * @param region Region this Effect is limited to. 
- *               Null here means 'apply the effect to the whole Object'.
- * @param center Center of the Effect.
- * @return       ID of the effect added, or -1 if we failed to add one. 
- */
-  public long macroblock(Dynamic1D size, Static4D region, Static2D center)
-    {
-    return mF.add(EffectNames.MACROBLOCK, size, region, center);
-    }
-  
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Creates macroblocks at and around point defined by the Dynamic2D and the Region.
- * <p>
- * The macroblocks change in size; at time 0 there are none, and after 'duration/2' milliseconds 
- * they are of (pixels X pixels) size; after 'duration' milliseconds there are again none (i.e. their
- * size is 1X1, i.e. 1 pixel).   
- * 
- * @param pixels   Maximum size, in pixels, of the Macroblocks we want to see.
- * @param region   Region this Effect is limited to. 
- *                 Null here means 'apply the effect to the whole Object'.
- * @param center   2-dimensional Dynamic which, at any given time, returns a Static2D representing the
- *                 current center of the effect.
- * @param duration Time, in milliseconds, it takes to do one full interpolation.
- * @param count    Controls how many interpolations we want to do. See {@link Dynamic#setCount(float)}
- * @return         ID of the effect added, or -1 if we failed to add one. 
- */
-  public long macroblock(int pixels, Static4D region, Dynamic2D center, int duration, float count)
-    {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(count);
-    di.setDuration(duration);
-    di.add(new Static1D(1));
-    di.add(new Static1D(pixels));
-
-    return mF.add(EffectNames.MACROBLOCK, di, region, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Creates macroblocks at and around point defined by the Point2D and the Region. 
- * <p>
- * The macroblocks change in size; at time 0 there are none, and after 'duration/2' milliseconds 
- * they are of (pixels X pixels) size; after 'duration' milliseconds there are again none (i.e. their
- * size is 1X1, i.e. 1 pixel).   
- * <p>
- * The difference between this and the previous method is that here the center of the Effect stays constant.
- *    
- * @param pixels   Maximum size, in pixels, of the Macroblocks we want to see.
- * @param region   Region this Effect is limited to. 
- *                 Null here means 'apply the effect to the whole Object'.
- * @param center   Center of the Effect.
- * @param duration Time, in milliseconds, it takes to do one full interpolation.
- * @param count    Controls how many interpolations we want to do. See {@link Dynamic#setCount(float)}
- * @return         ID of the effect added, or -1 if we failed to add one. 
+ * @return       ID of the effect added, or -1 if we failed to add one.
  */
-  public long macroblock(int pixels, Static4D region, Static2D center, int duration, float count)
+  public long macroblock(Data1D size, Data4D region)
     {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(count);
-    di.setDuration(duration);
-    di.add(new Static1D(1));
-    di.add(new Static1D(pixels));
-
-    return mF.add(EffectNames.MACROBLOCK, di, region, center);
+    return mF.add(EffectNames.MACROBLOCK, size, region);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
  * Creates macroblocks on the whole Object.
- * <p>
- * The macroblocks change in size; at time 0 there are none, and after 'duration/2' milliseconds 
- * they are of (pixels X pixels) size; after 'duration' milliseconds there are again none (i.e. their
- * size is 1X1, i.e. 1 pixel).   
- * <p>
- * The difference between this and the previous method is that here there is no masking Region; thus
- * there is also no center of the Effect. 
- *    
- * @param pixels   Maximum size, in pixels, of the Macroblocks we want to see.
- * @param duration Time, in milliseconds, it takes to do one full interpolation.
- * @param count    Controls how many interpolations we want to do. See {@link Dynamic#setCount(float)}
- * @return         ID of the effect added, or -1 if we failed to add one. 
+ *
+ * @param size   1-dimensional Data which, at any given time, returns the size of the macroblocks.
+ * @return       ID of the effect added, or -1 if we failed to add one.
  */
-  public long macroblock(int pixels, int duration, float count) 
+  public long macroblock(Data1D size)
     {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(count);
-    di.setDuration(duration);
-    di.add(new Static1D(1));
-    di.add(new Static1D(pixels));
-   
-    return mF.add(EffectNames.MACROBLOCK, di, null, mZero2D);
+    return mF.add(EffectNames.MACROBLOCK, size);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// CHROMA
 /**
  * Makes a certain sub-region of the Object smoothly change all three of its RGB components.
  *        
- * @param blend  1-dimensional Dynamic that returns the level of blend a given pixel will be
+ * @param blend  1-dimensional Data that returns the level of blend a given pixel will be
  *               mixed with the next parameter 'color': pixel = (1-level)*pixel + level*color
  * @param color  Color to mix. (1,0,0) is RED.
- * @param region Region this Effect is limited to. 
- *               Null here means 'apply the Effect to the whole Object'.
- * @param center 2-dimensional Dynamic which, at any given time, returns a Static2D representing
- *               the current center of the effect.
- * @return       ID of the effect added, or -1 if we failed to add one. 
+ * @param region Region this Effect is limited to.
+ * @param smooth If true, the level of 'blend' will smoothly fade out towards the edges of the region.
+ * @return       ID of the effect added, or -1 if we failed to add one.
  */
-  public long chroma(Dynamic1D blend, Static3D color, Static4D region, Dynamic2D center)
+  public long chroma(Data1D blend, Static3D color, Data4D region, boolean smooth)
     {
-    return mF.add(EffectNames.CHROMA, blend, color, region, center);
+    return mF.add( smooth? EffectNames.SMOOTH_CHROMA:EffectNames.CHROMA, blend, color, region);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Makes a certain sub-region of the Object smoothly change all three of its RGB components.
- * <p>
- * Here the center of the Effect stays constant.
- *         
- * @param blend  1-dimensional Dynamic that returns the level of blend a given pixel will be
+ * Makes the whole Object smoothly change all three of its RGB components.
+ *
+ * @param blend  1-dimensional Data that returns the level of blend a given pixel will be
  *               mixed with the next parameter 'color': pixel = (1-level)*pixel + level*color
  * @param color  Color to mix. (1,0,0) is RED.
- * @param region Region this Effect is limited to. 
- *               Null here means 'apply the Effect to the whole Object'.
- * @param center Center of the Effect.
- * @return       ID of the effect added, or -1 if we failed to add one. 
+ * @return       ID of the effect added, or -1 if we failed to add one.
  */
-  public long chroma(Dynamic1D blend, Static3D color, Static4D region, Static2D center)
+  public long chroma(Data1D blend, Static3D color)
     {
-    return mF.add(EffectNames.CHROMA, blend, color, region, center);
+    return mF.add(EffectNames.CHROMA, blend, color);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////  
 /**
  * Makes a certain sub-region of the Object smoothly change all three of its RGB components.
  *        
- * @param blend  Level of blend a given pixel will be mixed with the next parameter 'color':
- *               pixel = (1-t)*pixel + t*color
- * @param color  Color to mix. (1,0,0) is RED.
+ * @param blendcolor  4-dimensional Data returning the 4-tuple (blend,R,G,B).
+ *                    Level of blend a given pixel will be mixed with the next parameter 'color':
+ *                    pixel = (1-t)*pixel + t*color
  * @param region Region this Effect is limited to.
- *               Null here means 'apply the Effect to the whole Object'.
- * @param center 2-dimensional Dynamic which, at any given time, returns a Static2D representing the
- *               current center of the effect.
- * @return       ID of the effect added, or -1 if we failed to add one. 
- */
-  public long chroma(float blend, Static3D color, Static4D region, Dynamic2D center)
-    {
-    return mF.add(EffectNames.CHROMA, blend, color, region, center);
-    }
-
-///// //////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes a certain sub-region of the Object smoothly change all three of its RGB components.
- * <p>
- * Here the center of the Effect stays constant.
- *         
- * @param blend  Level of blend a given pixel will be mixed with the next parameter 'color':
- *               pixel = (1-t)*pixel + t*color
- * @param color  Color to mix. (1,0,0) is RED.
- * @param region The Region this Effect is limited to. 
- *               Null here means 'apply the Effect to the whole Object'.
- * @param center Center of the Effect.
- * @return       ID of the effect added, or -1 if we failed to add one. 
- */
-  public long chroma(float blend, Static3D color, Static4D region, Static2D center)
-    {
-    return mF.add(EffectNames.CHROMA, blend, color, region, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes a certain sub-region of the Object smoothly change all three of its RGB components.
- * <p>
- * Here the Effect applies to the whole Object.
- *         
- * @param blend Level of blend a given pixel will be mixed with the next parameter 'color':
- *              pixel = (1-t)*pixel + t*color
- * @param color Color to mix. (1,0,0) is RED.
- * @return      ID of the effect added, or -1 if we failed to add one. 
- */
-  public long chroma(float blend, Static3D color)
-    {
-    return mF.add(EffectNames.CHROMA, blend, color, null, mZero2D);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////  
-/**
- * Makes a certain sub-region of the Object smoothly change all three of its RGB components.
- * 
- * See {@link #chroma(Dynamic1D, Static3D, Static4D, Dynamic2D)}
+ * @param smooth If true, the level of 'blend' will smoothly fade out towards the edges of the region.
+ * @return       ID of the effect added, or -1 if we failed to add one.
  */
-  public long smooth_chroma(Dynamic1D blend, Static3D color, Static4D region, Dynamic2D center)
+  public long chroma(Data4D blendcolor, Data4D region, boolean smooth )
     {
-    return mF.add(EffectNames.SMOOTH_CHROMA, blend, color, region, center);
+    return mF.add( smooth? EffectNames.SMOOTH_CHROMA:EffectNames.CHROMA, blendcolor, region );
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Makes a certain sub-region of the Object smoothly change all three of its RGB components.
- * 
- * See {@link #chroma(Dynamic1D, Static3D, Static4D, Static2D)}
- */
-  public long smooth_chroma(Dynamic1D blend, Static3D color, Static4D region, Static2D center)
-    {
-    return mF.add(EffectNames.SMOOTH_CHROMA, blend, color, region, center);
-    }
-  
-///////////////////////////////////////////////////////////////////////////////////////////////////  
-/**
- * Makes a certain sub-region of the Object smoothly change all three of its RGB components.
- * 
- * See {@link #chroma(float, Static3D, Static4D, Dynamic2D)}
+ * Makes the whole Object smoothly change all three of its RGB components.
+ *
+ * @param blendcolor  4-dimensional Data returning the 4-tuple (blend,R,G,B).
+ *                    Level of blend a given pixel will be mixed with the next parameter 'color':
+ *                    pixel = (1-t)*pixel + t*color
+ * @return       ID of the effect added, or -1 if we failed to add one. 
  */
-  public long smooth_chroma(float blend, Static3D color, Static4D region, Dynamic2D center)
+  public long chroma(Data4D blendcolor)
     {
-    return mF.add(EffectNames.SMOOTH_CHROMA, blend, color, region, center);
+    return mF.add(EffectNames.CHROMA, blendcolor);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes a certain sub-region of the Object smoothly change all three of its RGB components.
- * 
- * See {@link #chroma(float, Static3D, Static4D, Static2D)}
- */
-  public long smooth_chroma(float blend, Static3D color, Static4D region, Static2D center)
-    {
-    return mF.add(EffectNames.SMOOTH_CHROMA, blend, color, region, center);
-    }
-  
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes a certain sub-region of the Object smoothly change all three of its RGB components.
- * 
- * See {@link #chroma(float, Static3D)}
- */
-  public long smooth_chroma(float blend, Static3D color)
-    {
-    return mF.add(EffectNames.SMOOTH_CHROMA, blend, color, null, mZero2D);
-    }
-  
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// ALPHA
 /**
  * Makes a certain sub-region of the Object smoothly change its transparency level.
  *        
- * @param alpha  1-dimensional Dynamic that returns the level of transparency we want to have at any given
+ * @param alpha  1-dimensional Data that returns the level of transparency we want to have at any given
  *               moment.
  * @param region Region this Effect is limited to. 
- *               Null here means 'apply the Effect to the whole Object'.
- * @param center 2-dimensional Dynamic which, at any given time, returns a Static2D representing the
- *               current center of the effect.
+ * @param smooth If true, the level of 'alpha' will smoothly fade out towards the edges of the region.
  * @return       ID of the effect added, or -1 if we failed to add one. 
  */
-  public long alpha(Dynamic1D alpha, Static4D region, Dynamic2D center)
+  public long alpha(Data1D alpha, Data4D region, boolean smooth)
     {
-    return mF.add(EffectNames.ALPHA, alpha, region, center);
+    return mF.add( smooth? EffectNames.SMOOTH_ALPHA:EffectNames.ALPHA, alpha, region);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Makes a certain sub-region of the Object smoothly change its transparency level.
- * <p>
- * Here the center of the Effect stays constant.
- *         
- * @param alpha  1-dimensional Dynamic that returns the level of transparency we want to have at any given
- *               moment.
- * @param region Region this Effect is limited to. 
- *               Null here means 'apply the Effect to the whole Object'.
- * @param center Center of the Effect.
- * @return       ID of the effect added, or -1 if we failed to add one. 
+ * Makes the whole Object smoothly change its transparency level.
+ *
+ * @param alpha  1-dimensional Data that returns the level of transparency we want to have at any
+ *               given moment.
+ * @return       ID of the effect added, or -1 if we failed to add one.
  */
-  public long alpha(Dynamic1D alpha, Static4D region, Static2D center)
+  public long alpha(Data1D alpha)
     {
-    return mF.add(EffectNames.ALPHA, alpha, region, center);
+    return mF.add(EffectNames.ALPHA, alpha);
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////  
+///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Makes a certain sub-region of the Object smoothly change its transparency level.
+ * Makes a certain sub-region of the Object smoothly change its brightness level.
  *        
- * @param alpha  Level of Alpha (between 0 and 1) we want to interpolate to.
- * @param region Region this Effect is limited to. 
- *               Null here means 'apply the Effect to the whole Object'.
- * @param center 2-dimensional Dynamic which, at any given time, returns a Static2D representing the
- *               current center of the effect.
- * @param duration Time, in milliseconds, it takes to do one full interpolation.
- * @param count  Controls how many interpolations we want to do. See {@link Dynamic#setCount(float)}
- * @return       ID of the effect added, or -1 if we failed to add one. 
+ * @param brightness 1-dimensional Data that returns the level of brightness we want to have
+ *                   at any given moment.
+ * @param region     Region this Effect is limited to.
+ * @param smooth     If true, the level of 'brightness' will smoothly fade out towards the edges of the region.
+ * @return           ID of the effect added, or -1 if we failed to add one.
  */
-  public long alpha(float alpha, Static4D region, Dynamic2D center, int duration, float count)
+  public long brightness(Data1D brightness, Data4D region, boolean smooth)
     {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(count);
-    di.setDuration(duration);
-    di.add(new Static1D(1));
-    di.add(new Static1D(alpha));
-   
-    return mF.add(EffectNames.ALPHA, di, region, center);
+    return mF.add( smooth ? EffectNames.SMOOTH_BRIGHTNESS: EffectNames.BRIGHTNESS, brightness, region);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Makes a certain sub-region of the Object smoothly change its transparency level.
- * <p>
- * Here the center of the Effect stays constant.
- *         
- * @param alpha    Level of Alpha (between 0 and 1) we want to interpolate to.
- * @param region   Region this Effect is limited to.
- *                 Null here means 'apply the Effect to the whole Object'.
- * @param center   Center of the Effect.
- * @param duration Time, in milliseconds, it takes to do one full interpolation.
- * @param count    Controls how many interpolations we want to do. See {@link Dynamic#setCount(float)}
- * @return         ID of the effect added, or -1 if we failed to add one.
+ * Makes the whole Object smoothly change its brightness level.
+ *
+ * @param brightness 1-dimensional Data that returns the level of brightness we want to have
+ *                   at any given moment.
+ * @return           ID of the effect added, or -1 if we failed to add one.
  */
-  public long alpha(float alpha, Static4D region, Static2D center, int duration, float count)
+  public long brightness(Data1D brightness)
     {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(count);
-    di.setDuration(duration);
-    di.add(new Static1D(1));
-    di.add(new Static1D(alpha));
-   
-    return mF.add(EffectNames.ALPHA, di, region, center);
+    return mF.add(EffectNames.BRIGHTNESS, brightness);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Makes a certain sub-region of the Object smoothly change its transparency level.
- * <p>
- * Here the center of the Effect stays constant and the effect for now change in time.
- *         
- * @param alpha  Level of Alpha (between 0 and 1) we want to interpolate to.
- * @param region Region this Effect is limited to.
- *               Null here means 'apply the Effect to the whole Object'.
- * @param center Center of the Effect.
- * @return       ID of the effect added, or -1 if we failed to add one. 
- */
-  public long alpha(float alpha, Static4D region, Static2D center)
-    {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(0.5f);
-    di.setDuration(0);
-    di.add(new Static1D(1));
-    di.add(new Static1D(alpha));
-   
-    return mF.add(EffectNames.ALPHA, di, region, center);
-    }
-  
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes the whole Object change its transparency level.
- * 
- * @param alpha    Level of Alpha (between 0 and 1) we want to interpolate to.
- * @param duration Time, in milliseconds, it takes to do one full interpolation.
- * @param count    Controls how many interpolations we want to do. See {@link Dynamic#setCount(float)}
- * @return         ID of the effect added, or -1 if we failed to add one. 
- */
-  public long alpha(float alpha, int duration, float count) 
-    {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(count);
-    di.setDuration(duration);
-    di.add(new Static1D(1));
-    di.add(new Static1D(alpha));
-         
-    return mF.add(EffectNames.ALPHA, di,null, mZero2D);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////  
-/**
- * Makes a certain sub-region of the Object smoothly change its transparency level.
- * 
- * See {@link #alpha(Dynamic1D, Static4D, Dynamic2D)}
+ * Makes a certain sub-region of the Object smoothly change its contrast level.
+ *        
+ * @param contrast 1-dimensional Data that returns the level of contrast we want to have
+ *                 at any given moment.
+ * @param region   Region this Effect is limited to.
+ * @param smooth   If true, the level of 'contrast' will smoothly fade out towards the edges of the region.
+ * @return         ID of the effect added, or -1 if we failed to add one.
  */
-  public long smooth_alpha(Dynamic1D alpha, Static4D region, Dynamic2D center)
+  public long contrast(Data1D contrast, Data4D region, boolean smooth)
     {
-    return mF.add(EffectNames.SMOOTH_ALPHA, alpha, region, center);
+    return mF.add( smooth ? EffectNames.SMOOTH_CONTRAST:EffectNames.CONTRAST, contrast, region);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Makes a certain sub-region of the Object smoothly change its transparency level.
- * 
- * See {@link #alpha(Dynamic1D, Static4D, Static2D)}
- */
-  public long smooth_alpha(Dynamic1D alpha, Static4D region, Static2D center)
-    {
-    return mF.add(EffectNames.SMOOTH_ALPHA, alpha, region, center);
-    }
-  
-///////////////////////////////////////////////////////////////////////////////////////////////////  
-/**
- * Makes a certain sub-region of the Object smoothly change its transparency level.
- * 
- * See {@link #alpha(float, Static4D, Dynamic2D, int, float)}
+ * Makes the whole Object smoothly change its contrast level.
+ *
+ * @param contrast 1-dimensional Data that returns the level of contrast we want to have
+ *                 at any given moment.
+ * @return         ID of the effect added, or -1 if we failed to add one.
  */
-  public long smooth_alpha(float alpha, Static4D region, Dynamic2D center, int duration, float count)
+  public long contrast(Data1D contrast)
     {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(count);
-    di.setDuration(duration);
-    di.add(new Static1D(1));
-    di.add(new Static1D(alpha));
-   
-    return mF.add(EffectNames.SMOOTH_ALPHA, di, region, center);
+    return mF.add(EffectNames.CONTRAST, contrast);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Makes a certain sub-region of the Object smoothly change its transparency level.
- * 
- * See {@link #alpha(float, Static4D, Static2D, int, float)}
+ * Makes a certain sub-region of the Object smoothly change its saturation level.
+ *        
+ * @param saturation 1-dimensional Data that returns the level of saturation we want to have
+ *                   at any given moment.
+ * @param region     Region this Effect is limited to.
+ * @param smooth     If true, the level of 'saturation' will smoothly fade out towards the edges of the region.
+ * @return           ID of the effect added, or -1 if we failed to add one.
  */
-  public long smooth_alpha(float alpha, Static4D region, Static2D center, int duration, float count)
+  public long saturation(Data1D saturation, Data4D region, boolean smooth)
     {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(count);
-    di.setDuration(duration);
-    di.add(new Static1D(1));
-    di.add(new Static1D(alpha));
-   
-    return mF.add(EffectNames.SMOOTH_ALPHA, di, region, center);
+    return mF.add( smooth ? EffectNames.SMOOTH_SATURATION:EffectNames.SATURATION, saturation, region);
     }
-  
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Makes a certain sub-region of the Object smoothly change its transparency level.
- * 
- * See {@link #alpha(float, Static4D, Static2D)}
+ * Makes the whole Object smoothly change its saturation level.
+ *
+ * @param saturation 1-dimensional Data that returns the level of saturation we want to have
+ *                   at any given moment.
+ * @return           ID of the effect added, or -1 if we failed to add one.
  */
-  public long smooth_alpha(float alpha, Static4D region, Static2D center)
+  public long saturation(Data1D saturation)
     {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(0.5f);
-    di.setDuration(0);
-    di.add(new Static1D(1));
-    di.add(new Static1D(alpha));
-   
-    return mF.add(EffectNames.SMOOTH_ALPHA, di, region, center);
-    }
-  
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// BRIGHTNESS
-/**
- * Makes a certain sub-region of the Object smoothly change its brightness level.
- *        
- * @param brightness 1-dimensional Dynamic that returns the level of brightness we want to have
- *                   at any given moment.
- * @param region     Region this Effect is limited to.
- *                   Null here means 'apply the Effect to the whole Object'.
- * @param center     2-dimensional Dynamic which, at any given time, returns a Static2D representing
- *                   the current center of the effect.
- * @return           ID of the effect added, or -1 if we failed to add one.
- */
-  public long brightness(Dynamic1D brightness, Static4D region, Dynamic2D center)
-    {
-    return mF.add(EffectNames.BRIGHTNESS, brightness, region, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes a certain sub-region of the Object smoothly change its brightness level.
- * <p>
- * Here the center of the Effect stays constant.
- *         
- * @param brightness 1-dimensional Dynamic that returns the level of brightness we want to have
- *                   at any given moment.
- * @param region     Region this Effect is limited to.
- *                   Null here means 'apply the Effect to the whole Object'.
- * @param center     Center of the Effect.
- * @return           ID of the effect added, or -1 if we failed to add one.
- */
-  public long brightness(Dynamic1D brightness, Static4D region, Static2D center)
-    {
-    return mF.add(EffectNames.BRIGHTNESS, brightness, region, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////  
-/**
- * Makes a certain sub-region of the Object smoothly change its brightness level.
- *        
- * @param brightness Level of Brightness (between 0 and infinity) we want to interpolate to.
- *                   1 - level of brightness unchanged, anything less than 1 - 'darken the image',
- *                   anything more than 1- lighten it up. 
- * @param region     Region this Effect is limited to.
- *                   Null here means 'apply the Effect to the whole Object'.
- * @param center     2-dimensional Dynamic which, at any given time, returns a Static2D
- *                   representing the current center of the effect.
- * @param duration   Time, in milliseconds, it takes to do one full interpolation.
- * @param count      Controls how many interpolations we want to do. See {@link Dynamic#setCount(float)}
- * @return           ID of the effect added, or -1 if we failed to add one. 
- */
-  public long brightness(float brightness, Static4D region, Dynamic2D center, int duration, float count)
-    {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(count);
-    di.setDuration(duration);
-    di.add(new Static1D(1));
-    di.add(new Static1D(brightness));
-   
-    return mF.add(EffectNames.BRIGHTNESS, di, region, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes a certain sub-region of the Object smoothly change its brightness level.
- * <p>
- * Here the center of the Effect stays constant.
- *         
- * @param brightness Level of Brightness (between 0 and infinity) we want to interpolate to.
- *                   1 - level of brightness unchanged, anything less than 1 - 'darken the image',
- *                   anything more than 1 - lighten it up.
- * @param region     Region this Effect is limited to. 
- *                   Null here means 'apply the Effect to the whole Object'.
- * @param center     Center of the Effect.
- * @param duration   Time, in milliseconds, it takes to do one full interpolation.
- * @param count      Controls how many interpolations we want to do. See {@link Dynamic#setCount(float)}
- * @return           ID of the effect added, or -1 if we failed to add one. 
- */
-  public long brightness(float brightness, Static4D region, Static2D center, int duration, float count)
-    {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(count);
-    di.setDuration(duration);
-    di.add(new Static1D(1));
-    di.add(new Static1D(brightness));
-   
-    return mF.add(EffectNames.BRIGHTNESS, di, region, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes a certain sub-region of the Object smoothly change its brightness level.
- * <p>
- * Here the center of the Effect stays constant and the effect for now change in time.
- *         
- * @param brightness Level of Brightness (between 0 and infinity) we want to interpolate to.
- *                   1 - level of brightness unchanged, anything less than 1 - 'darken the image',
- *                   anything more than 1 - lighten it up.
- * @param region     Region this Effect is limited to.
- *                   Null here means 'apply the Effect to the whole Object'.
- * @param center     Center of the Effect.
- * @return           ID of the effect added, or -1 if we failed to add one. 
- */
-  public long brightness(float brightness, Static4D region, Static2D center)
-    {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(0.5f);
-    di.setDuration(0);
-    di.add(new Static1D(1));
-    di.add(new Static1D(brightness));
-   
-    return mF.add(EffectNames.BRIGHTNESS, di, region, center);
-    }
- 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// SMOOTH BRIGHTNESS
-/**
- * Makes a certain sub-region of the Object smoothly change its brightness level.
- *        
- * @param brightness 1-dimensional Dynamic that returns the level of brightness we want to have
- *                   at any given moment.
- * @param region     Region this Effect is limited to.
- *                   Null here means 'apply the Effect to the whole Object'.
- * @param center     2-dimensional Dynamic which, at any given time, returns a Static2D
- *                   representing the current center of the effect.
- * @return           ID of the effect added, or -1 if we failed to add one.
- */
-  public long smooth_brightness(Dynamic1D brightness, Static4D region, Dynamic2D center)
-    {
-    return mF.add(EffectNames.SMOOTH_BRIGHTNESS, brightness, region, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes a certain sub-region of the Object smoothly change its brightness level.
- * <p>
- * Here the center of the Effect stays constant.
- *         
- * @param brightness 1-dimensional Dynamic that returns the level of brightness we want to have
- *                   at any given moment.
- * @param region     Region this Effect is limited to.
- *                   Null here means 'apply the Effect to the whole Object'.
- * @param center     Center of the Effect.
- * @return           ID of the effect added, or -1 if we failed to add one.
- */
-  public long smooth_brightness(Dynamic1D brightness, Static4D region, Static2D center)
-    {
-    return mF.add(EffectNames.SMOOTH_BRIGHTNESS, brightness, region, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////  
-/**
- * Makes a certain sub-region of the Object smoothly change its brightness level.
- *        
- * @param brightness Level of Brightness (between 0 and infinity) we want to interpolate to.
- *                   1 - level of brightness unchanged, anything less than 1 - 'darken the image',
- *                   anything more than 1 - lighten it up. 
- * @param region     Region this Effect is limited to. 
- *                   Null here means 'apply the Effect to the whole Object'.
- * @param center     2-dimensional Dynamic which, at any given time, returns a Static2D
- *                   represention the current center of the effect.
- * @param duration   Time, in milliseconds, it takes to do one full interpolation.
- * @param count      Controls how many interpolations we want to do. See {@link Dynamic#setCount(float)}
- * @return           ID of the effect added, or -1 if we failed to add one. 
- */
-  public long smooth_brightness(float brightness, Static4D region, Dynamic2D center, int duration, float count)
-    {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(count);
-    di.setDuration(duration);
-    di.add(new Static1D(1));
-    di.add(new Static1D(brightness));
-   
-    return mF.add(EffectNames.SMOOTH_BRIGHTNESS, di, region, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes a certain sub-region of the Object smoothly change its brightness level.
- * <p>
- * Here the center of the Effect stays constant.
- *         
- * @param brightness Level of Brightness (between 0 and infinity) we want to interpolate to.
- *                   1 - level of brightness unchanged, anything less than 1 - 'darken the image',
- *                   anything more than 1 - lighten it up.
- * @param region     Region this Effect is limited to. 
- *                   Null here means 'apply the Effect to the whole Object'.
- * @param center     Center of the Effect.
- * @param duration   Time, in milliseconds, it takes to do one full interpolation.
- * @param count      Controls how many interpolations we want to do. See {@link Dynamic#setCount(float)}
- * @return           ID of the effect added, or -1 if we failed to add one. 
- */
-  public long smooth_brightness(float brightness, Static4D region, Static2D center, int duration, float count)
-    {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(count);
-    di.setDuration(duration);
-    di.add(new Static1D(1));
-    di.add(new Static1D(brightness));
-   
-    return mF.add(EffectNames.SMOOTH_BRIGHTNESS, di, region, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes a certain sub-region of the Object smoothly change its brightness level.
- * <p>
- * Here the center of the Effect stays constant and the effect for now change in time.
- *         
- * @param brightness Level of Brightness (between 0 and infinity) we want to interpolate to.
- *                   1 - level of brightness unchanged, anything less than 1 - 'darken the image',
- *                   anything more than 1 - lighten it up.
- * @param region     Region this Effect is limited to. 
- *                   Null here means 'apply the Effect to the whole Object'.
- * @param center     Center of the Effect.
- * @return           ID of the effect added, or -1 if we failed to add one. 
- */
-  public long smooth_brightness(float brightness, Static4D region, Static2D center)
-    {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(0.5f);
-    di.setDuration(0);
-    di.add(new Static1D(1));
-    di.add(new Static1D(brightness));
-   
-    return mF.add(EffectNames.SMOOTH_BRIGHTNESS, di, region, center);
-    }
-    
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes the whole Object change its brightness level.
- * 
- * @param brightness Level of Brightness (between 0 and infinity) we want to interpolate to.
- *                   1 - level of brightness unchanged, anything less than 1 - 'darken the image',
- *                   anything more than 1- lighten it up.
- * @param duration   Time, in milliseconds, it takes to do one full interpolation.
- * @param count      Controls how many interpolations we want to do. See {@link Dynamic#setCount(float)}
- * @return           ID of the effect added, or -1 if we failed to add one. 
- */
-  public long smooth_brightness(float brightness, int duration, float count) 
-    {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(count);
-    di.setDuration(duration);
-    di.add(new Static1D(1));
-    di.add(new Static1D(brightness));
-         
-    return mF.add(EffectNames.SMOOTH_BRIGHTNESS, di,null, mZero2D);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// CONTRAST
-/**
- * Makes a certain sub-region of the Object smoothly change its contrast level.
- *        
- * @param contrast 1-dimensional Dynamic that returns the level of contrast we want to have
- *                 at any given moment.
- * @param region   Region this Effect is limited to.
- *                 Null here means 'apply the Effect to the whole Object'.
- * @param center   2-dimensional Dynamic which, at any given time, returns a Static2D
- *                 representing the current center of the effect.
- * @return         ID of the effect added, or -1 if we failed to add one.
- */
-  public long contrast(Dynamic1D contrast, Static4D region, Dynamic2D center)
-    {
-    return mF.add(EffectNames.CONTRAST, contrast, region, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes a certain sub-region of the Object smoothly change its contrast level.
- * <p>
- * Here the center of the Effect stays constant.
- *         
- * @param contrast 1-dimensional Dynamic that returns the level of contrast we want to have
- *                 at any given moment.
- * @param region   Region this Effect is limited to.
- *                 Null here means 'apply the Effect to the whole Object'.
- * @param center  Center of the Effect.
- * @return        ID of the effect added, or -1 if we failed to add one.
- */
-  public long contrast(Dynamic1D contrast, Static4D region, Static2D center)
-    {
-    return mF.add(EffectNames.CONTRAST, contrast, region, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////  
-/**
- * Makes a certain sub-region of the Object smoothly change its contrast level.
- *        
- * @param contrast Level of contrast (between 0 and infinity) we want to interpolate to.
- *                 1 - level of contrast unchanged, anything less than 1 - reduce contrast,
- *                 anything more than 1 - increase the contrast. 
- * @param region   Region this Effect is limited to.
- *                 Null here means 'apply the Effect to the whole Object'.
- * @param center   2-dimensional Dynamic which, at any given time, returns a Static2D
- *                 represention the current center of the effect.
- * @param duration Time, in milliseconds, it takes to do one full interpolation.
- * @param count    Controls how many interpolations we want to do. See {@link Dynamic#setCount(float)}
- * @return         ID of the effect added, or -1 if we failed to add one. 
- */
-  public long contrast(float contrast, Static4D region, Dynamic2D center, int duration, float count)
-    {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(count);
-    di.setDuration(duration);
-    di.add(new Static1D(1));
-    di.add(new Static1D(contrast));
-   
-    return mF.add(EffectNames.CONTRAST, di, region, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes a certain sub-region of the Object smoothly change its contrast level.
- * <p>
- * Here the center of the Effect stays constant.
- *         
- * @param contrast Level of contrast (between 0 and infinity) we want to interpolate to.
- *                 1 - level of contrast unchanged, anything less than 1 - reduce contrast,
- *                 anything more than 1 -increase the contrast. 
- * @param region   Region this Effect is limited to. 
- *                 Null here means 'apply the Effect to the whole Object'.
- * @param center   Center of the Effect.
- * @param duration Time, in milliseconds, it takes to do one full interpolation.
- * @param count    Controls how many interpolations we want to do. See {@link Dynamic#setCount(float)}
- * @return         ID of the effect added, or -1 if we failed to add one. 
- */
-  public long contrast(float contrast, Static4D region, Static2D center, int duration, float count)
-    {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(count);
-    di.setDuration(duration);
-    di.add(new Static1D(1));
-    di.add(new Static1D(contrast));
-   
-    return mF.add(EffectNames.CONTRAST, di, region, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes a certain sub-region of the Object smoothly change its contrast level.
- * <p>
- * Here the center of the Effect stays constant and the effect for now change in time.
- *         
- * @param contrast Level of contrast (between 0 and infinity) we want to interpolate to.
- *                 1 - level of contrast unchanged, anything less than 1 - reduce contrast,
- *                 anything more than 1 - increase the contrast. 
- * @param region   Region this Effect is limited to. 
- *                 Null here means 'apply the Effect to the whole Object'.
- * @param center   Center of the Effect.
- * @return         ID of the effect added, or -1 if we failed to add one. 
- */
-  public long contrast(float contrast, Static4D region, Static2D center)
-    {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(0.5f);
-    di.setDuration(0);
-    di.add(new Static1D(1));
-    di.add(new Static1D(contrast));
-   
-    return mF.add(EffectNames.CONTRAST, di, region, center);
-    }
- 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// SMOOTH CONTRAST
-/**
- * Makes a certain sub-region of the Object smoothly change its contrast level.
- *        
- * @param contrast 1-dimensional Dynamic that returns the level of contrast we want to have
- *                 at any given moment.
- * @param region   Region this Effect is limited to.
- *                 Null here means 'apply the Effect to the whole Object'.
- * @param center   2-dimensional Dynamic which, at any given time, returns a Static2D
- *                 representing the current center of the effect.
- * @return         ID of the effect added, or -1 if we failed to add one.
- */
-  public long smooth_contrast(Dynamic1D contrast, Static4D region, Dynamic2D center)
-    {
-    return mF.add(EffectNames.SMOOTH_CONTRAST, contrast, region, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes a certain sub-region of the Object smoothly change its contrast level.
- * <p>
- * Here the center of the Effect stays constant.
- *         
- * @param contrast 1-dimensional Dynamic that returns the level of contrast we want to have
- *                 at any given moment.
- * @param region   Region this Effect is limited to.
- *                 Null here means 'apply the Effect to the whole Object'.
- * @param center   Center of the Effect.
- * @return         ID of the effect added, or -1 if we failed to add one.
- */
-  public long smooth_contrast(Dynamic1D contrast, Static4D region, Static2D center)
-    {
-    return mF.add(EffectNames.SMOOTH_CONTRAST, contrast, region, center);
+    return mF.add(EffectNames.SATURATION, saturation);
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////  
-/**
- * Makes a certain sub-region of the Object smoothly change its contrast level.
- *        
- * @param contrast Level of contrast (between 0 and infinity) we want to interpolate to.
- *                 1 - level of contrast unchanged, anything less than 1 - reduce contrast,
- *                 anything more than 1 - increase the contrast. 
- * @param region   Region this Effect is limited to. 
- *                 Null here means 'apply the Effect to the whole Object'.
- * @param center   2-dimensional Dynamic which, at any given time, returns a Static2D
- *                 representing the current center of the effect.
- * @param duration Time, in milliseconds, it takes to do one full interpolation.
- * @param count    Controls how many interpolations we want to do. See {@link Dynamic#setCount(float)}
- * @return         ID of the effect added, or -1 if we failed to add one. 
- */
-  public long smooth_contrast(float contrast, Static4D region, Dynamic2D center, int duration, float count)
-    {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(count);
-    di.setDuration(duration);
-    di.add(new Static1D(1));
-    di.add(new Static1D(contrast));
-   
-    return mF.add(EffectNames.SMOOTH_CONTRAST, di, region, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes a certain sub-region of the Object smoothly change its contrast level.
- * <p>
- * Here the center of the Effect stays constant.
- *         
- * @param contrast Level of contrast (between 0 and infinity) we want to interpolate to.
- *                 1 - level of contrast unchanged, anything less than 1 - reduce contrast,
- *                 anything more than 1 - increase the contrast. 
- * @param region   Region this Effect is limited to. 
- *                 Null here means 'apply the Effect to the whole Object'.
- * @param center   Center of the Effect.
- * @param duration Time, in milliseconds, it takes to do one full interpolation.
- * @param count    Controls how many interpolations we want to do. See {@link Dynamic#setCount(float)}
- * @return         ID of the effect added, or -1 if we failed to add one. 
- */
-  public long smooth_contrast(float contrast, Static4D region, Static2D center, int duration, float count)
-    {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(count);
-    di.setDuration(duration);
-    di.add(new Static1D(1));
-    di.add(new Static1D(contrast));
-   
-    return mF.add(EffectNames.SMOOTH_CONTRAST, di, region, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes a certain sub-region of the Object smoothly change its contrast level.
- * <p>
- * Here the center of the Effect stays constant and the effect for now change in time.
- *         
- * @param contrast Level of contrast (between 0 and infinity) we want to interpolate to.
- *                 1 - level of contrast unchanged, anything less than 1 - reduce contrast,
- *                 anything more than 1 - increase the contrast. 
- * @param region   Region this Effect is limited to. 
- *                 Null here means 'apply the Effect to the whole Object'.
- * @param center   Center of the Effect.
- * @return         ID of the effect added, or -1 if we failed to add one. 
- */
-  public long smooth_contrast(float contrast, Static4D region, Static2D center)
-    {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(0.5f);
-    di.setDuration(0);
-    di.add(new Static1D(1));
-    di.add(new Static1D(contrast));
-   
-    return mF.add(EffectNames.SMOOTH_CONTRAST, di, region, center);
-    }
-    
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes the whole Object change its contrast level.
- * 
- * @param contrast Level of contrast (between 0 and infinity) we want to interpolate to.
- *                 1 - level of contrast unchanged, anything less than 1 - reduce contrast,
- *                 anything more than 1 - increase the contrast.
- * @param duration Time, in milliseconds, it takes to do one full interpolation.
- * @param count    Controls how many interpolations we want to do. See {@link Dynamic#setCount(float)}
- * @return         ID of the effect added, or -1 if we failed to add one. 
- */
-  public long smooth_contrast(float contrast, int duration, float count) 
-    {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(count);
-    di.setDuration(duration);
-    di.add(new Static1D(1));
-    di.add(new Static1D(contrast));
-         
-    return mF.add(EffectNames.SMOOTH_CONTRAST, di,null, mZero2D);
-    }
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// SATURATION
-/**
- * Makes a certain sub-region of the Object smoothly change its saturation level.
- *        
- * @param saturation 1-dimensional Dynamic that returns the level of saturation we want to have
- *                   at any given moment.
- * @param region     Region this Effect is limited to.
- *                   Null here means 'apply the Effect to the whole Object'.
- * @param center     2-dimensional Dynamic which, at any given time, returns a Static2D
- *                   representing the current center of the effect.
- * @return           ID of the effect added, or -1 if we failed to add one.
- */
-  public long saturation(Dynamic1D saturation, Static4D region, Dynamic2D center)
-    {
-    return mF.add(EffectNames.SATURATION, saturation, region, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes a certain sub-region of the Object smoothly change its saturation level.
- * <p>
- * Here the center of the Effect stays constant.
- *         
- * @param saturation 1-dimensional Dynamic that returns the level of saturation we want to have
- *                   at any given moment.
- * @param region     Region this Effect is limited to.
- *                   Null here means 'apply the Effect to the whole Object'.
- * @param center     Center of the Effect.
- * @return           ID of the effect added, or -1 if we failed to add one.
- */
-  public long saturation(Dynamic1D saturation, Static4D region, Static2D center)
-    {
-    return mF.add(EffectNames.SATURATION, saturation, region, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////  
-/**
- * Makes a certain sub-region of the Object smoothly change its saturation level.
- *        
- * @param saturation Level of saturation (between 0 and infinity) we want to interpolate to.
- *                   1 - level of saturation unchanged, anything less than 1 - reduce saturation,
- *                   anything more than 1 - increase the saturation. 
- * @param region     Region this Effect is limited to.
- *                   Null here means 'apply the Effect to the whole Object'.
- * @param center     2-dimensional Dynamic which, at any given time, returns a Static2D
- *                   representing the current center of the effect.
- * @param duration   Time, in milliseconds, it takes to do one full interpolation.
- * @param count      Controls how many interpolations we want to do. See {@link Dynamic#setCount(float)}
- * @return           ID of the effect added, or -1 if we failed to add one. 
- */
-  public long saturation(float saturation, Static4D region, Dynamic2D center, int duration, float count)
-    {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(count);
-    di.setDuration(duration);
-    di.add(new Static1D(1));
-    di.add(new Static1D(saturation));
-   
-    return mF.add(EffectNames.SATURATION, di, region, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes a certain sub-region of the Object smoothly change its saturation level.
- * <p>
- * Here the center of the Effect stays constant.
- *         
- * @param saturation Level of saturation (between 0 and infinity) we want to interpolate to.
- *                   1 - level of saturation unchanged, anything less than 1 - reduce saturation,
- *                   anything more than 1 - increase the saturation. 
- * @param region     Region this Effect is limited to. 
- *                   Null here means 'apply the Effect to the whole Object'.
- * @param center     Center of the Effect.
- * @param duration   Time, in milliseconds, it takes to do one full interpolation.
- * @param count      Controls how many interpolations we want to do. See {@link Dynamic#setCount(float)}
- * @return           ID of the effect added, or -1 if we failed to add one. 
- */
-  public long saturation(float saturation, Static4D region, Static2D center, int duration, float count)
-    {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(count);
-    di.setDuration(duration);
-    di.add(new Static1D(1));
-    di.add(new Static1D(saturation));
-   
-    return mF.add(EffectNames.SATURATION, di, region, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes a certain sub-region of the Object smoothly change its saturation level.
- * <p>
- * Here the center of the Effect stays constant and the effect for now change in time.
- *         
- * @param saturation Level of saturation (between 0 and infinity) we want to interpolate to.
- *                   1 - level of saturation unchanged, anything less than 1 - reduce saturation,
- *                   anything more than 1- increase the saturation. 
- * @param region     Region this Effect is limited to. 
- *                   Null here means 'apply the Effect to the whole Object'.
- * @param center     Center of the Effect.
- * @return           ID of the effect added, or -1 if we failed to add one. 
- */
-  public long saturation(float saturation, Static4D region, Static2D center)
-    {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(0.5f);
-    di.setDuration(0);
-    di.add(new Static1D(1));
-    di.add(new Static1D(saturation));
-   
-    return mF.add(EffectNames.SATURATION, di, region, center);
-    }
- 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// SMOOTH_SATURATION
-/**
- * Makes a certain sub-region of the Object smoothly change its saturation level.
- *        
- * @param saturation 1-dimensional Dynamic that returns the level of saturation we want to have
- *                   at any given moment.
- * @param region     Region this Effect is limited to.
- *                   Null here means 'apply the Effect to the whole Object'.
- * @param center     2-dimensional Dynamic which, at any given time, returns a Static2D
- *                   representing the current center of the effect.
- * @return           ID of the effect added, or -1 if we failed to add one.
- */
-  public long smooth_saturation(Dynamic1D saturation, Static4D region, Dynamic2D center)
-    {
-    return mF.add(EffectNames.SMOOTH_SATURATION, saturation, region, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes a certain sub-region of the Object smoothly change its saturation level.
- * <p>
- * Here the center of the Effect stays constant.
- *         
- * @param saturation 1-dimensional Dynamic that returns the level of saturation we want to have
- *                   at any given moment.
- * @param region     Region this Effect is limited to.
- *                   Null here means 'apply the Effect to the whole Object'.
- * @param center     Center of the Effect.
- * @return           ID of the effect added, or -1 if we failed to add one.
- */
-  public long smooth_saturation(Dynamic1D saturation, Static4D region, Static2D center)
-    {
-    return mF.add(EffectNames.SMOOTH_SATURATION, saturation, region, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////  
-/**
- * Makes a certain sub-region of the Object smoothly change its saturation level.
- *        
- * @param saturation Level of saturation (between 0 and infinity) we want to interpolate to.
- *                   1 - level of saturation unchanged, anything less than 1 - reduce saturation,
- *                   anything more than 1 -increase the saturation. 
- * @param region     Region this Effect is limited to. 
- *                   Null here means 'apply the Effect to the whole Object'.
- * @param center     2-dimensional Dynamic which, at any given time, returns a Static2D
- *                   representing the current center of the effect.
- * @param duration   Time, in milliseconds, it takes to do one full interpolation.
- * @param count      Controls how many interpolations we want to do. See {@link Dynamic#setCount(float)}
- * @return           ID of the effect added, or -1 if we failed to add one. 
- */
-  public long smooth_saturation(float saturation, Static4D region, Dynamic2D center, int duration, float count)
-    {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(count);
-    di.setDuration(duration);
-    di.add(new Static1D(1));
-    di.add(new Static1D(saturation));
-   
-    return mF.add(EffectNames.SMOOTH_SATURATION, di, region, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes a certain sub-region of the Object smoothly change its saturation level.
- * <p>
- * Here the center of the Effect stays constant.
- *         
- * @param saturation Level of saturation (between 0 and infinity) we want to interpolate to.
- *                   1 - level of saturation unchanged, anything less than 1 - reduce saturation,
- *                   anything more than 1 - increase the saturation. 
- * @param region     Region this Effect is limited to. 
- *                   Null here means 'apply the Effect to the whole Object'.
- * @param center     Center of the Effect.
- * @param duration   Time, in milliseconds, it takes to do one full interpolation.
- * @param count      Controls how many interpolations we want to do. See {@link Dynamic#setCount(float)}
- * @return           ID of the effect added, or -1 if we failed to add one. 
- */
-  public long smooth_saturation(float saturation, Static4D region, Static2D center, int duration, float count)
-    {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(count);
-    di.setDuration(duration);
-    di.add(new Static1D(1));
-    di.add(new Static1D(saturation));
-   
-    return mF.add(EffectNames.SMOOTH_SATURATION, di, region, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes a certain sub-region of the Object smoothly change its saturation level.
- * <p>
- * Here the center of the Effect stays constant and the effect for now change in time.
- *         
- * @param saturation Level of saturation (between 0 and infinity) we want to interpolate to.
- *                   1 - level of saturation unchanged, anything less than 1 - reduce saturation,
- *                   anything more than 1 - increase the saturation. 
- * @param region     Region this Effect is limited to. 
- *                   Null here means 'apply the Effect to the whole Object'.
- * @param center     Center of the Effect.
- * @return           ID of the effect added, or -1 if we failed to add one. 
- */
-  public long smooth_saturation(float saturation, Static4D region, Static2D center)
-    {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(0.5f);
-    di.setDuration(0);
-    di.add(new Static1D(1));
-    di.add(new Static1D(saturation));
-   
-    return mF.add(EffectNames.SMOOTH_SATURATION, di, region, center);
-    }
-    
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes the whole Object change its saturation level.
- * 
- * @param saturation Level of saturation (between 0 and infinity) we want to interpolate to.
- *                   1 - level of saturation unchanged, anything less than 1 - reduce saturation,
- *                   anything more than 1 - increase the saturation. 
- * @param duration   Time, in milliseconds, it takes to do one full interpolation.
- * @param count      Controls how many interpolations we want to do. See {@link Dynamic#setCount(float)}
- * @return           ID of the effect added, or -1 if we failed to add one. 
- */
-  public long smooth_saturation(float saturation, int duration, float count) 
-    {
-    Dynamic1D di = new Dynamic1D();
-    di.setCount(count);
-    di.setDuration(duration);
-    di.add(new Static1D(1));
-    di.add(new Static1D(saturation));
-         
-    return mF.add(EffectNames.SMOOTH_SATURATION, di,null, mZero2D);
-    }
-            
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Vertex-based effects  
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/library/EffectQueue.java b/src/main/java/org/distorted/library/EffectQueue.java
index 0b4e5f3..3aa5e76 100644
--- a/src/main/java/org/distorted/library/EffectQueue.java
+++ b/src/main/java/org/distorted/library/EffectQueue.java
@@ -81,7 +81,7 @@ abstract class EffectQueue
       mType            = new int[mMax[mMaxIndex]];
       mUniforms        = new float[numUniforms*mMax[mMaxIndex]];
       mInterI          = new Dynamic[mMax[mMaxIndex]];
-      mInterP          = new Dynamic2D[mMax[mMaxIndex]];
+      mInterP          = new Dynamic[mMax[mMaxIndex]];
       mCurrentDuration = new long[mMax[mMaxIndex]];
       mID              = new long[mMax[mMaxIndex]];
       mIDIndex         = new byte[mMax[mMaxIndex]];
diff --git a/src/main/java/org/distorted/library/EffectQueueFragment.java b/src/main/java/org/distorted/library/EffectQueueFragment.java
index 863b1f1..9f43117 100644
--- a/src/main/java/org/distorted/library/EffectQueueFragment.java
+++ b/src/main/java/org/distorted/library/EffectQueueFragment.java
@@ -22,7 +22,11 @@ package org.distorted.library;
 import android.opengl.GLES20;
 
 import org.distorted.library.message.EffectMessage;
+import org.distorted.library.type.Data1D;
+import org.distorted.library.type.Data4D;
 import org.distorted.library.type.Dynamic1D;
+import org.distorted.library.type.Dynamic4D;
+import org.distorted.library.type.Static1D;
 import org.distorted.library.type.Static2D;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
@@ -33,7 +37,7 @@ import org.distorted.library.type.Dynamic2D;
 
 class EffectQueueFragment extends EffectQueue
   {
-  private static final int NUM_UNIFORMS = 9;
+  private static final int NUM_UNIFORMS = 8;
   private static final int INDEX = EffectTypes.FRAGMENT.ordinal();
   private float[] mBuf;
   private static int mNumEffectsH;
@@ -123,7 +127,7 @@ class EffectQueueFragment extends EffectQueue
     if( mNumEffects>0 )
       {     
       GLES20.glUniform1iv( mTypeH    ,  mNumEffects, mType    ,0);
-      GLES20.glUniform3fv( mUniformsH,3*mNumEffects, mUniforms,0);
+      GLES20.glUniform4fv( mUniformsH,2*mNumEffects, mUniforms,0);
       }  
     }
 
@@ -151,13 +155,12 @@ class EffectQueueFragment extends EffectQueue
         {   
         tx = mBuf[4*i  ]-mObjHalfX; // we have to invert y and move everything by (half of bmp width, half of bmp height)
         ty =-mBuf[4*i+1]+mObjHalfY; //
-      
-        mUniforms[NUM_UNIFORMS*i+4] = w*mBuf[4*i+2];                                  // in fragment shader rx and ry radii are the second and third values of the Region thus 9*i+4 and 9*i+5
-        mUniforms[NUM_UNIFORMS*i+5] = h*mBuf[4*i+3];                                  // 
-     // mUniforms[NUM_UNIFORMS*i+6] =                                                 // this value is not used in Fragment Shader   
-        mUniforms[NUM_UNIFORMS*i+7] = MVmatrix[0]*tx + MVmatrix[4]*ty + MVmatrix[12]; // multiply the ModelView matrix times the (x,y,0,1) point, i.e. the (x,y) point on the surface of the bitmap.
-        mUniforms[NUM_UNIFORMS*i+8] = MVmatrix[1]*tx + MVmatrix[5]*ty + MVmatrix[13]; //  
-        
+
+        mUniforms[NUM_UNIFORMS*i+4] = MVmatrix[0]*tx + MVmatrix[4]*ty + MVmatrix[12]; // multiply the ModelView matrix times the (x,y,0,1) point, i.e. the (x,y) point on the surface of the bitmap.
+        mUniforms[NUM_UNIFORMS*i+5] = MVmatrix[1]*tx + MVmatrix[5]*ty + MVmatrix[13]; //
+        mUniforms[NUM_UNIFORMS*i+6] = w*mBuf[4*i+2];                                  // in fragment shader rx and ry radii are the last two values of the second vec4
+        mUniforms[NUM_UNIFORMS*i+7] = h*mBuf[4*i+3];                                  //
+
         if( mType[i]==EffectNames.MACROBLOCK.ordinal() ) // fill up the .y and .z components of the Interpolated values already to avoid having to compute this in the fragment shader
           {
           mUniforms[NUM_UNIFORMS*i+1] = 2.0f*mObjHalfX/mUniforms[NUM_UNIFORMS*i];
@@ -168,28 +171,26 @@ class EffectQueueFragment extends EffectQueue
     }
   
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-       
-  synchronized long add(EffectNames eln, Dynamic inter, Static4D region, Dynamic2D point)
+// macroblock, alpha, brightness, contrast, saturation
+
+  synchronized long add(EffectNames eln, Data1D data)
     {
     if( mMax[INDEX]>mNumEffects )
       {
       EffectNames.fillWithUnities(eln.ordinal(), mUniforms, NUM_UNIFORMS*mNumEffects); 
-      mInterI[mNumEffects] = inter;
-      mInterP[mNumEffects] = point;
 
-      if( region==null )
+      if( data instanceof Dynamic1D)
+        mInterI[mNumEffects] = (Dynamic1D)data;
+      else if( data instanceof Static1D )
         {
-        mBuf[4*mNumEffects+2] = 1000*mObjHalfX;
-        mBuf[4*mNumEffects+3] = 1000*mObjHalfY;
+        mInterI[mNumEffects] = null;
+        mUniforms[NUM_UNIFORMS*mNumEffects] = ((Static1D)data).getX();
         }
-      else
-        {
-        float z = region.getZ();
-        float w = region.getW();
+      else return -1;
 
-        mBuf[4*mNumEffects+2] = z<=0.0f ? 1000*mObjHalfX : z;
-        mBuf[4*mNumEffects+3] = w<=0.0f ? 1000*mObjHalfY : w;
-        }
+      mInterP[mNumEffects] = null;
+      mBuf[4*mNumEffects+2] = 1000*mObjHalfX;
+      mBuf[4*mNumEffects+3] = 1000*mObjHalfY;
 
       return addBase(eln); 
       }
@@ -198,30 +199,34 @@ class EffectQueueFragment extends EffectQueue
     }
   
 ///////////////////////////////////////////////////////////////////////////////////////////////////
+// macroblock, alpha, brightness, contrast, saturation
 
-  synchronized long add(EffectNames eln, Dynamic inter, Static4D region, Static2D point)
+  synchronized long add(EffectNames eln, Data1D data, Data4D region)
     {
     if( mMax[INDEX]>mNumEffects )
       {
-      EffectNames.fillWithUnities(eln.ordinal(), mUniforms, NUM_UNIFORMS*mNumEffects);    
-      mInterI[mNumEffects] = inter;
-      mInterP[mNumEffects] = null;
-      mBuf[4*mNumEffects  ] = point.getX();
-      mBuf[4*mNumEffects+1] = point.getY();
+      EffectNames.fillWithUnities(eln.ordinal(), mUniforms, NUM_UNIFORMS*mNumEffects);
 
-      if( region==null )
+      if( data instanceof Dynamic1D)
+        mInterI[mNumEffects] = (Dynamic1D)data;
+      else if( data instanceof Static1D )
         {
-        mBuf[4*mNumEffects+2] = 1000*mObjHalfX;
-        mBuf[4*mNumEffects+3] = 1000*mObjHalfY;
+        mInterI[mNumEffects] = null;
+        mUniforms[NUM_UNIFORMS*mNumEffects] = ((Static1D)data).getX();
         }
-      else
-        {
-        float z = region.getZ();
-        float w = region.getW();
+      else return -1;
 
-        mBuf[4*mNumEffects+2] = z<=0.0f ? 1000*mObjHalfX : z;
-        mBuf[4*mNumEffects+3] = w<=0.0f ? 1000*mObjHalfY : w;
+      if( region instanceof Dynamic4D)
+        mInterP[mNumEffects] = (Dynamic4D)region;
+      else if( region instanceof Static4D )
+        {
+        mInterP[mNumEffects]  = null;
+        mBuf[4*mNumEffects  ] = ((Static4D)region).getX();
+        mBuf[4*mNumEffects+1] = ((Static4D)region).getY();
+        mBuf[4*mNumEffects+2] = ((Static4D)region).getZ();
+        mBuf[4*mNumEffects+3] = ((Static4D)region).getW();
         }
+      else return -1;
 
       return addBase(eln);
       }
@@ -230,32 +235,39 @@ class EffectQueueFragment extends EffectQueue
     }
   
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-       
-  synchronized long add(EffectNames eln, Dynamic1D inter, Static3D c, Static4D region, Dynamic2D point)
+// chroma
+
+  synchronized long add(EffectNames eln, Data1D level, Static3D color, Data4D region)
     {
     if( mMax[INDEX]>mNumEffects )
       {
-      mInterI[mNumEffects] = inter;
-      mInterP[mNumEffects] = point;
+      EffectNames.fillWithUnities(eln.ordinal(), mUniforms, NUM_UNIFORMS*mNumEffects);
 
-      if( region==null )
+      if( level instanceof Dynamic1D)
+        mInterI[mNumEffects] = (Dynamic1D)level;
+      else if( level instanceof Static1D )
         {
-        mBuf[4*mNumEffects+2] = 1000*mObjHalfX;
-        mBuf[4*mNumEffects+3] = 1000*mObjHalfY;
+        mInterI[mNumEffects] = null;
+        mUniforms[NUM_UNIFORMS*mNumEffects] = ((Static1D)level).getX();
         }
-      else
-        {
-        float z = region.getZ();
-        float w = region.getW();
+      else return -1;
 
-        mBuf[4*mNumEffects+2] = z<=0.0f ? 1000*mObjHalfX : z;
-        mBuf[4*mNumEffects+3] = w<=0.0f ? 1000*mObjHalfY : w;
+      mUniforms[NUM_UNIFORMS*mNumEffects+1] = color.getX();
+      mUniforms[NUM_UNIFORMS*mNumEffects+2] = color.getY();
+      mUniforms[NUM_UNIFORMS*mNumEffects+3] = color.getZ();
+
+      if( region instanceof Dynamic4D)
+        mInterP[mNumEffects] = (Dynamic4D)region;
+      else if( region instanceof Static4D )
+        {
+        mInterP[mNumEffects]  = null;
+        mBuf[4*mNumEffects  ] = ((Static4D)region).getX();
+        mBuf[4*mNumEffects+1] = ((Static4D)region).getY();
+        mBuf[4*mNumEffects+2] = ((Static4D)region).getZ();
+        mBuf[4*mNumEffects+3] = ((Static4D)region).getW();
         }
+      else return -1;
 
-      mUniforms[NUM_UNIFORMS*mNumEffects+1] = c.getX();
-      mUniforms[NUM_UNIFORMS*mNumEffects+2] = c.getY();
-      mUniforms[NUM_UNIFORMS*mNumEffects+3] = c.getZ();
-     
       return addBase(eln); 
       }
       
@@ -263,34 +275,31 @@ class EffectQueueFragment extends EffectQueue
     }
   
 ///////////////////////////////////////////////////////////////////////////////////////////////////
+// chroma
 
-  synchronized long add(EffectNames eln, Dynamic1D inter, Static3D c, Static4D region, Static2D point)
+  synchronized long add(EffectNames eln, Data1D level, Static3D color)
     {
     if( mMax[INDEX]>mNumEffects )
       {
-      mInterI[mNumEffects] = inter;
-      mInterP[mNumEffects] = null;
-      mBuf[4*mNumEffects  ] = point.getX();
-      mBuf[4*mNumEffects+1] = point.getY();
+      EffectNames.fillWithUnities(eln.ordinal(), mUniforms, NUM_UNIFORMS*mNumEffects);
 
-      if( region==null )
+      if( level instanceof Dynamic1D)
+        mInterI[mNumEffects] = (Dynamic1D)level;
+      else if( level instanceof Static1D )
         {
-        mBuf[4*mNumEffects+2] = 1000*mObjHalfX;
-        mBuf[4*mNumEffects+3] = 1000*mObjHalfY;
+        mInterI[mNumEffects] = null;
+        mUniforms[NUM_UNIFORMS*mNumEffects] = ((Static1D)level).getX();
         }
-      else
-        {
-        float z = region.getZ();
-        float w = region.getW();
+      else return -1;
 
-        mBuf[4*mNumEffects+2] = z<=0.0f ? 1000*mObjHalfX : z;
-        mBuf[4*mNumEffects+3] = w<=0.0f ? 1000*mObjHalfY : w;
-        }
+      mUniforms[NUM_UNIFORMS*mNumEffects+1] = color.getX();
+      mUniforms[NUM_UNIFORMS*mNumEffects+2] = color.getY();
+      mUniforms[NUM_UNIFORMS*mNumEffects+3] = color.getZ();
+
+      mInterP[mNumEffects]  = null;            //
+      mBuf[4*mNumEffects+2] = 1000*mObjHalfX;  // i.e. null region
+      mBuf[4*mNumEffects+3] = 1000*mObjHalfY;  //
 
-      mUniforms[NUM_UNIFORMS*mNumEffects+1] = c.getX();
-      mUniforms[NUM_UNIFORMS*mNumEffects+2] = c.getY();
-      mUniforms[NUM_UNIFORMS*mNumEffects+3] = c.getZ();
-   
       return addBase(eln);
       }
        
@@ -298,33 +307,38 @@ class EffectQueueFragment extends EffectQueue
     }
   
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-       
-  synchronized long add(EffectNames eln, float t, Static3D c, Static4D region, Dynamic2D point)
+// chroma
+
+  synchronized long add(EffectNames eln, Data4D chroma, Data4D region)
     {
     if( mMax[INDEX]>mNumEffects )
       {
-      mInterI[mNumEffects] = null;
-      mInterP[mNumEffects] = point;
+      EffectNames.fillWithUnities(eln.ordinal(), mUniforms, NUM_UNIFORMS*mNumEffects);
 
-      if( region==null )
+      if( chroma instanceof Dynamic4D)
+        mInterI[mNumEffects] = (Dynamic4D)chroma;
+      else if( chroma instanceof Static4D )
         {
-        mBuf[4*mNumEffects+2] = 1000*mObjHalfX;
-        mBuf[4*mNumEffects+3] = 1000*mObjHalfY;
+        mInterI[mNumEffects] = null;
+        mUniforms[NUM_UNIFORMS*mNumEffects  ] = ((Static4D)chroma).getX();
+        mUniforms[NUM_UNIFORMS*mNumEffects+1] = ((Static4D)chroma).getY();
+        mUniforms[NUM_UNIFORMS*mNumEffects+2] = ((Static4D)chroma).getZ();
+        mUniforms[NUM_UNIFORMS*mNumEffects+3] = ((Static4D)chroma).getW();
         }
-      else
-        {
-        float z = region.getZ();
-        float w = region.getW();
+      else return -1;
 
-        mBuf[4*mNumEffects+2] = z<=0.0f ? 1000*mObjHalfX : z;
-        mBuf[4*mNumEffects+3] = w<=0.0f ? 1000*mObjHalfY : w;
+      if( region instanceof Dynamic4D)
+        mInterP[mNumEffects] = (Dynamic4D)region;
+      else if( region instanceof Static4D )
+        {
+        mInterP[mNumEffects]  = null;
+        mBuf[4*mNumEffects  ] = ((Static4D)region).getX();
+        mBuf[4*mNumEffects+1] = ((Static4D)region).getY();
+        mBuf[4*mNumEffects+2] = ((Static4D)region).getZ();
+        mBuf[4*mNumEffects+3] = ((Static4D)region).getW();
         }
+      else return -1;
 
-      mUniforms[NUM_UNIFORMS*mNumEffects+0] = t;
-      mUniforms[NUM_UNIFORMS*mNumEffects+1] = c.getX();
-      mUniforms[NUM_UNIFORMS*mNumEffects+2] = c.getY();
-      mUniforms[NUM_UNIFORMS*mNumEffects+3] = c.getZ();
-     
       return addBase(eln); 
       }
       
@@ -332,35 +346,30 @@ class EffectQueueFragment extends EffectQueue
     }
   
 ///////////////////////////////////////////////////////////////////////////////////////////////////
+// chroma
 
-  synchronized long add(EffectNames eln, float t, Static3D c, Static4D region, Static2D point)
+  synchronized long add(EffectNames eln, Data4D chroma)
     {
     if( mMax[INDEX]>mNumEffects )
       {
-      mInterI[mNumEffects] = null;
-      mInterP[mNumEffects] = null;
-      mBuf[4*mNumEffects  ] = point.getX();
-      mBuf[4*mNumEffects+1] = point.getY();
+      EffectNames.fillWithUnities(eln.ordinal(), mUniforms, NUM_UNIFORMS*mNumEffects);
 
-      if( region==null )
+      if( chroma instanceof Dynamic4D)
+        mInterI[mNumEffects] = (Dynamic4D)chroma;
+      else if( chroma instanceof Static4D )
         {
-        mBuf[4*mNumEffects+2] = 1000*mObjHalfX;
-        mBuf[4*mNumEffects+3] = 1000*mObjHalfY;
+        mInterI[mNumEffects] = null;
+        mUniforms[NUM_UNIFORMS*mNumEffects  ] = ((Static4D)chroma).getX();
+        mUniforms[NUM_UNIFORMS*mNumEffects+1] = ((Static4D)chroma).getY();
+        mUniforms[NUM_UNIFORMS*mNumEffects+2] = ((Static4D)chroma).getZ();
+        mUniforms[NUM_UNIFORMS*mNumEffects+3] = ((Static4D)chroma).getW();
         }
-      else
-        {
-        float z = region.getZ();
-        float w = region.getW();
+      else return -1;
 
-        mBuf[4*mNumEffects+2] = z<=0.0f ? 1000*mObjHalfX : z;
-        mBuf[4*mNumEffects+3] = w<=0.0f ? 1000*mObjHalfY : w;
-        }
+      mInterP[mNumEffects]  = null;            //
+      mBuf[4*mNumEffects+2] = 1000*mObjHalfX;  // i.e. null region
+      mBuf[4*mNumEffects+3] = 1000*mObjHalfY;  //
 
-      mUniforms[NUM_UNIFORMS*mNumEffects+0] = t;
-      mUniforms[NUM_UNIFORMS*mNumEffects+1] = c.getX();
-      mUniforms[NUM_UNIFORMS*mNumEffects+2] = c.getY();
-      mUniforms[NUM_UNIFORMS*mNumEffects+3] = c.getZ();
-   
       return addBase(eln);
       }
       
diff --git a/src/main/res/raw/main_fragment_shader.glsl b/src/main/res/raw/main_fragment_shader.glsl
index 6088790..f611bdb 100644
--- a/src/main/res/raw/main_fragment_shader.glsl
+++ b/src/main/res/raw/main_fragment_shader.glsl
@@ -21,7 +21,7 @@ precision highp float;
   
 uniform sampler2D u_Texture;            // The input texture.
     
-varying vec3 v_Position;		// Interpolated position for this fragment.
+varying vec3 v_Position;                // Interpolated position for this fragment.
 varying vec4 v_Color;                   // This is the color from the vertex shader interpolated across the triangle per fragment.
 varying vec3 v_Normal;                  // Interpolated normal for this fragment.
 varying vec2 v_TexCoordinate;           // Interpolated texture coordinate per fragment.
@@ -30,10 +30,9 @@ uniform int fNumEffects;                // total number of fragment effects
 
 #if NUM_FRAGMENT>0
 uniform int fType[NUM_FRAGMENT];        // their types.
-uniform vec3 fUniforms[3*NUM_FRAGMENT]; // i-th effect is 3 consecutive vec3's: [3*i], [3*i+1], [3*i+2]. first 4 floats are the Interpolated values,
-                                        // next 5 describe the Region, i.e. area over which the effect is active.
-                                        // Important note: here the Region is written in a different order than in the Vertex shader.
- 
+uniform vec4 fUniforms[2*NUM_FRAGMENT]; // i-th effect is 2 consecutive vec4's: [2*i], [2*i+1]. First vec4 is the Interpolated values,
+                                        // next describes the Region, i.e. area over which the effect is active.
+
 const vec3 LUMI = vec3( 0.2125, 0.7154, 0.0721 );                                        
  
 //////////////////////////////////////////////////////////////////////////////////////////////
@@ -51,7 +50,7 @@ void macroblock(float degree, int effect, inout vec2 tex)
 
 void chroma(float degree, int effect, inout vec4 color)
   {
-  color.rgb = mix(color.rgb, vec3(fUniforms[effect].yz,fUniforms[effect+1].x), degree*fUniforms[effect].x); 
+  color.rgb = mix(color.rgb, fUniforms[effect].yzw, degree*fUniforms[effect].x);
   }
 
 //////////////////////////////////////////////////////////////////////////////////////////////
@@ -101,35 +100,35 @@ void main()
 #if NUM_FRAGMENT>0  
   for(int i=0; i<fNumEffects; i++)
     {
-    diff = (v_Position.xy - fUniforms[3*i+2].yz)/fUniforms[3*i+1].yz;
+    diff = (v_Position.xy - fUniforms[2*i+1].xy)/fUniforms[2*i+1].zw;
     pointDegree = max(0.0,1.0-dot(diff,diff));
   
-    //switch(fType[i])
+    //switch(fType[i])  // future version of GLSL
     //  {
-    //  case MACROBLOCK        : macroblock(sign(pointDegree),3*i,tex); break;
-    //  case CHROMA            : chroma    (sign(pointDegree),3*i,col); break;
-    //  case SMOOTH_CHROMA     : chroma    (     pointDegree ,3*i,col); break;
-    //  case ALPHA             : alpha     (sign(pointDegree),3*i,col); break;
-    //  case SMOOTH_ALPHA      : alpha     (     pointDegree ,3*i,col); break;
-    //  case BRIGHTNESS        : brightness(sign(pointDegree),3*i,col); break;
-    //  case SMOOTH_BRIGHTNESS : brightness(     pointDegree ,3*i,col); break;
-    //  case CONTRAST          : contrast  (sign(pointDegree),3*i,col); break;
-    //  case SMOOTH_CONTRAST   : contrast  (     pointDegree ,3*i,col); break;
-    //  case SATURATION        : saturation(sign(pointDegree),3*i,col); break;
-    //  case SMOOTH_SATURATION : saturation(     pointDegree ,3*i,col); break;
+    //  case MACROBLOCK        : macroblock(sign(pointDegree),2*i,tex); break;
+    //  case CHROMA            : chroma    (sign(pointDegree),2*i,col); break;
+    //  case SMOOTH_CHROMA     : chroma    (     pointDegree ,2*i,col); break;
+    //  case ALPHA             : alpha     (sign(pointDegree),2*i,col); break;
+    //  case SMOOTH_ALPHA      : alpha     (     pointDegree ,2*i,col); break;
+    //  case BRIGHTNESS        : brightness(sign(pointDegree),2*i,col); break;
+    //  case SMOOTH_BRIGHTNESS : brightness(     pointDegree ,2*i,col); break;
+    //  case CONTRAST          : contrast  (sign(pointDegree),2*i,col); break;
+    //  case SMOOTH_CONTRAST   : contrast  (     pointDegree ,2*i,col); break;
+    //  case SATURATION        : saturation(sign(pointDegree),2*i,col); break;
+    //  case SMOOTH_SATURATION : saturation(     pointDegree ,2*i,col); break;
     //  }
     
-         if( fType[i]==MACROBLOCK        ) macroblock(sign(pointDegree),3*i,tex);
-    else if( fType[i]==CHROMA            ) chroma    (sign(pointDegree),3*i,col);
-    else if( fType[i]==SMOOTH_CHROMA     ) chroma    (     pointDegree ,3*i,col);
-    else if( fType[i]==ALPHA             ) alpha     (sign(pointDegree),3*i,col);
-    else if( fType[i]==SMOOTH_ALPHA      ) alpha     (     pointDegree ,3*i,col);
-    else if( fType[i]==BRIGHTNESS        ) brightness(sign(pointDegree),3*i,col);
-    else if( fType[i]==SMOOTH_BRIGHTNESS ) brightness(     pointDegree ,3*i,col);
-    else if( fType[i]==CONTRAST          ) contrast  (sign(pointDegree),3*i,col);
-    else if( fType[i]==SMOOTH_CONTRAST   ) contrast  (     pointDegree ,3*i,col);
-    else if( fType[i]==SATURATION        ) saturation(sign(pointDegree),3*i,col);
-    else if( fType[i]==SMOOTH_SATURATION ) saturation(     pointDegree ,3*i,col);
+         if( fType[i]==MACROBLOCK        ) macroblock(sign(pointDegree),2*i,tex);
+    else if( fType[i]==CHROMA            ) chroma    (sign(pointDegree),2*i,col);
+    else if( fType[i]==SMOOTH_CHROMA     ) chroma    (     pointDegree ,2*i,col);
+    else if( fType[i]==ALPHA             ) alpha     (sign(pointDegree),2*i,col);
+    else if( fType[i]==SMOOTH_ALPHA      ) alpha     (     pointDegree ,2*i,col);
+    else if( fType[i]==BRIGHTNESS        ) brightness(sign(pointDegree),2*i,col);
+    else if( fType[i]==SMOOTH_BRIGHTNESS ) brightness(     pointDegree ,2*i,col);
+    else if( fType[i]==CONTRAST          ) contrast  (sign(pointDegree),2*i,col);
+    else if( fType[i]==SMOOTH_CONTRAST   ) contrast  (     pointDegree ,2*i,col);
+    else if( fType[i]==SATURATION        ) saturation(sign(pointDegree),2*i,col);
+    else if( fType[i]==SMOOTH_SATURATION ) saturation(     pointDegree ,2*i,col);
     }
 #endif
  
