diff --git a/package.json b/package.json
index 5a5b5d0..7a33dc8 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "webglobe",
-  "version": "0.3.1",
+  "version": "0.3.2",
   "description": "A WebGL virtual globe and map engine.",
   "main": "require.js",
   "scripts": {
diff --git a/src/world/Camera.ts b/src/world/Camera.ts
index e1d94f9..e96fb62 100644
--- a/src/world/Camera.ts
+++ b/src/world/Camera.ts
@@ -17,14 +17,20 @@ class Camera extends Object3D {
   private readonly baseTheoryDistanceFromCamera2EarthSurface = 1.23 * Kernel.EARTH_RADIUS;
   private readonly maxPitch = 40;
 
-  private level: number = -1; //当前渲染等级
-
-  private animationLevel: number = -1;//非整数,表示缩放动画过程中的level
-
   //旋转的时候,绕着视线与地球交点进行旋转
   //定义抬头时,旋转角为正值
   private isZeroPitch: boolean = true;//表示当前Camera视线有没有发生倾斜
 
+  private level: number = -1; //当前渲染等级
+  private realLevel: number = -2;//可能是正数,可能是非整数,非整数表示缩放动画过程中的level
+
+  private lastRealLevel: number = -3;//上次render()时所用到的this.realLevel
+  private lastMatrix: Matrix;//上次render()时的this.matrix
+  private lastFov: number = -1;
+  private lastAspect: number = -1;
+  private lastNear: number = -1;
+  private lastFar: number = -1;
+
   private viewMatrix: Matrix;//视点矩阵,即Camera模型矩阵的逆矩阵
   private projMatrix: Matrix;//当Matrix变化的时候,需要重新计算this.far
   private projViewMatrix: Matrix;//获取投影矩阵与视点矩阵的乘积
@@ -36,11 +42,6 @@ class Camera extends Object3D {
 
   private animating: boolean = false;
 
-  Enum: any = {
-    EARTH_FULL_OVERSPREAD_SCREEN: "EARTH_FULL_OVERSPREAD_SCREEN", //Canvas内全部被地球充满
-    EARTH_NOT_FULL_OVERSPREAD_SCREEN: "EARTH_NOT_FULL_OVERSPREAD_SCREEN" //Canvas没有全部被地球充满
-  };
-
   //this.near一旦初始化之后就不应该再修改
   //this.far可以动态计算
   //this.aspect在Viewport改变后重新计算
@@ -48,6 +49,8 @@ class Camera extends Object3D {
   constructor(private fov = 45, private aspect = 1, private near = 1, private far = 100) {
     super();
     this.initFov = this.fov;
+    this.lastMatrix = new Matrix();
+    this.lastMatrix.setUniqueValue(0);
     this.projMatrix = new Matrix();
     this._rawSetPerspectiveMatrix(this.fov, this.aspect, this.near, this.far);
     this._initCameraPosition();
@@ -121,11 +124,27 @@ class Camera extends Object3D {
     return far;
   }
 
-  //更新各种矩阵,保守起见,可以在每帧绘制之前调用
-  //理论上只在用户交互的时候调用就可以
-  update(): void {
-    this._normalUpdate();
-    this._updateProjViewMatrixForDraw();
+  //更新各种矩阵,理论上只在用户交互的时候调用就可以
+  update(force: boolean = false): void {
+    if(force || this._isNeedUpdate()){
+      this._normalUpdate();
+      this._updateProjViewMatrixForDraw();
+    }
+    this.lastFov = this.fov;
+    this.lastAspect = this.aspect;
+    this.lastNear = this.near;
+    this.lastFar = this.far;
+    this.lastRealLevel = this.realLevel;
+    this.lastMatrix.setMatrixByOther(this.matrix);
+  }
+
+  private _isNeedUpdate(): boolean{
+    return (this.fov !== this.lastFov) ||
+           (this.aspect !== this.lastAspect) ||
+           (this.near !== this.lastNear) ||
+           (this.far !== this.lastFar) ||
+           (this.realLevel !== this.lastRealLevel) ||
+           (!this.matrix.equals(this.lastMatrix));
   }
 
   getProjViewMatrixForDraw(): Matrix {
@@ -168,9 +187,8 @@ class Camera extends Object3D {
 
   //返回更新后的fov值,如果返回结果 < 0,说明无需更新fov
   private _updatePositionAndFov(cameraMatrix: Matrix): number {
-    //是否满足near值,和fov没有关系,和position有关
-    //但是改变position的话,fov也要相应变动以满足对应的缩放效果
-    const currentLevel = this.animating ? this.animationLevel : this.level;
+    //是否满足near值,和fov没有关系,和position有关,但是改变position的话,fov也要相应变动以满足对应的缩放效果
+    const currentLevel = this.animating ? this.realLevel : this.level;
 
     //safeLevel不是整数
     var safeLevel = this._getSafeThresholdLevelForNear();
@@ -260,8 +278,9 @@ class Camera extends Object3D {
       return;
     }
     var isLevelChanged = this._updatePositionByLevel(level, this.matrix);
-    //不要在this._setLevel()方法中更新this.level,因为这会影响animateToLevel()方法
+    //不要在this._updatePositionByLevel()方法中更新this.level,因为这会影响animateToLevel()方法
     this.level = level;
+    this.realLevel = level;
     Kernel.globe.refresh();
   }
 
@@ -431,7 +450,7 @@ class Camera extends Object3D {
     var deltaZ = (newPosition.z - oldPosition.z) / count;
     var deltaLevel = (newLevel - this.level) / count;
     var start: number = -1;
-    this.animationLevel = this.level;
+    this.realLevel = this.level;
     this.animating = true;
 
     var callback = (timestap: number) => {
@@ -441,10 +460,10 @@ class Camera extends Object3D {
       var a = timestap - start;
       if (a >= span) {
         this.animating = false;
-        this.animationLevel = -1;
+        this.realLevel = newLevel;
         this.setLevel(newLevel);
       } else {
-        this.animationLevel += deltaLevel;
+        this.realLevel += deltaLevel;
         var p = this.getPosition();
         this.setPosition(p.x + deltaX, p.y + deltaY, p.z + deltaZ);
         requestAnimationFrame(callback);
diff --git a/src/world/math/Matrix.ts b/src/world/math/Matrix.ts
index 63d8274..948e69e 100644
--- a/src/world/math/Matrix.ts
+++ b/src/world/math/Matrix.ts
@@ -14,6 +14,15 @@ class Matrix{
       this.setElements(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44);
     }
 
+    equals(matrix: Matrix): boolean{
+      if(this === matrix){
+        return true;
+      }
+      return this.elements.every((ele: number, index: number) => {
+        return ele === matrix.elements[index];
+      });
+    }
+
     setElements(m11: number, m12: number, m13: number, m14: number,
                 m21: number, m22: number, m23: number, m24: number,
                 m31: number, m32: number, m33: number, m34: number,
@@ -185,9 +194,6 @@ class Matrix{
     }
 
     setMatrixByOther(otherMatrix: Matrix): void {
-      if (!(otherMatrix instanceof Matrix)) {
-        throw "invalid otherMatrix";
-      }
       for (var i = 0; i < otherMatrix.elements.length; i++) {
         this.elements[i] = otherMatrix.elements[i];
       }
@@ -201,7 +207,14 @@ class Matrix{
           1, 0, 0, 0,
           0, 1, 0, 0,
           0, 0, 1, 0,
-          0, 0, 0, 1);
+          0, 0, 0, 1
+      );
+    }
+
+    setUniqueValue(value: number){
+      this.elements.forEach((ele, index) => {
+        this.elements[index] = value;
+      });
     }
 
     /**
@@ -231,7 +244,8 @@ class Matrix{
           this.elements[0], this.elements[4], this.elements[8], this.elements[12],
           this.elements[1], this.elements[5], this.elements[9], this.elements[13],
           this.elements[2], this.elements[6], this.elements[10], this.elements[14],
-          this.elements[3], this.elements[7], this.elements[11], this.elements[15]);
+          this.elements[3], this.elements[7], this.elements[11], this.elements[15]
+      );
     }
 
     multiplyMatrix(otherMatrix: Matrix): Matrix {
diff --git a/versions.txt b/versions.txt
index da58fb2..ab43142 100644
--- a/versions.txt
+++ b/versions.txt
@@ -101,4 +101,6 @@
       但是实际传递给shader用于绘图的是projViewMatrixForDraw。Camera.getPickCartesianCoordInEarthByCanvas()方法也是基于projViewMatrixForDraw系列矩阵的。
       该版本提高了深度值的精度,基本解决了z值精度问题。在update()方法中会计算projViewMatrixForDraw系列矩阵。
 
-0.3.1 使得Globe.animateToLevel()可以在0.3.0的版本上运行,解决办法是引入了camera.animationLevel,其值是非整数。      
\ No newline at end of file
+0.3.1 使得Globe.animateToLevel()可以在0.3.0的版本上运行,解决办法是引入了camera.animationLevel,其值是非整数。
+
+0.3.2 优化了Camera.update()方法,只有发生用户交互的情况下才实际进行计算。
\ No newline at end of file