浏览代码

Merge pull request #9601 from Michalzr/feature/skyMaterialUpVector

Feature/sky material up vector
sebavan 4 年之前
父节点
当前提交
91a07d1e20
共有 3 个文件被更改,包括 44 次插入3 次删除
  1. 1 1
      materialsLibrary/src/sky/sky.fragment.fx
  2. 14 2
      materialsLibrary/src/sky/skyMaterial.ts
  3. 29 0
      src/Maths/math.vector.ts

+ 1 - 1
materialsLibrary/src/sky/sky.fragment.fx

@@ -12,6 +12,7 @@ varying vec4 vColor;
 // Sky
 uniform vec3 cameraPosition;
 uniform vec3 cameraOffset;
+uniform vec3 up;
 uniform float luminance;
 uniform float turbidity;
 uniform float rayleigh;
@@ -36,7 +37,6 @@ const float v = 4.0;
 
 const float rayleighZenithLength = 8.4E3;
 const float mieZenithLength = 1.25E3;
-const vec3 up = vec3(0.0, 1.0, 0.0);
 
 const float EE = 1000.0;
 const float sunAngularDiameterCos = 0.999956676946448443553574619906976478926848692873900859324;

+ 14 - 2
materialsLibrary/src/sky/skyMaterial.ts

@@ -1,6 +1,6 @@
 import { Nullable } from "babylonjs/types";
 import { serializeAsVector3, serialize, SerializationHelper } from "babylonjs/Misc/decorators";
-import { Vector3, Matrix } from "babylonjs/Maths/math.vector";
+import { Vector3, Matrix, Quaternion } from "babylonjs/Maths/math.vector";
 import { IAnimatable } from 'babylonjs/Animations/animatable.interface';
 import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture";
 import { MaterialDefines } from "babylonjs/Materials/materialDefines";
@@ -113,8 +113,15 @@ export class SkyMaterial extends PushMaterial {
     @serialize()
     public cameraOffset: Vector3 = Vector3.Zero();
 
+    /**
+     * Defines the vector the skyMaterial should consider as up. (default is Vector3(0, 1, 0) as returned by Vector3.Up())
+     */
+    @serializeAsVector3()
+    public up: Vector3 = Vector3.Up();
+
     // Private members
     private _cameraPosition: Vector3 = Vector3.Zero();
+    private _skyOrientation: Quaternion = new Quaternion();
 
     /**
      * Instantiates a new sky material.
@@ -212,7 +219,7 @@ export class SkyMaterial extends PushMaterial {
                 ["world", "viewProjection", "view",
                     "vFogInfos", "vFogColor", "pointSize", "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "vClipPlane5", "vClipPlane6",
                     "luminance", "turbidity", "rayleigh", "mieCoefficient", "mieDirectionalG", "sunPosition",
-                    "cameraPosition", "cameraOffset"
+                    "cameraPosition", "cameraOffset", "up"
                 ],
                 [],
                 join, fallbacks, this.onCompiled, this.onError), defines);
@@ -282,6 +289,8 @@ export class SkyMaterial extends PushMaterial {
 
         this._activeEffect.setVector3("cameraOffset", this.cameraOffset);
 
+        this._activeEffect.setVector3("up", this.up);
+
         if (this.luminance > 0) {
             this._activeEffect.setFloat("luminance", this.luminance);
         }
@@ -298,6 +307,9 @@ export class SkyMaterial extends PushMaterial {
             this.sunPosition.x = this.distance * Math.cos(phi);
             this.sunPosition.y = this.distance * Math.sin(phi) * Math.sin(theta);
             this.sunPosition.z = this.distance * Math.sin(phi) * Math.cos(theta);
+
+            Quaternion.FromUnitVectorsToRef(Vector3.UpReadOnly, this.up, this._skyOrientation);
+            this.sunPosition.rotateByQuaternionToRef(this._skyOrientation, this.sunPosition);
         }
 
         this._activeEffect.setVector3("sunPosition", this.sunPosition);

+ 29 - 0
src/Maths/math.vector.ts

@@ -3454,6 +3454,35 @@ export class Quaternion {
     }
 
     /**
+     * Updates a quaternion so that it rotates vector vecFrom to vector vecTo
+     * @param vecFrom defines the direction vector from which to rotate
+     * @param vecTo defines the direction vector to which to rotate
+     * @param result the quaternion to store the result
+     * @returns the updated quaternion
+     */
+    public static FromUnitVectorsToRef(vecFrom: DeepImmutable<Vector3>, vecTo: DeepImmutable<Vector3>, result: Quaternion): Quaternion {
+        const r = Vector3.Dot(vecFrom, vecTo) + 1;
+
+        if (r < Epsilon) {
+            if (Math.abs(vecFrom.x) > Math.abs(vecFrom.z)) {
+                result.set(-vecFrom.y, vecFrom.x, 0, 0);
+            } else {
+                result.set(0, - vecFrom.z, vecFrom.y, 0);
+            }
+        } else {
+            Vector3.CrossToRef(vecFrom, vecTo, TmpVectors.Vector3[0]);
+            result.set(
+                TmpVectors.Vector3[0].x,
+                TmpVectors.Vector3[0].y,
+                TmpVectors.Vector3[0].z,
+                r
+            );
+        }
+
+        return result.normalize();
+    }
+
+    /**
      * Creates a new quaternion from the given Euler float angles (y, x, z)
      * @param yaw defines the rotation around Y axis
      * @param pitch defines the rotation around X axis