diff --git a/graf3d/eve/inc/LinkDef.h b/graf3d/eve/inc/LinkDef.h
index 3ae26cc05ce4281888d5b3bae4116338a5579cc3..0b43da36848b2b3323211a7b5c406ae727c84a1f 100644
--- a/graf3d/eve/inc/LinkDef.h
+++ b/graf3d/eve/inc/LinkDef.h
@@ -191,6 +191,11 @@
 #pragma link C++ class TEveProjectable+;
 #pragma link C++ class TEveProjected+;
 #pragma link C++ class TEveProjection+;
+#pragma link C++ class TEveProjection::PreScaleEntry_t+;
+#pragma link C++ class std::vector<TEveProjection::PreScaleEntry_t>;
+#pragma link C++ class std::vector<TEveProjection::PreScaleEntry_t>::iterator;
+#pragma link C++ typedef TEveProjection::vPreScale_t;
+#pragma link C++ typedef TEveProjection::vPreScale_i;
 #pragma link C++ class TEveRhoZProjection+;
 #pragma link C++ class TEveRPhiProjection+;
 
diff --git a/graf3d/eve/inc/TEveProjectionManager.h b/graf3d/eve/inc/TEveProjectionManager.h
index 4826abb190c016fb89e1f9cf8398ff1000764b30..1c2a454c0eee67b456ea1bb62ab74a0ba59ac658 100644
--- a/graf3d/eve/inc/TEveProjectionManager.h
+++ b/graf3d/eve/inc/TEveProjectionManager.h
@@ -26,7 +26,9 @@ private:
    TEveProjectionManager& operator=(const TEveProjectionManager&); // Not implemented
 
 protected:
-   TEveProjection* fProjection;     // projection
+   TEveProjection* fProjections[TEveProjection::kPT_End];
+
+   TEveProjection* fProjection;     // current projection
    TEveVector      fCenter;         // center of distortion
    Float_t         fCurrentDepth;   // z depth of object being projected
 
@@ -44,7 +46,7 @@ public:
    void AddDependent(TEveElement* el);
    void RemoveDependent(TEveElement* el);
 
-   void            SetProjection(TEveProjection::EPType_e type, Float_t distort=0);
+   void            SetProjection(TEveProjection::EPType_e type);
    TEveProjection* GetProjection() { return fProjection; }
 
    virtual void    UpdateName();
diff --git a/graf3d/eve/inc/TEveProjections.h b/graf3d/eve/inc/TEveProjections.h
index f835559acd9c015a336a959cb6e3d80e7de1ecfa..c3da8e4425563e86289bdbab26cb86760f69b4dc 100644
--- a/graf3d/eve/inc/TEveProjections.h
+++ b/graf3d/eve/inc/TEveProjections.h
@@ -14,6 +14,8 @@
 
 #include "TEveVSDStructs.h"
 
+#include <vector>
+
 ////////////////////////////////////////////////////////////////
 //                                                            //
 // TEveProjection                                             //
@@ -23,10 +25,29 @@
 class TEveProjection
 {
 public:
-   enum EPType_e   { kPT_Unknown, kPT_RPhi, kPT_RhoZ };         // type
+   enum EPType_e   { kPT_Unknown, kPT_RPhi, kPT_RhoZ, kPT_End };// type
    enum EPProc_e   { kPP_Plane, kPP_Distort, kPP_Full };        // procedure
    enum EGeoMode_e { kGM_Unknown, kGM_Polygons, kGM_Segments }; // reconstruction of geometry
 
+   struct PreScaleEntry_t
+   {
+      Float_t fMin, fMax;
+      Float_t fOffset;
+      Float_t fScale;
+
+      PreScaleEntry_t() :
+         fMin(0), fMax(0), fOffset(0), fScale(1) {}
+      PreScaleEntry_t(Float_t min, Float_t max, Float_t off, Float_t scale) :
+         fMin(min), fMax(max), fOffset(off), fScale(scale) {}
+
+      virtual ~PreScaleEntry_t() {}
+
+      ClassDef(PreScaleEntry_t, 0);
+   };
+
+   typedef std::vector<PreScaleEntry_t>           vPreScale_t;
+   typedef std::vector<PreScaleEntry_t>::iterator vPreScale_i;
+
 protected:
    EPType_e            fType;          // type
    EGeoMode_e          fGeoMode;       // strategy of polygon projection (what to try first)
@@ -35,6 +56,9 @@ protected:
    TEveVector          fCenter;        // center of distortion
    TEveVector          fZeroPosVal;    // projected origin (0, 0, 0)
 
+   Bool_t              fUsePreScale;   // use pre-scaling
+   vPreScale_t         fPreScales[2];  // scaling before the distortion
+
    Float_t             fDistortion;    // distortion
    Float_t             fFixR;          // radius from which scaling remains constant
    Float_t             fFixZ;          // z-coordinate from which scaling remains constant
@@ -49,7 +73,7 @@ protected:
    TEveVector          fUpLimit;       // convergence of point -infinity
 
 public:
-   TEveProjection(TEveVector& center);
+   TEveProjection();
    virtual ~TEveProjection() {}
 
    virtual   void      ProjectPoint(Float_t&, Float_t&, Float_t&, EPProc_e p = kPP_Full ) = 0;
@@ -70,6 +94,13 @@ public:
 
    virtual void        UpdateLimit();
 
+   Bool_t   GetUsePreScale() const   { return fUsePreScale; }
+   void     SetUsePreScale(Bool_t x) { fUsePreScale = x; }
+
+   void     PreScalePoint(Float_t& x, Float_t& y);
+   void     AddPreScaleEntry(Int_t coord, Float_t max_val, Float_t scale);
+   void     ClearPreScales();
+
    void     SetDistortion(Float_t d);
    Float_t  GetDistortion() const { return fDistortion; }
    Float_t  GetFixR() const { return fFixR; }
@@ -107,7 +138,7 @@ private:
    TEveVector   fProjectedCenter; // projected center of distortion.
 
 public:
-   TEveRhoZProjection(TEveVector& center);
+   TEveRhoZProjection();
    virtual ~TEveRhoZProjection() {}
 
    virtual   void      ProjectPoint(Float_t& x, Float_t& y, Float_t& z, EPProc_e proc = kPP_Full);
@@ -133,7 +164,7 @@ public:
 class TEveRPhiProjection : public TEveProjection
 {
 public:
-   TEveRPhiProjection(TEveVector& center);
+   TEveRPhiProjection();
    virtual ~TEveRPhiProjection() {}
 
    virtual void ProjectPoint(Float_t& x, Float_t& y, Float_t& z, EPProc_e proc = kPP_Full);
diff --git a/graf3d/eve/src/TEveProjectionManager.cxx b/graf3d/eve/src/TEveProjectionManager.cxx
index 5e9e93c733443c9e10a28f038fd362ba9dcbc819..d37773709395dda05e0f9175e9ee1fb6d65ce734 100644
--- a/graf3d/eve/src/TEveProjectionManager.cxx
+++ b/graf3d/eve/src/TEveProjectionManager.cxx
@@ -50,8 +50,9 @@ TEveProjectionManager::TEveProjectionManager():
 {
    // Constructor.
 
-   fProjection = new TEveRPhiProjection(fCenter);
-   UpdateName();
+   for (Int_t i = 0; i < TEveProjection::kPT_End; ++i)
+      fProjections[i] = 0;
+   SetProjection(TEveProjection::kPT_RPhi);
 }
 
 //______________________________________________________________________________
@@ -60,7 +61,10 @@ TEveProjectionManager::~TEveProjectionManager()
    // Destructor.
    // Destroys also dependent elements.
 
-   if (fProjection) delete fProjection;
+   for (Int_t i = 0; i < TEveProjection::kPT_End; ++i)
+   {
+      delete fProjections[i];
+   }
    while ( ! fDependentEls.empty())
    {
       fDependentEls.front()->Destroy();
@@ -92,32 +96,33 @@ void TEveProjectionManager::UpdateName()
 }
 
 //______________________________________________________________________________
-void TEveProjectionManager::SetProjection(TEveProjection::EPType_e type, Float_t distort)
+void TEveProjectionManager::SetProjection(TEveProjection::EPType_e type)
 {
    // Set projection type and distortion.
 
    static const TEveException eH("TEveProjectionManager::SetProjection ");
 
-   delete fProjection;
-   fProjection = 0;
-
-   switch (type)
+   if (fProjections[type] == 0)
    {
-      case TEveProjection::kPT_RPhi:
+      switch (type)
       {
-         fProjection  = new TEveRPhiProjection(fCenter);
-         break;
+         case TEveProjection::kPT_RPhi:
+         {
+            fProjections[type] = new TEveRPhiProjection();
+            break;
+         }
+         case TEveProjection::kPT_RhoZ:
+         {
+            fProjections[type] = new TEveRhoZProjection();
+            break;
+         }
+         default:
+            throw(eH + "projection type not valid.");
+            break;
       }
-      case TEveProjection::kPT_RhoZ:
-      {
-         fProjection  = new TEveRhoZProjection(fCenter);
-         break;
-      }
-      default:
-         throw(eH + "projection type not valid.");
-         break;
    }
-   fProjection->SetDistortion(distort);
+   fProjection = fProjections[type];
+   fProjection->SetCenter(fCenter);
    UpdateName();
 }
 
diff --git a/graf3d/eve/src/TEveProjectionManagerEditor.cxx b/graf3d/eve/src/TEveProjectionManagerEditor.cxx
index 92ea7c4b48a2c7cb10f04e0ffd431b35b7a05f96..588974e294579ff65a303e818de36192350a4757 100644
--- a/graf3d/eve/src/TEveProjectionManagerEditor.cxx
+++ b/graf3d/eve/src/TEveProjectionManagerEditor.cxx
@@ -17,13 +17,16 @@
 #include "TGComboBox.h"
 #include "TGLabel.h"
 
-//______________________________________________________________________________
+//==============================================================================
 // TEveProjectionManagerEditor
+//==============================================================================
+
+//______________________________________________________________________________
 //
 // GUI editor for TEveProjectionManager class.
 //
 
-ClassImp(TEveProjectionManagerEditor)
+ClassImp(TEveProjectionManagerEditor);
 
 //______________________________________________________________________________
 TEveProjectionManagerEditor::TEveProjectionManagerEditor(const TGWindow *p,
@@ -185,7 +188,7 @@ void TEveProjectionManagerEditor::DoType(Int_t type)
 {
    // Slot for setting of projection type.
 
-   fM->SetProjection((TEveProjection::EPType_e)type, 0.001f * fDistortion->GetValue());
+   fM->SetProjection((TEveProjection::EPType_e)type);
    fM->ProjectChildren();
    Update();
 }
diff --git a/graf3d/eve/src/TEveProjections.cxx b/graf3d/eve/src/TEveProjections.cxx
index c574c33074478259b66b142fc0eebe82e35a344e..253793a091cec8f70a0df414d79a8bcd224efb8a 100644
--- a/graf3d/eve/src/TEveProjections.cxx
+++ b/graf3d/eve/src/TEveProjections.cxx
@@ -29,11 +29,12 @@ ClassImp(TEveProjection);
 Float_t TEveProjection::fgEps = 0.005f;
 
 //______________________________________________________________________________
-TEveProjection::TEveProjection(TEveVector& center) :
+TEveProjection::TEveProjection() :
    fType          (kPT_Unknown),
    fGeoMode       (kGM_Unknown),
    fName          (0),
-   fCenter        (center.fX, center.fY, center.fZ),
+   fCenter        (),
+   fUsePreScale   (kFALSE),
    fDistortion    (0.0f),
    fFixR          (300), fFixZ          (400),
    fPastFixRFac   (0),   fPastFixZFac   (0),
@@ -58,6 +59,98 @@ void TEveProjection::ProjectVector(TEveVector& v)
    ProjectPoint(v.fX, v.fY, v.fZ);
 }
 
+//______________________________________________________________________________
+void TEveProjection::PreScalePoint(Float_t& v0, Float_t& v1)
+{
+   // Pre-scale point (v0, v1) in projected coordinates:
+   //   RhoZ ~ (rho, z)
+   //   RPhi ~ (r, phi), scaling phi doesn't make much sense.
+
+   if (!fPreScales[0].empty())
+   {
+      Bool_t invp = kFALSE;
+      if (v0 < 0) {
+         v0    = -v0;
+         invp = kTRUE;
+      }
+      vPreScale_i i = fPreScales[0].begin();
+      while (v0 > i->fMax)
+         ++i;
+      v0 = i->fOffset + (v0 - i->fMin)*i->fScale;
+      if (invp)
+         v0 = -v0;
+   }
+   if (!fPreScales[1].empty())
+   {
+      Bool_t invp = kFALSE;
+      if (v1 < 0) {
+         v1    = -v1;
+         invp = kTRUE;
+      }
+      vPreScale_i i = fPreScales[1].begin();
+      while (v1 > i->fMax)
+         ++i;
+      v1 = i->fOffset + (v1 - i->fMin)*i->fScale;
+      if (invp)
+         v1 = -v1;
+   }
+}
+
+//______________________________________________________________________________
+void TEveProjection::AddPreScaleEntry(Int_t coord, Float_t value, Float_t scale)
+{
+   // Add new scaling range for given coordinate.
+   // Arguments:
+   //  coord    0 ~ x, 1 ~ y;
+   //  value    value of input coordinate from which to apply this scale;
+   //  scale    the scale to apply from value onwards.
+   //
+   // NOTE: If pre-scaling is combined with center-displaced then
+   // the scale of the central region should be 1. This limitation
+   // can be removed but will cost CPU.
+
+   static const TEveException eh("TEveProjection::AddPreScaleEntry ");
+
+   if (coord < 0 || coord > 1)
+      throw (eh + "coordinate out of range.");
+
+   const Float_t infty  = std::numeric_limits<Float_t>::infinity();
+
+   vPreScale_t& vec = fPreScales[coord];
+
+   if (vec.empty())
+   {
+      if (value == 0)
+      {
+         vec.push_back(PreScaleEntry_t(0, infty, 0, scale));
+      }
+      else
+      {
+         vec.push_back(PreScaleEntry_t(0, value, 0, 1));
+         vec.push_back(PreScaleEntry_t(value, infty, value, scale));
+      }
+   }
+   else
+   {
+      PreScaleEntry_t& prev = vec.back();
+      if (value <= prev.fMin)
+         throw (eh + "minimum value not larger than previous one.");
+
+      prev.fMax = value;
+      Float_t offset =  prev.fOffset + (prev.fMax - prev.fMin)*prev.fScale;
+      vec.push_back(PreScaleEntry_t(value, infty, offset, scale));
+   }
+}
+
+//______________________________________________________________________________
+void TEveProjection::ClearPreScales()
+{
+   // Clear all pre-scaling information.
+
+   fPreScales[0].clear();
+   fPreScales[1].clear();
+}
+
 //______________________________________________________________________________
 void TEveProjection::UpdateLimit()
 {
@@ -219,8 +312,8 @@ Float_t TEveProjection::GetScreenVal(Int_t i, Float_t x)
 ClassImp(TEveRhoZProjection);
 
 //______________________________________________________________________________
-TEveRhoZProjection::TEveRhoZProjection(TEveVector& center) :
-   TEveProjection(center)
+TEveRhoZProjection::TEveRhoZProjection() :
+   TEveProjection()
 {
    // Constructor.
 
@@ -230,7 +323,7 @@ TEveRhoZProjection::TEveRhoZProjection(TEveVector& center) :
 
 //______________________________________________________________________________
 void TEveRhoZProjection::ProjectPoint(Float_t& x, Float_t& y, Float_t& z,
-                                      EPProc_e proc )
+                                      EPProc_e proc)
 {
    // Project point.
 
@@ -244,6 +337,9 @@ void TEveRhoZProjection::ProjectPoint(Float_t& x, Float_t& y, Float_t& z,
    }
    if (proc == kPP_Distort || proc == kPP_Full)
    {
+      if (fUsePreScale)
+         PreScalePoint(y, x);
+
       // move to center
       x -= fProjectedCenter.fX;
       y -= fProjectedCenter.fY;
@@ -352,8 +448,8 @@ Bool_t TEveRhoZProjection::AcceptSegment(TEveVector& v1, TEveVector& v2,
 ClassImp(TEveRPhiProjection);
 
 //______________________________________________________________________________
-TEveRPhiProjection::TEveRPhiProjection(TEveVector& center) :
-   TEveProjection(center)
+TEveRPhiProjection::TEveRPhiProjection() :
+   TEveProjection()
 {
    // Constructor.
 
@@ -372,10 +468,20 @@ void TEveRPhiProjection::ProjectPoint(Float_t& x, Float_t& y, Float_t& z,
 
    if (proc != kPP_Plane)
    {
-      x -= fCenter.fX;
-      y -= fCenter.fY;
-      Float_t phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
-      Float_t r   = Sqrt(x*x + y*y);
+      Float_t r, phi;
+      if (fUsePreScale)
+      {
+         r   = Sqrt(x*x + y*y);
+         phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
+         PreScalePoint(r, phi);
+         x = r*Cos(phi);
+         y = r*Sin(phi);
+      }
+
+      x  -= fCenter.fX;
+      y  -= fCenter.fY;
+      r   = Sqrt(x*x + y*y);
+      phi = (x == 0.0f && y == 0.0f) ? 0.0f : ATan2(y, x);
 
       if (r > fFixR)
          r =  fFixR + fPastFixRScale*(r - fFixR);
diff --git a/tutorials/eve/projection_test_prescale.C b/tutorials/eve/projection_test_prescale.C
new file mode 100644
index 0000000000000000000000000000000000000000..0ce2868a244d1976a2c3972db4d1780cdcc7fa49
--- /dev/null
+++ b/tutorials/eve/projection_test_prescale.C
@@ -0,0 +1,77 @@
+const char* esd_geom_file_name = "http://root.cern.ch/files/alice_ESDgeometry.root";
+
+void projection_test_prescale()
+{
+   TFile::SetCacheFileDir(".");
+   TEveManager::Create();
+
+   // camera
+   TEveScene* s = gEve->SpawnNewScene("Projected Event");
+   gEve->GetDefViewer()->AddScene(s);
+   TGLViewer* v = (TGLViewer *)gEve->GetGLViewer();
+   v->SetCurrentCamera(TGLViewer::kCameraOrthoXOY);
+   TGLOrthoCamera* cam = (TGLOrthoCamera*) v->CurrentCamera();
+   cam->SetZoomMinMax(0.2, 20);
+
+   TGLCameraMarkupStyle* mup = v->GetCameraMarkup();
+   if (mup) mup->SetShow(kFALSE);
+
+   // projections
+   TEveProjectionManager* mng = new TEveProjectionManager();
+   {
+      mng->SetProjection(TEveProjection::kPT_RPhi);
+      TEveProjection* p = mng->GetProjection();
+      p->AddPreScaleEntry(0, 0,   4);     // r scale 2 from 0
+      p->AddPreScaleEntry(0, 45,  1);    // r scale 1 from 45
+      p->AddPreScaleEntry(0, 310, 0.5);
+      p->SetUsePreScale(1);
+   }
+   {
+      mng->SetProjection(TEveProjection::kPT_RhoZ);
+      TEveProjection* p = mng->GetProjection();
+      // Increase silicon tracker
+      p->AddPreScaleEntry(0, 0, 4);     // rho scale 4 from 0
+      p->AddPreScaleEntry(1, 0, 4);     // z   scale 4 from 0
+      // Normal for TPC
+      p->AddPreScaleEntry(0, 45,  1);   // rho scale 1 from 45
+      p->AddPreScaleEntry(1, 110, 1);   // z   scale 1 from 110
+      // Reduce the rest
+      p->AddPreScaleEntry(0, 310, 0.5);
+      p->AddPreScaleEntry(1, 250, 0.5);
+      p->SetUsePreScale(1);
+   }
+   mng->SetProjection(TEveProjection::kPT_RPhi);
+   s->AddElement(mng);
+
+
+   TEveProjectionAxes* axes = new TEveProjectionAxes(mng);
+   axes->SetText("TEveProjections demo");
+   axes->SetFontFile("comicbd");
+   axes->SetFontSize(20);
+   s->AddElement(axes);
+   gEve->AddToListTree(axes, kTRUE);
+   gEve->AddToListTree(mng, kTRUE);
+
+   // Simple geometry
+   TFile* geom = TFile::Open(esd_geom_file_name, "CACHEREAD");
+   if (!geom)
+      return;
+
+   TEveGeoShapeExtract* gse = (TEveGeoShapeExtract*) geom->Get("Gentle");
+   TEveGeoShape* gsre = TEveGeoShape::ImportShapeExtract(gse, 0);
+   geom->Close();
+   delete geom;
+   gEve->AddGlobalElement(gsre);
+   gEve->GetGlobalScene()->SetRnrState(kFALSE);
+   mng->ImportElements(gsre);
+
+   TEveLine* line = new TEveLine;
+   line->SetMainColor(kGreen);
+   for (Int_t i=0; i<160; ++i)
+      line->SetNextPoint(120*sin(0.2*i), 120*cos(0.2*i), 80-i);
+   gEve->AddElement(line);
+   mng->ImportElements(line);
+   line->SetRnrSelf(kFALSE);
+
+   gEve->Redraw3D(kTRUE);
+}