commit 1585ba24cdb1e2d9b1856f82f561500155e23b4f
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Wed Jan 2 15:57:54 2019 +0000

    Make the Fragment effects truly 3D: change their 4D 'region' into a 3D 'center' (a point in 3D) and 3D 'region' (which is now a set of 3 radii defining an ellipsoid around the center)
    
    Also corresponding changes to the applications.

diff --git a/src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldEffectsManager.java b/src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldEffectsManager.java
index 64a483b..e183b1b 100644
--- a/src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldEffectsManager.java
+++ b/src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldEffectsManager.java
@@ -78,12 +78,14 @@ class AroundTheWorldEffectsManager
 
   // Fragment effects:
   // a) change color of the skin to more brown and less red (CHROMA)
-  private Static4D aSkinColorRegion;
+  private Static3D aSkinColorCenter;
+  private Static3D aSkinColorRegion;
   private Static3D aChromaSkin;
   private Static1D aChromaSkinFactor;
   private Dynamic1D aChromaSkinDyn;
   // b) darken both eyes (2 x SMOOTH_CHROMA)
-  private Static4D aLEyeColorRegion, aREyeColorRegion;
+  private Static3D aLEyeColorCenter, aREyeColorCenter;
+  private Static3D aLEyeColorRegion, aREyeColorRegion;
   private Static3D aChromaEyes;
   private Static1D aChromaEyesFactor;
   private Dynamic1D aChromaEyesDyn;
@@ -117,17 +119,20 @@ class AroundTheWorldEffectsManager
   private Dynamic2D bLipsDyn;
   // Fragment effects
   // a) make the whole face darker (CHROMA)
-  private Static4D bSkinColorRegion;
+  private Static3D bSkinColorCenter;
+  private Static3D bSkinColorRegion;
   private Static3D bChromaSkin;
   private Static1D bChromaSkinFactor;
   private Dynamic1D bChromaSkinDyn;
   // b) move both eyes back to whiteness (2 x SMOOTH CHROMA)
-  private Static4D bLEyeColorRegion, bREyeColorRegion;
+  private Static3D bLEyeColorCenter, bREyeColorCenter;
+  private Static3D bLEyeColorRegion, bREyeColorRegion;
   private Static3D bChromaEyes;
   private Static1D bChromaEyesFactor;
   private Dynamic1D bChromaEyesDyn;
   // c) darken both pupils (2 x SMOOTH_CHROMA)
-  private Static4D bLPupilColorRegion, bRPupilColorRegion;
+  private Static3D bLPupilColorCenter, bRPupilColorCenter;
+  private Static3D bLPupilColorRegion, bRPupilColorRegion;
   private Static3D bChromaPupil;
   private Static1D bChromaPupilFactor;
   private Dynamic1D bChromaPupilDyn;
@@ -188,9 +193,12 @@ class AroundTheWorldEffectsManager
     aEyebrowsDyn.add(aEyebrowsFactor);
 
     // Fragment Effects
-    aSkinColorRegion   = new Static4D(300,300,600,600);
-    aLEyeColorRegion   = new Static4D(172,230,29,25);
-    aREyeColorRegion   = new Static4D(423,230,29,25);
+    aSkinColorCenter   = new Static3D(300,300,0);
+    aSkinColorRegion   = new Static3D(600,600,600);
+    aLEyeColorCenter   = new Static3D(172,230,0);
+    aLEyeColorRegion   = new Static3D(29,25,25);
+    aREyeColorCenter   = new Static3D(423,230,0);
+    aREyeColorRegion   = new Static3D(29,25,25);
 
     aChromaSkin        = new Static3D(0.5f, 0.5f, 0.5f);
     aChromaEyes        = new Static3D(0.5f, 0.14f, 0.14f);
@@ -235,11 +243,16 @@ class AroundTheWorldEffectsManager
     bLipsDyn.add(bLipsFactor);
 
     // Fragment Effects
-    bSkinColorRegion   = new Static4D(300,300,600,600);
-    bLEyeColorRegion = new Static4D(158,241,55,24);
-    bREyeColorRegion = new Static4D(436,241,55,24);
-    bLPupilColorRegion   = new Static4D(166,230,28,23);
-    bRPupilColorRegion   = new Static4D(431,230,28,23);
+    bSkinColorCenter     = new Static3D(300,300,0);
+    bSkinColorRegion     = new Static3D(600,600,600);
+    bLEyeColorCenter     = new Static3D(158,241,0);
+    bLEyeColorRegion     = new Static3D(55,24,50);
+    bREyeColorCenter     = new Static3D(436,241,0);
+    bREyeColorRegion     = new Static3D(55,24,50);
+    bLPupilColorCenter   = new Static3D(166,230,0);
+    bLPupilColorRegion   = new Static3D(28,23,25);
+    bRPupilColorCenter   = new Static3D(431,230,0);
+    bRPupilColorRegion   = new Static3D(28,23,25);
 
     bChromaSkin        = new Static3D(0.4f, 0.25f, 0.25f);
     bChromaEyes        = new Static3D(1.0f, 1.0f, 1.0f);
@@ -269,29 +282,29 @@ class AroundTheWorldEffectsManager
     effects.apply( new VertexEffectSink(wLipsDyn, wLipsCenter, wLipsRegion) );
 
     // ASIANNESS
-    effects.apply( new VertexEffectDistort(aLipsNoseDyn, aLipsNoseCenter, aLipsNoseRegion) );
-    effects.apply( new VertexEffectPinch(aNoseBroaderDyn, aNoseBroaderCenter, aNoseBroaderRegion) );
-    effects.apply( new VertexEffectDistort( aNostrilsDyn, aNostrilsCenter, aNostrilsRegion) );
-    effects.apply( new VertexEffectSwirl( aLEyeDyn, aLEyeCenter, aEyesRegion) );
-    effects.apply( new VertexEffectSwirl( aREyeDyn, aREyeCenter, aEyesRegion) );
-    effects.apply( new VertexEffectDistort( aEyebrowsDyn, aEyebrowsCenter, aEyebrowsRegion) );
+    effects.apply( new VertexEffectDistort(aLipsNoseDyn   , aLipsNoseCenter   , aLipsNoseRegion   ) );
+    effects.apply( new VertexEffectPinch  (aNoseBroaderDyn, aNoseBroaderCenter, aNoseBroaderRegion) );
+    effects.apply( new VertexEffectDistort( aNostrilsDyn  , aNostrilsCenter   , aNostrilsRegion   ) );
+    effects.apply( new VertexEffectSwirl  ( aLEyeDyn      , aLEyeCenter       , aEyesRegion       ) );
+    effects.apply( new VertexEffectSwirl  ( aREyeDyn      , aREyeCenter       , aEyesRegion       ) );
+    effects.apply( new VertexEffectDistort( aEyebrowsDyn  , aEyebrowsCenter   , aEyebrowsRegion   ) );
 
-    effects.apply( new FragmentEffectChroma( aChromaSkinDyn, aChromaSkin, aSkinColorRegion, false) );
-    effects.apply( new FragmentEffectChroma( aChromaEyesDyn, aChromaEyes, aLEyeColorRegion, true ) );
-    effects.apply( new FragmentEffectChroma( aChromaEyesDyn, aChromaEyes, aREyeColorRegion, true ) );
+    effects.apply( new FragmentEffectChroma( aChromaSkinDyn, aChromaSkin, aSkinColorCenter, aSkinColorRegion, false) );
+    effects.apply( new FragmentEffectChroma( aChromaEyesDyn, aChromaEyes, aLEyeColorCenter, aLEyeColorRegion, true ) );
+    effects.apply( new FragmentEffectChroma( aChromaEyesDyn, aChromaEyes, aREyeColorCenter, aREyeColorRegion, true ) );
 
     // BLACKNESS
-    effects.apply( new VertexEffectPinch( bFaceDyn, bFaceCenter, bFaceRegion ) );
-    effects.apply( new VertexEffectDistort( bTipLowerDyn, bTipLowerCenter, bTipLowerRegion ) );
-    effects.apply( new VertexEffectPinch( bWholeNoseDyn, bWholeNoseCenter, bWholeNoseRegion ) );
-    effects.apply( new VertexEffectPinch( bNoseBroaderDyn, bNoseBroaderCenter, bNoseBroaderRegion ) );
-    effects.apply( new VertexEffectPinch( bLipsDyn, bLipsCenter, bLipsRegion ) );
-
-    effects.apply( new FragmentEffectChroma( bChromaSkinDyn, bChromaSkin, bSkinColorRegion, false ) );
-    effects.apply( new FragmentEffectChroma( bChromaEyesDyn, bChromaEyes, bLEyeColorRegion, true  ) );
-    effects.apply( new FragmentEffectChroma( bChromaEyesDyn, bChromaEyes, bREyeColorRegion, true  ) );
-    effects.apply( new FragmentEffectChroma( bChromaPupilDyn, bChromaPupil, bLPupilColorRegion, true) );
-    effects.apply( new FragmentEffectChroma( bChromaPupilDyn, bChromaPupil, bRPupilColorRegion, true) );
+    effects.apply( new VertexEffectPinch  ( bFaceDyn       , bFaceCenter       , bFaceRegion        ) );
+    effects.apply( new VertexEffectDistort( bTipLowerDyn   , bTipLowerCenter   , bTipLowerRegion    ) );
+    effects.apply( new VertexEffectPinch  ( bWholeNoseDyn  , bWholeNoseCenter  , bWholeNoseRegion   ) );
+    effects.apply( new VertexEffectPinch  ( bNoseBroaderDyn, bNoseBroaderCenter, bNoseBroaderRegion ) );
+    effects.apply( new VertexEffectPinch  ( bLipsDyn       , bLipsCenter       , bLipsRegion        ) );
+
+    effects.apply( new FragmentEffectChroma( bChromaSkinDyn , bChromaSkin , bSkinColorCenter  , bSkinColorRegion  , false ) );
+    effects.apply( new FragmentEffectChroma( bChromaEyesDyn , bChromaEyes , bLEyeColorCenter  , bLEyeColorRegion  , true  ) );
+    effects.apply( new FragmentEffectChroma( bChromaEyesDyn , bChromaEyes , bREyeColorCenter  , bREyeColorRegion  , true  ) );
+    effects.apply( new FragmentEffectChroma( bChromaPupilDyn, bChromaPupil, bLPupilColorCenter, bLPupilColorRegion, true  ) );
+    effects.apply( new FragmentEffectChroma( bChromaPupilDyn, bChromaPupil, bRPupilColorCenter, bRPupilColorRegion, true  ) );
 
     effects.apply( new FragmentEffectContrast(bContrastDyn) );
     }
diff --git a/src/main/java/org/distorted/examples/catanddog/CatAndDogRenderer.java b/src/main/java/org/distorted/examples/catanddog/CatAndDogRenderer.java
index 7568101..37a238e 100644
--- a/src/main/java/org/distorted/examples/catanddog/CatAndDogRenderer.java
+++ b/src/main/java/org/distorted/examples/catanddog/CatAndDogRenderer.java
@@ -75,8 +75,10 @@ class CatAndDogRenderer implements GLSurfaceView.Renderer
       moveDyn.add(mMove);
       moveDyn.add(new Static3D(0,0,0));
 
-      Static4D chromaRegion= new Static4D( 530, 200,100,100);
-      Static4D alphaRegion = new Static4D( 230, 200,100,100);
+      Static3D chromaCenter= new Static3D( 530, 200, 0   );
+      Static3D chromaRegion= new Static3D( 100, 100, 100 );
+      Static3D alphaCenter = new Static3D( 230, 200, 0   );
+      Static3D alphaRegion = new Static3D( 100, 100, 100 );
 
       Dynamic1D chromaDyn = new Dynamic1D(3000,0.0f);
       chromaDyn.add(new Static1D(1));
@@ -92,8 +94,8 @@ class CatAndDogRenderer implements GLSurfaceView.Renderer
       diRotate.add(new Static1D(360));
 
       mEffects = new DistortedEffects();
-      mEffects.apply( new FragmentEffectChroma( chromaDyn, new Static3D(1,0,0), chromaRegion ,true) );
-      mEffects.apply( new FragmentEffectAlpha(alphaDyn, alphaRegion, false) );
+      mEffects.apply( new FragmentEffectChroma( chromaDyn, new Static3D(1,0,0), chromaCenter, chromaRegion ,true) );
+      mEffects.apply( new FragmentEffectAlpha(alphaDyn, alphaCenter, alphaRegion, false) );
       mEffects.apply( new MatrixEffectMove(moveDyn));
       mEffects.apply( new MatrixEffectScale(diScale));
       mEffects.apply( new MatrixEffectRotate( diRotate, new Static3D(0,0,1), mRotate) );
diff --git a/src/main/java/org/distorted/examples/deform/DeformRenderer.java b/src/main/java/org/distorted/examples/deform/DeformRenderer.java
index 33cdb4b..65e5843 100644
--- a/src/main/java/org/distorted/examples/deform/DeformRenderer.java
+++ b/src/main/java/org/distorted/examples/deform/DeformRenderer.java
@@ -157,7 +157,7 @@ class DeformRenderer implements GLSurfaceView.Renderer
 
    void setRegionRadius(int r)
       {
-      mRadius = ( r==100 ? 100.0f : r/100.0f);
+      mRadius = ( r==100 ? 100.0f : r/200.0f);
       mRegion.set4(mRadius*scrWidth);
       }
 
diff --git a/src/main/java/org/distorted/examples/earth/EarthActivity.java b/src/main/java/org/distorted/examples/earth/EarthActivity.java
index 0adb40e..a69cc52 100644
--- a/src/main/java/org/distorted/examples/earth/EarthActivity.java
+++ b/src/main/java/org/distorted/examples/earth/EarthActivity.java
@@ -168,12 +168,12 @@ public class EarthActivity extends Activity implements SeekBar.OnSeekBarChangeLi
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    void addNewPoint(float x, float y, EffectName effect)
+    void addNewPoint(float longitude, float latitude, EffectName effect)
       {
       EarthSurfaceView view = this.findViewById(R.id.earthSurfaceView);
       EarthRenderer renderer = view.getRenderer();
 
-      renderer.addNewPoint(x,y,effect);
+      renderer.addNewPoint(longitude,latitude,effect);
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/examples/earth/EarthRenderer.java b/src/main/java/org/distorted/examples/earth/EarthRenderer.java
index 6cc5073..066d511 100644
--- a/src/main/java/org/distorted/examples/earth/EarthRenderer.java
+++ b/src/main/java/org/distorted/examples/earth/EarthRenderer.java
@@ -24,11 +24,23 @@ import android.graphics.BitmapFactory;
 import android.opengl.GLSurfaceView;
 
 import org.distorted.examples.R;
+import org.distorted.library.effect.Effect;
 import org.distorted.library.effect.EffectName;
 import org.distorted.library.effect.EffectType;
+import org.distorted.library.effect.FragmentEffectAlpha;
+import org.distorted.library.effect.FragmentEffectBrightness;
+import org.distorted.library.effect.FragmentEffectChroma;
+import org.distorted.library.effect.FragmentEffectContrast;
+import org.distorted.library.effect.FragmentEffectSaturation;
 import org.distorted.library.effect.MatrixEffectMove;
 import org.distorted.library.effect.MatrixEffectQuaternion;
 import org.distorted.library.effect.MatrixEffectScale;
+import org.distorted.library.effect.VertexEffectDeform;
+import org.distorted.library.effect.VertexEffectDistort;
+import org.distorted.library.effect.VertexEffectPinch;
+import org.distorted.library.effect.VertexEffectSink;
+import org.distorted.library.effect.VertexEffectSwirl;
+import org.distorted.library.effect.VertexEffectWave;
 import org.distorted.library.main.Distorted;
 import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedScreen;
@@ -36,6 +48,7 @@ import org.distorted.library.main.DistortedTexture;
 import org.distorted.library.mesh.MeshBase;
 import org.distorted.library.mesh.MeshSphere;
 import org.distorted.library.type.DynamicQuat;
+import org.distorted.library.type.Static1D;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 
@@ -49,7 +62,7 @@ import javax.microedition.khronos.opengles.GL10;
 
 class EarthRenderer implements GLSurfaceView.Renderer
 {
-    private static final int   SIZE =   100;
+    private static final int   SIZE =   500;
     private static final int   LEVEL=    32;
     private static final float FOV  = 30.0f;
     private static final float NEAR =  0.1f;
@@ -65,12 +78,17 @@ class EarthRenderer implements GLSurfaceView.Renderer
     Static4D mQuat1, mQuat2;
     int mScreenMin;
 
+    private Static3D mColor;
+    private Static1D mStrength;
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
     EarthRenderer(GLSurfaceView v)
       {
       mView = v;
 
+      mStrength = new Static1D(0.5f);
+      mColor= new Static3D(255,0,0);
       mMove = new Static3D(0,0,0);
       mScale= new Static3D(1,1,1);
       mCenter=new Static3D(0,0,0);
@@ -132,9 +150,50 @@ class EarthRenderer implements GLSurfaceView.Renderer
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    void addNewPoint(float x, float y, EffectName effect)
+    void addNewPoint(float longitude, float latitude, EffectName name)
       {
+      Effect effect =null;
+
+      double sinLON = Math.sin(longitude);
+      double cosLON = Math.cos(longitude);
+      double sinLAT = Math.sin(latitude);
+      double cosLAT = Math.cos(latitude);
+
+      float x = 0.7071f*(float)(sinLON*cosLAT);
+      float y = 0.7071f*(float)(cosLON*cosLAT);
+      float z = 0.7071f*(float)        sinLAT ;
 
+      float radius = SIZE/10;
+      Static4D region = new Static4D(x*mObjWidth,y*mObjHeight,radius,radius);
+
+      switch(name)
+        {
+        /*
+        case DISTORT          : effect = new VertexEffectDistort(mDyn3, center, mRegionV); break;
+        case DEFORM           : effect = new VertexEffectDeform (mDyn3, center, mRegionV); break;
+        case SINK             : effect = new VertexEffectSink   (mDyn1, center, mRegionV); break;
+        case PINCH            : effect = new VertexEffectPinch  (mDyn2, center, mRegionV); break;
+        case SWIRL            : effect = new VertexEffectSwirl  (mDyn1, center, mRegionV); break;
+        case WAVE             : effect = new VertexEffectWave   (mDyn5, center, mRegionV); break;
+
+        case ALPHA            : effect = new FragmentEffectAlpha     (mStrength,        region, false); break;
+        case SMOOTH_ALPHA     : effect = new FragmentEffectAlpha     (mStrength,        region, true ); break;
+        case CHROMA           : effect = new FragmentEffectChroma    (mStrength, mColor,region, false); break;
+        case SMOOTH_CHROMA    : effect = new FragmentEffectChroma    (mStrength, mColor,region, true ); break;
+        case BRIGHTNESS       : effect = new FragmentEffectBrightness(mStrength,        region, false); break;
+        case SMOOTH_BRIGHTNESS: effect = new FragmentEffectBrightness(mStrength,        region, true ); break;
+        case SATURATION       : effect = new FragmentEffectSaturation(mStrength,        region, false); break;
+        case SMOOTH_SATURATION: effect = new FragmentEffectSaturation(mStrength,        region, true ); break;
+        case CONTRAST         : effect = new FragmentEffectContrast  (mStrength,        region, false); break;
+        case SMOOTH_CONTRAST  : effect = new FragmentEffectContrast  (mStrength,        region, true ); break;
+        */
+        }
+
+      if( effect!=null )
+        {
+        android.util.Log.e("renderer", "adding fragment effect");
+        mEffects.apply(effect);
+        }
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/examples/earth/EarthSurfaceViewPicker.java b/src/main/java/org/distorted/examples/earth/EarthSurfaceViewPicker.java
index a58167e..b430abc 100644
--- a/src/main/java/org/distorted/examples/earth/EarthSurfaceViewPicker.java
+++ b/src/main/java/org/distorted/examples/earth/EarthSurfaceViewPicker.java
@@ -195,7 +195,10 @@ class EarthSurfaceViewPicker extends SurfaceView implements SurfaceHolder.Callba
       mPointsY.add( (int)(MULTIPLIER*yf) );
       mPointsE.add(mCurrentEffect.ordinal());
 
-      mAct.get().addNewPoint(xf,yf,mCurrentEffect);
+      float longitude = (float)((xf-0.5f)*2.0f*Math.PI);
+      float latitude  = (float)((yf-0.5f)*Math.PI);
+
+      mAct.get().addNewPoint(longitude,latitude,mCurrentEffect);
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/examples/effectqueue/EffectQueueRenderer.java b/src/main/java/org/distorted/examples/effectqueue/EffectQueueRenderer.java
index f90b813..7704579 100644
--- a/src/main/java/org/distorted/examples/effectqueue/EffectQueueRenderer.java
+++ b/src/main/java/org/distorted/examples/effectqueue/EffectQueueRenderer.java
@@ -48,8 +48,9 @@ import org.distorted.library.type.Static3D;
 class EffectQueueRenderer implements GLSurfaceView.Renderer, EffectListener
   {  
   private static final int NUMLINES =  10;
-  final int BWID = 300;
-  final int BHEI = 400;
+  private static final int MESH_QUALITY = 100;
+  static final int BWID = 600;
+  static final int BHEI = 600;
    
   private EffectQueueSurfaceView mView;
   private Paint mPaint;
@@ -77,7 +78,7 @@ class EffectQueueRenderer implements GLSurfaceView.Renderer, EffectListener
     mScale = new Static3D(1,1,1);
     MatrixEffectScale scaleEffect = new MatrixEffectScale(mScale);
 
-    mMesh = new MeshFlat(80,80*texHeight/texWidth);
+    mMesh = new MeshFlat(MESH_QUALITY,MESH_QUALITY*texHeight/texWidth);
     mTexture = new DistortedTexture(texWidth,texHeight);
     mEffects = new DistortedEffects();
     mEffects.apply(scaleEffect);
diff --git a/src/main/java/org/distorted/examples/effectqueue/EffectQueueSurfaceView.java b/src/main/java/org/distorted/examples/effectqueue/EffectQueueSurfaceView.java
index 2db443c..234e889 100644
--- a/src/main/java/org/distorted/examples/effectqueue/EffectQueueSurfaceView.java
+++ b/src/main/java/org/distorted/examples/effectqueue/EffectQueueSurfaceView.java
@@ -41,7 +41,7 @@ import org.distorted.library.type.Dynamic3D;
 
 public class EffectQueueSurfaceView extends GLSurfaceView
   {
-  private static final int RADIUS = 60;
+  private static final int RADIUS = EffectQueueRenderer.BWID/6;
 
   private EffectQueueRenderer mRenderer;
   private int mCurrentEffect;
@@ -51,7 +51,8 @@ public class EffectQueueSurfaceView extends GLSurfaceView
   private Dynamic1D mInterA, mInterB, mInterC, mInterS;
   private Dynamic3D mInterD;
 
-  private final static Static3D mRED = new Static3D(1,0,0);
+  private final static Static3D mRED    = new Static3D(1,0,0);
+  private final static Static3D mREGION = new Static3D(RADIUS,RADIUS,RADIUS);
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
     
@@ -146,15 +147,15 @@ public class EffectQueueSurfaceView extends GLSurfaceView
                                               success = mRenderer.getEffects().apply(sink);
                                               act.effectAdded(success,sink);
                                               break;
-                                      case 2: FragmentEffectAlpha alpha = new FragmentEffectAlpha(mInterA, new Static4D(x,y,RADIUS,RADIUS), true);
+                                      case 2: FragmentEffectAlpha alpha = new FragmentEffectAlpha(mInterA, new Static3D(x,y,0), mREGION, true);
                                               success = mRenderer.getEffects().apply(alpha);
                                               act.effectAdded(success,alpha);
                                               break;
-                                      case 3: FragmentEffectSaturation saturation = new FragmentEffectSaturation(mInterB, new Static4D(x,y,RADIUS,RADIUS), false);
+                                      case 3: FragmentEffectSaturation saturation = new FragmentEffectSaturation(mInterB, new Static3D(x,y,0), mREGION, false);
                                               success = mRenderer.getEffects().apply(saturation);
                                               act.effectAdded(success,saturation);
                                               break;
-                                      case 4: FragmentEffectChroma chroma = new FragmentEffectChroma(mInterC, mRED, new Static4D(x,y,RADIUS,RADIUS), true);
+                                      case 4: FragmentEffectChroma chroma = new FragmentEffectChroma(mInterC, mRED, new Static3D(x,y,0), mREGION, true);
                                               success = mRenderer.getEffects().apply(chroma);
                                               act.effectAdded(success,chroma);
                                               break;
diff --git a/src/main/java/org/distorted/examples/effects3d/Effects3DEffect.java b/src/main/java/org/distorted/examples/effects3d/Effects3DEffect.java
index 99c083c..a64c38d 100644
--- a/src/main/java/org/distorted/examples/effects3d/Effects3DEffect.java
+++ b/src/main/java/org/distorted/examples/effects3d/Effects3DEffect.java
@@ -76,7 +76,7 @@ class Effects3DEffect implements SeekBar.OnSeekBarChangeListener
   private int[] mSeekID;
   private int[] mSeekRegionID;
   private int[] mSeekCenterID;
-  private int mDimension;
+  private int mDimension, mRegionDimension;
   private TextView mText,mTextRegion,mTextCenter;
 
   private Dynamic1D mDyn1;
@@ -89,8 +89,10 @@ class Effects3DEffect implements SeekBar.OnSeekBarChangeListener
   private Static3D  mSta3;
   private Static4D  mSta4;
   private Static5D  mSta5;
-  private Dynamic4D mRegionDyn;
-  private Static4D  mRegionSta;
+  private Dynamic4D mRegion4Dyn;
+  private Static4D  mRegion4Sta;
+  private Dynamic3D mRegion3Dyn;
+  private Static3D  mRegion3Sta;
   private Dynamic3D mCenterDyn;
   private Static3D  mCenterSta;
 
@@ -147,23 +149,23 @@ class Effects3DEffect implements SeekBar.OnSeekBarChangeListener
       case SCALE            : effect = new MatrixEffectScale       (mDyn3)            ; break;
       case SHEAR            : effect = new MatrixEffectShear       (mDyn3, mCenterDyn); break;
 
-      case DISTORT          : effect = new VertexEffectDistort     (mDyn3, mCenterDyn, mRegionDyn); break;
-      case DEFORM           : effect = new VertexEffectDeform      (mDyn3, mCenterDyn, mRegionDyn); break;
-      case SINK             : effect = new VertexEffectSink        (mDyn1, mCenterDyn, mRegionDyn); break;
-      case PINCH            : effect = new VertexEffectPinch       (mDyn2, mCenterDyn, mRegionDyn); break;
-      case SWIRL            : effect = new VertexEffectSwirl       (mDyn1, mCenterDyn, mRegionDyn); break;
-      case WAVE             : effect = new VertexEffectWave        (mDyn5, mCenterDyn, mRegionDyn); break;
-
-      case ALPHA            : effect = new FragmentEffectAlpha     (mDyn1,        mRegionDyn, false); break;
-      case SMOOTH_ALPHA     : effect = new FragmentEffectAlpha     (mDyn1,        mRegionDyn, true ); break;
-      case CHROMA           : effect = new FragmentEffectChroma    (mDyn1, mDyn3, mRegionDyn, false); break;
-      case SMOOTH_CHROMA    : effect = new FragmentEffectChroma    (mDyn1, mDyn3, mRegionDyn, true ); break;
-      case BRIGHTNESS       : effect = new FragmentEffectBrightness(mDyn1,        mRegionDyn, false); break;
-      case SMOOTH_BRIGHTNESS: effect = new FragmentEffectBrightness(mDyn1,        mRegionDyn, true ); break;
-      case SATURATION       : effect = new FragmentEffectSaturation(mDyn1,        mRegionDyn, false); break;
-      case SMOOTH_SATURATION: effect = new FragmentEffectSaturation(mDyn1,        mRegionDyn, true ); break;
-      case CONTRAST         : effect = new FragmentEffectContrast  (mDyn1,        mRegionDyn, false); break;
-      case SMOOTH_CONTRAST  : effect = new FragmentEffectContrast  (mDyn1,        mRegionDyn, true ); break;
+      case DISTORT          : effect = new VertexEffectDistort     (mDyn3, mCenterDyn, mRegion4Dyn); break;
+      case DEFORM           : effect = new VertexEffectDeform      (mDyn3, mCenterDyn, mRegion4Dyn); break;
+      case SINK             : effect = new VertexEffectSink        (mDyn1, mCenterDyn, mRegion4Dyn); break;
+      case PINCH            : effect = new VertexEffectPinch       (mDyn2, mCenterDyn, mRegion4Dyn); break;
+      case SWIRL            : effect = new VertexEffectSwirl       (mDyn1, mCenterDyn, mRegion4Dyn); break;
+      case WAVE             : effect = new VertexEffectWave        (mDyn5, mCenterDyn, mRegion4Dyn); break;
+
+      case ALPHA            : effect = new FragmentEffectAlpha     (mDyn1,        mCenterDyn, mRegion3Dyn, false); break;
+      case SMOOTH_ALPHA     : effect = new FragmentEffectAlpha     (mDyn1,        mCenterDyn, mRegion3Dyn, true ); break;
+      case CHROMA           : effect = new FragmentEffectChroma    (mDyn1, mDyn3, mCenterDyn, mRegion3Dyn, false); break;
+      case SMOOTH_CHROMA    : effect = new FragmentEffectChroma    (mDyn1, mDyn3, mCenterDyn, mRegion3Dyn, true ); break;
+      case BRIGHTNESS       : effect = new FragmentEffectBrightness(mDyn1,        mCenterDyn, mRegion3Dyn, false); break;
+      case SMOOTH_BRIGHTNESS: effect = new FragmentEffectBrightness(mDyn1,        mCenterDyn, mRegion3Dyn, true ); break;
+      case SATURATION       : effect = new FragmentEffectSaturation(mDyn1,        mCenterDyn, mRegion3Dyn, false); break;
+      case SMOOTH_SATURATION: effect = new FragmentEffectSaturation(mDyn1,        mCenterDyn, mRegion3Dyn, true ); break;
+      case CONTRAST         : effect = new FragmentEffectContrast  (mDyn1,        mCenterDyn, mRegion3Dyn, false); break;
+      case SMOOTH_CONTRAST  : effect = new FragmentEffectContrast  (mDyn1,        mCenterDyn, mRegion3Dyn, true ); break;
 
       case BLUR             : effect = new PostprocessEffectBlur   (mDyn1       ); break;
       case GLOW             : effect = new PostprocessEffectGlow   (mDyn1, mDyn4); break;
@@ -401,7 +403,8 @@ class Effects3DEffect implements SeekBar.OnSeekBarChangeListener
     float z = (mInterRegion[2]-deduct)*factorX;   // ??
     float r =  mInterRegion[3]        *(factorX+factorY)/2;
 
-    mRegionSta.set(x,y,z,r);
+    mRegion4Sta.set(x,y,z,r);
+    mRegion3Sta.set(x,y,z);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -418,12 +421,24 @@ class Effects3DEffect implements SeekBar.OnSeekBarChangeListener
 
   private void setRegionText()
     {
-    int f0 = (int)mRegionSta.get1();
-    int f1 = (int)mRegionSta.get2();
-    int f2 = (int)mRegionSta.get3();
-    int f3 = (int)mRegionSta.get4();
+    if( mRegionDimension==4 )
+      {
+      int f0 = (int) mRegion4Sta.get1();
+      int f1 = (int) mRegion4Sta.get2();
+      int f2 = (int) mRegion4Sta.get3();
+      int f3 = (int) mRegion4Sta.get4();
+
+      mTextRegion.setText("region (" + f0 + "," + f1 + "," + f2 + "," + f3 + ")");
+      }
 
-    mTextRegion.setText("region ("+f0+","+f1+","+f2+","+f3+")");
+    if( mRegionDimension==3 )
+      {
+      int f0 = (int) mRegion3Sta.get1();
+      int f1 = (int) mRegion3Sta.get2();
+      int f2 = (int) mRegion3Sta.get3();
+
+      mTextRegion.setText("region (" + f0 + "," + f1 + "," + f2 + ")");
+      }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -455,7 +470,8 @@ class Effects3DEffect implements SeekBar.OnSeekBarChangeListener
     mSta4 = null;
     mSta5 = null;
 
-    mDimension = mName.getDimension();
+    mDimension = mName.getEffectDimension();
+    mRegionDimension = mName.getRegionDimension();
 
     switch(mDimension)
       {
@@ -511,9 +527,12 @@ class Effects3DEffect implements SeekBar.OnSeekBarChangeListener
 
     mInterRegion = new int[4];
     mSeekRegionID= new int[4];
-    mRegionDyn   = new Dynamic4D();
-    mRegionSta   = new Static4D(0,0,0,0);
-    mRegionDyn.add(mRegionSta);
+    mRegion4Dyn  = new Dynamic4D();
+    mRegion4Sta  = new Static4D(0,0,0,0);
+    mRegion4Dyn.add(mRegion4Sta);
+    mRegion3Dyn  = new Dynamic3D();
+    mRegion3Sta  = new Static3D(0,0,0);
+    mRegion3Dyn.add(mRegion3Sta);
 
     mInterCenter = new int[3];
     mSeekCenterID= new int[3];
@@ -610,32 +629,62 @@ class Effects3DEffect implements SeekBar.OnSeekBarChangeListener
     {
     Effects3DActivity2 act = mAct.get();
 
-    mRegion = act.getLayoutInflater().inflate(R.layout.effectregion, null);
-    mRegion.setBackgroundColor( num%2==1 ? BACKGROUND_EVEN: BACKGROUND_ODD );
+    if( mRegionDimension== 4 )
+      {
+      mRegion = act.getLayoutInflater().inflate(R.layout.effectregion4, null);
+      mRegion.setBackgroundColor(num % 2 == 1 ? BACKGROUND_EVEN : BACKGROUND_ODD);
 
-    SeekBar[] seek = new SeekBar[4];
+      SeekBar[] seek = new SeekBar[4];
 
-    seek[0] = mRegion.findViewById(R.id.effectRegionBarX );
-    seek[1] = mRegion.findViewById(R.id.effectRegionBarY );
-    seek[2] = mRegion.findViewById(R.id.effectRegionBarRX);
-    seek[3] = mRegion.findViewById(R.id.effectRegionBarRY);
+      seek[0] = mRegion.findViewById(R.id.effectRegion4BarX);
+      seek[1] = mRegion.findViewById(R.id.effectRegion4BarY);
+      seek[2] = mRegion.findViewById(R.id.effectRegion4BarZ);
+      seek[3] = mRegion.findViewById(R.id.effectRegion4BarR);
 
-    mSeekRegionID[0] = seek[0].getId();
-    mSeekRegionID[1] = seek[1].getId();
-    mSeekRegionID[2] = seek[2].getId();
-    mSeekRegionID[3] = seek[3].getId();
+      mSeekRegionID[0] = seek[0].getId();
+      mSeekRegionID[1] = seek[1].getId();
+      mSeekRegionID[2] = seek[2].getId();
+      mSeekRegionID[3] = seek[3].getId();
 
-    mTextRegion = mRegion.findViewById(R.id.effectRegionText);
+      mTextRegion = mRegion.findViewById(R.id.effectRegion4Text);
 
-    setDefaultRegionInter();
+      setDefaultRegionInter();
 
-    for(int i=0; i<4; i++)
-      {
-      seek[i].setOnSeekBarChangeListener(this);
-      seek[i].setProgress( mInterRegion[i] );
+      for (int i = 0; i < 4; i++)
+        {
+        seek[i].setOnSeekBarChangeListener(this);
+        seek[i].setProgress(mInterRegion[i]);
+        }
+
+      act.setRegion(mRegion4Sta.get1(), mRegion4Sta.get2(), mRegion4Sta.get3(), mRegion4Sta.get4());
       }
+    else
+      {
+      mRegion = act.getLayoutInflater().inflate(R.layout.effectregion3, null);
+      mRegion.setBackgroundColor(num % 2 == 1 ? BACKGROUND_EVEN : BACKGROUND_ODD);
+
+      SeekBar[] seek = new SeekBar[3];
+
+      seek[0] = mRegion.findViewById(R.id.effectRegion3BarRX);
+      seek[1] = mRegion.findViewById(R.id.effectRegion3BarRY);
+      seek[2] = mRegion.findViewById(R.id.effectRegion3BarRZ);
+
+      mSeekRegionID[0] = seek[0].getId();
+      mSeekRegionID[1] = seek[1].getId();
+      mSeekRegionID[2] = seek[2].getId();
+
+      mTextRegion = mRegion.findViewById(R.id.effectRegion3Text);
 
-    act.setRegion(mRegionSta.get1(),mRegionSta.get2(),mRegionSta.get3(), mRegionSta.get4() );
+      setDefaultRegionInter();
+
+      for (int i = 0; i < 3; i++)
+        {
+        seek[i].setOnSeekBarChangeListener(this);
+        seek[i].setProgress(mInterRegion[i]);
+        }
+
+      act.setRegion(mRegion3Sta.get1(), mRegion3Sta.get2(), mRegion3Sta.get3(), 1.0f );
+      }
 
     return mRegion;
     }
@@ -709,25 +758,25 @@ class Effects3DEffect implements SeekBar.OnSeekBarChangeListener
       setText();
       }
 
-    if( bar.getId() == mSeekRegionID[0] )
+    if( mRegionDimension>=1 && bar.getId() == mSeekRegionID[0] )
       {
       mInterRegion[0] = progress;
       fillRegionStatics();
       setRegionText();
       }
-    if( bar.getId() == mSeekRegionID[1] )
+    if( mRegionDimension>=2 && bar.getId() == mSeekRegionID[1] )
       {
       mInterRegion[1] = progress;
       fillRegionStatics();
       setRegionText();
       }
-    if( bar.getId() == mSeekRegionID[2] )
+    if( mRegionDimension>=3 && bar.getId() == mSeekRegionID[2] )
       {
       mInterRegion[2] = progress;
       fillRegionStatics();
       setRegionText();
       }
-    if( bar.getId() == mSeekRegionID[3] )
+    if( mRegionDimension>=4 && bar.getId() == mSeekRegionID[3] )
       {
       mInterRegion[3] = progress;
       fillRegionStatics();
@@ -765,7 +814,7 @@ class Effects3DEffect implements SeekBar.OnSeekBarChangeListener
       view.getRenderer().showRegionAndCenter( showR,showC );
 
       act.setCenter(mCenterSta.get1(),mCenterSta.get2(),mCenterSta.get3());
-      act.setRegion(mRegionSta.get1(),mRegionSta.get2(),mRegionSta.get3(), mRegionSta.get4());
+      act.setRegion(mRegion4Sta.get1(),mRegion4Sta.get2(),mRegion4Sta.get3(), mRegion4Sta.get4());
       }
     }
 
diff --git a/src/main/java/org/distorted/examples/effects3d/Effects3DTab.java b/src/main/java/org/distorted/examples/effects3d/Effects3DTab.java
index 85deba4..67eba71 100644
--- a/src/main/java/org/distorted/examples/effects3d/Effects3DTab.java
+++ b/src/main/java/org/distorted/examples/effects3d/Effects3DTab.java
@@ -169,13 +169,13 @@ public class Effects3DTab extends Fragment implements AdapterView.OnItemSelected
     View view = eff.createView(mChildren);
     layout.addView(view);
 
-    if( mEffectNames[mEffectAdd].supportsCenter() )
+    if( mEffectNames[mEffectAdd].getCenterDimension() > 0 )
       {
       View center = eff.createCenter(mChildren);
       layout.addView(center);
       }
 
-    if( mEffectNames[mEffectAdd].supportsRegion() )
+    if( mEffectNames[mEffectAdd].getRegionDimension() > 0 )
       {
       View region = eff.createRegion(mChildren);
       layout.addView(region);
diff --git a/src/main/java/org/distorted/examples/movingeffects/MovingEffectsSurfaceView.java b/src/main/java/org/distorted/examples/movingeffects/MovingEffectsSurfaceView.java
index bb0af7e..879ab19 100644
--- a/src/main/java/org/distorted/examples/movingeffects/MovingEffectsSurfaceView.java
+++ b/src/main/java/org/distorted/examples/movingeffects/MovingEffectsSurfaceView.java
@@ -37,7 +37,6 @@ import org.distorted.library.effect.VertexEffectSink;
 import org.distorted.library.effect.VertexEffectSwirl;
 import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.type.Dynamic3D;
-import org.distorted.library.type.Dynamic4D;
 import org.distorted.library.type.Static1D;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
@@ -58,16 +57,16 @@ public class MovingEffectsSurfaceView extends GLSurfaceView
 
     private static final Object lock = new Object();
 
-    private Dynamic3D mCenterVertex;
+    private Dynamic3D mCenter;
     private Static4D mRegionVertex;
-    private Dynamic4D mRegionFragment;
+    private Static3D mRegionFragment;
 
     private Paint mPaint;
     private int moving;
     private long mTime = 0;
     
     private int mCurrEffect;
-    private int mSize1, mSize2, mSizeR;
+    private int mSize1, mSize2;
     private Static3D mDistort;
 
     private MovingEffectsRenderer mRenderer;
@@ -89,8 +88,8 @@ public class MovingEffectsSurfaceView extends GLSurfaceView
       mPaint.setStyle(Style.FILL);
       moving = -1;
       
-      mCenterVertex   = new Dynamic3D(LOOP_TIME,0.0f);
-      mRegionFragment = new Dynamic4D(LOOP_TIME,0.0f);
+      mCenter         = new Dynamic3D(LOOP_TIME,0.0f);
+      mRegionFragment = new Static3D(0,0,0);
       mRegionVertex   = new Static4D(0,0,0,0);
       mDistort        = new Static3D(0,0,0);
 
@@ -105,11 +104,11 @@ public class MovingEffectsSurfaceView extends GLSurfaceView
         setEGLContextClientVersion( (configurationInfo.reqGlEsVersion>>16) >= 3 ? 3:2 );
         setRenderer(mRenderer);
 
-        mEffectDistort = new VertexEffectDistort( mDistort , mCenterVertex, mRegionVertex);
-        mEffectSink    = new VertexEffectSink(new Static1D(10), mCenterVertex, mRegionVertex);
-        mEffectSwirl   = new VertexEffectSwirl( new Static1D(30), mCenterVertex, mRegionVertex);
-        mEffectAlpha   = new FragmentEffectAlpha(new Static1D(0.5f), mRegionFragment, true);
-        mEffectChroma  = new FragmentEffectChroma(new Static1D(0.5f), new Static3D(1,0,0), mRegionFragment, true);
+        mEffectDistort = new VertexEffectDistort ( mDistort         , mCenter, mRegionVertex);
+        mEffectSink    = new VertexEffectSink    (new Static1D(10)  , mCenter, mRegionVertex);
+        mEffectSwirl   = new VertexEffectSwirl   (new Static1D(30)  , mCenter, mRegionVertex);
+        mEffectAlpha   = new FragmentEffectAlpha (new Static1D(0.5f), mCenter, mRegionFragment, true);
+        mEffectChroma  = new FragmentEffectChroma(new Static1D(0.5f), new Static3D(1,0,0), mCenter, mRegionFragment, true);
         }
       }
 
@@ -121,9 +120,10 @@ public class MovingEffectsSurfaceView extends GLSurfaceView
 
       mSize1 = max/200;
       mSize2 = max/80;
-      mSizeR = max/6;
+      int rad= max/6;
 
-      mRegionVertex.set(0,0,0,mSizeR);
+      mRegionVertex.set(0,0,0,rad);
+      mRegionFragment.set(rad,rad,rad);
       mDistort.set3(max/10);
       }
 
@@ -223,8 +223,7 @@ public class MovingEffectsSurfaceView extends GLSurfaceView
         DistortedEffects q = mRenderer.getEffects();
         q.abortByType(EffectType.VERTEX);
         q.abortByType(EffectType.FRAGMENT);
-        mCenterVertex.removeAll();
-        mRegionFragment.removeAll();
+        mCenter.removeAll();
         mCurrEffect = EFFECT_POINTS;
         mRenderer.setRefresh();
         }
@@ -236,7 +235,7 @@ public class MovingEffectsSurfaceView extends GLSurfaceView
       {
       synchronized(lock)
         {  
-        int len = mCenterVertex.getNumPoints();
+        int len = mCenter.getNumPoints();
 
         float[] drawCoord = new float[3];
         Static3D cu;
@@ -248,7 +247,7 @@ public class MovingEffectsSurfaceView extends GLSurfaceView
           for(int i=0; i<NUM_POINTS; i++)
             {
             mPaint.setColor( 0xffffffff );
-            mCenterVertex.get( drawCoord, 0, (long)(i*step) );
+            mCenter.get( drawCoord, 0, (long)(i*step) );
             c.drawCircle(drawCoord[0], drawCoord[1], mSize1, mPaint );
             }
           }
@@ -257,7 +256,7 @@ public class MovingEffectsSurfaceView extends GLSurfaceView
       
         for(int curr=0; curr<len; curr++)
           {       
-          cu = mCenterVertex.getPoint(curr);
+          cu = mCenter.getPoint(curr);
           c.drawCircle(cu.get1(), cu.get2(), mSize2, mPaint);
           }
         
@@ -280,11 +279,11 @@ public class MovingEffectsSurfaceView extends GLSurfaceView
                                     
                                       float gx, gy;
                                       Static3D dv;
-                                      int len = mCenterVertex.getNumPoints();
+                                      int len = mCenter.getNumPoints();
                                  
                                       for(int g=0; g<len; g++)
                                         {
-                                        dv = mCenterVertex.getPoint(g);
+                                        dv = mCenter.getPoint(g);
                                         gx = dv.get1();
                                         gy = dv.get2();
 
@@ -300,8 +299,7 @@ public class MovingEffectsSurfaceView extends GLSurfaceView
                                         {
                                         synchronized(lock)
                                           {
-                                          mCenterVertex.add(new Static3D(xDown,yDown,0));
-                                          mRegionFragment.add(new Static4D(xDown,yDown,mSizeR,mSizeR));
+                                          mCenter.add(new Static3D(xDown,yDown,0));
                                           }
                                         }
                                       mRenderer.setRefresh();
@@ -311,8 +309,7 @@ public class MovingEffectsSurfaceView extends GLSurfaceView
                                         xDown = (int)event.getX();
                                         yDown = (int)event.getY();
 
-                                        mCenterVertex.setPoint(moving, xDown, yDown, 0);
-                                        mRegionFragment.setPoint(moving, xDown, yDown, mSizeR, mSizeR);
+                                        mCenter.setPoint(moving, xDown, yDown, 0);
                                         }
                                       mRenderer.setRefresh();
                                       break;
diff --git a/src/main/java/org/distorted/examples/objecttree/ObjectTreeRenderer.java b/src/main/java/org/distorted/examples/objecttree/ObjectTreeRenderer.java
index c0fcc21..ac45b8f 100644
--- a/src/main/java/org/distorted/examples/objecttree/ObjectTreeRenderer.java
+++ b/src/main/java/org/distorted/examples/objecttree/ObjectTreeRenderer.java
@@ -180,7 +180,7 @@ class ObjectTreeRenderer implements GLSurfaceView.Renderer
       mGridTexture.setTexture(bitmap2);
       DistortedEffects gridEffects = new DistortedEffects();
 
-      final int GRID = 10;
+      final int GRID = 20;
 
       if( mMeshFlat==null ) mMeshFlat = new MeshFlat(1,1);
       if( mMeshCubes==null) mMeshCubes= new MeshCubes(GRID,GRID,1);
diff --git a/src/main/java/org/distorted/examples/starwars/StarWarsRenderer.java b/src/main/java/org/distorted/examples/starwars/StarWarsRenderer.java
index ce0efce..89014c2 100644
--- a/src/main/java/org/distorted/examples/starwars/StarWarsRenderer.java
+++ b/src/main/java/org/distorted/examples/starwars/StarWarsRenderer.java
@@ -418,8 +418,9 @@ class StarWarsRenderer implements GLSurfaceView.Renderer, EffectListener
         mCrawlBackgroundEffects.apply( new MatrixEffectRotate(new Static1D(CRAWL_ANGLE), new Static3D(1,0,0), new Static3D(screenW/2,backH,0)) );
 
         final int transpDist = 5;
-        Static4D region = new Static4D(screenW/2,(1-transpDist)*backH,transpDist*backH,transpDist*backH);
-        mCrawlBackgroundEffects.apply( new FragmentEffectAlpha(new Static1D(1-transpDist*0.6f), region, true) );
+        Static3D center = new Static3D( screenW/2 , (1-transpDist)*backH , 0 );
+        Static3D region = new Static3D( transpDist*backH , transpDist*backH , transpDist*backH );
+        mCrawlBackgroundEffects.apply( new FragmentEffectAlpha(new Static1D(1-transpDist*0.6f), center, region, true) );
 
         Dynamic3D di = new Dynamic3D(70000,0.5f);
         di.add(new Static3D(screenW/2,+backH       , 0));
diff --git a/src/main/res/layout/effectregion.xml b/src/main/res/layout/effectregion.xml
deleted file mode 100644
index 72963d7..0000000
--- a/src/main/res/layout/effectregion.xml
+++ /dev/null
@@ -1,66 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:id="@+id/effectRegionLayout"
-              android:layout_width="match_parent"
-              android:layout_height="wrap_content"
-              android:orientation="vertical">
-
-    <TextView
-        android:id="@+id/effectRegionText"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginEnd="5dp"
-        android:layout_marginStart="5dp"
-        android:layout_marginTop="3dp"
-        />
-
-    <LinearLayout
-        android:orientation="horizontal"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent">
-
-        <SeekBar
-            android:id="@+id/effectRegionBarX"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginEnd="5dp"
-            android:layout_marginLeft="5dp"
-            android:layout_marginRight="5dp"
-            android:layout_weight="0.5"/>
-
-        <SeekBar
-            android:id="@+id/effectRegionBarY"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginEnd="5dp"
-            android:layout_marginLeft="5dp"
-            android:layout_marginRight="5dp"
-            android:layout_weight="0.5"/>
-
-    </LinearLayout>
-
-    <LinearLayout
-        android:orientation="horizontal"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent">
-
-        <SeekBar
-            android:id="@+id/effectRegionBarRX"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginEnd="5dp"
-            android:layout_marginLeft="5dp"
-            android:layout_marginRight="5dp"
-            android:layout_weight="0.5"/>
-
-        <SeekBar
-            android:id="@+id/effectRegionBarRY"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginEnd="5dp"
-            android:layout_marginLeft="5dp"
-            android:layout_marginRight="5dp"
-            android:layout_weight="0.5"/>
-
-    </LinearLayout>
-</LinearLayout>
diff --git a/src/main/res/layout/effectregion3.xml b/src/main/res/layout/effectregion3.xml
new file mode 100644
index 0000000..43b3ff5
--- /dev/null
+++ b/src/main/res/layout/effectregion3.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:id="@+id/effectRegion3Layout"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content"
+              android:orientation="vertical">
+
+    <TextView
+        android:id="@+id/effectRegion3Text"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="5dp"
+        android:layout_marginStart="5dp"
+        android:layout_marginTop="3dp"
+        />
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <SeekBar
+            android:id="@+id/effectRegion3BarRX"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginEnd="5dp"
+            android:layout_marginLeft="5dp"
+            android:layout_marginRight="5dp"
+            android:layout_weight="1.0"/>
+
+        <SeekBar
+            android:id="@+id/effectRegion3BarRY"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginEnd="5dp"
+            android:layout_marginLeft="5dp"
+            android:layout_marginRight="5dp"
+            android:layout_weight="1.0"/>
+
+        <SeekBar
+            android:id="@+id/effectRegion3BarRZ"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginEnd="5dp"
+            android:layout_marginLeft="5dp"
+            android:layout_marginRight="5dp"
+            android:layout_weight="1.0"/>
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/src/main/res/layout/effectregion4.xml b/src/main/res/layout/effectregion4.xml
new file mode 100644
index 0000000..b829678
--- /dev/null
+++ b/src/main/res/layout/effectregion4.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:id="@+id/effectRegionLayout"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content"
+              android:orientation="vertical">
+
+    <TextView
+        android:id="@+id/effectRegion4Text"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="5dp"
+        android:layout_marginStart="5dp"
+        android:layout_marginTop="3dp"
+        />
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <SeekBar
+            android:id="@+id/effectRegion4BarX"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginEnd="5dp"
+            android:layout_marginLeft="5dp"
+            android:layout_marginRight="5dp"
+            android:layout_weight="0.5"/>
+
+        <SeekBar
+            android:id="@+id/effectRegion4BarY"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginEnd="5dp"
+            android:layout_marginLeft="5dp"
+            android:layout_marginRight="5dp"
+            android:layout_weight="0.5"/>
+
+    </LinearLayout>
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <SeekBar
+            android:id="@+id/effectRegion4BarZ"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginEnd="5dp"
+            android:layout_marginLeft="5dp"
+            android:layout_marginRight="5dp"
+            android:layout_weight="0.5"/>
+
+        <SeekBar
+            android:id="@+id/effectRegion4BarR"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginEnd="5dp"
+            android:layout_marginLeft="5dp"
+            android:layout_marginRight="5dp"
+            android:layout_weight="0.5"/>
+
+    </LinearLayout>
+</LinearLayout>
