Jelajahi Sumber

Adding way to add camera offset in sky material to keep horizon at a specific position relative to the camera

Julien MOREAU-MATHIS 6 tahun lalu
induk
melakukan
5f57bc32b0

+ 1 - 0
dist/preview release/what's new.md

@@ -99,6 +99,7 @@
 ### Viewer
 
 ### Materials Library
+- Added the `cameraOffset` vector property in the `SkyMaterial` to get an offset according to the horizon ([julien-moreau](https://github.com/julien-moreau))
 
 ## Bug fixes
 - Fixed TransformNode.setDirection (orientation was wrong) ([Deltakosh](https://github.com/deltakosh))

+ 111 - 15
materialsLibrary/src/sky/babylon.skyMaterial.ts

@@ -1,6 +1,7 @@
 /// <reference path="../../../dist/preview release/babylon.d.ts"/>
 
 module BABYLON {
+    /** @hidden */
     class SkyMaterialDefines extends MaterialDefines {
         public CLIPPLANE = false;
         public CLIPPLANE2 = false;
@@ -17,60 +18,119 @@ module BABYLON {
         }
     }
 
+    /**
+     * This is the sky material which allows to create dynamic and texture free effects for skyboxes.
+     * @see https://doc.babylonjs.com/extensions/sky
+     */
     export class SkyMaterial extends PushMaterial {
-        // Public members
+        /**
+         * Defines the overall luminance of sky in interval ]0, 1[.
+         */
         @serialize()
         public luminance: number = 1.0;
-
+        /**
+         * Defines the amount (scattering) of haze as opposed to molecules in atmosphere.
+         */
         @serialize()
         public turbidity: number = 10.0;
-
+        /**
+         * Defines the sky appearance (light intensity).
+         */
         @serialize()
         public rayleigh: number = 2.0;
-
+        /**
+         * Defines the mieCoefficient in interval [0, 0.1] which affects the property .mieDirectionalG.
+         */
         @serialize()
         public mieCoefficient: number = 0.005;
-
+        /**
+         * Defines the amount of haze particles following the Mie scattering theory.
+         */
         @serialize()
         public mieDirectionalG: number = 0.8;
-
+        /**
+         * Defines the distance of the sun according to the active scene camera.
+         */
         @serialize()
         public distance: number = 500;
-
+        /**
+         * Defines the sun inclination, in interval [-0.5, 0.5]. When the inclination is not 0, the sun is said
+         * "inclined".
+         */
         @serialize()
         public inclination: number = 0.49;
-
+        /**
+         * Defines the solar azimuth in interval [0, 1]. The azimuth is the angle in the horizontal plan between
+         * an object direction and a reference direction.
+         */
         @serialize()
         public azimuth: number = 0.25;
-
+        /**
+         * Defines the sun position in the sky on (x,y,z). If the property .useSunPosition is set to false, then
+         * the property is overriden by the inclination and the azimuth and can be read at any moment.
+         */
         @serializeAsVector3()
         public sunPosition: Vector3 = new Vector3(0, 100, 0);
-
+        /**
+         * Defines if the sun position should be computed (inclination and azimuth) according to the given
+         * .sunPosition property.
+         */
         @serialize()
         public useSunPosition: boolean = false;
+        /**
+         * Defines an offset vector used to get a horizon offset.
+         * @example skyMaterial.cameraOffset.y = camera.globalPosition.y // Set horizon relative to 0 on the Y axis
+         */
+        @serialize()
+        public cameraOffset: Vector3 = Vector3.Zero();
 
-        // Private members
         private _cameraPosition: Vector3 = Vector3.Zero();
-
         private _renderId: number;
 
+        /**
+         * Instantiates a new sky material.
+         * This material allows to create dynamic and texture free
+         * effects for skyboxes by taking care of the atmosphere state.
+         * @see https://doc.babylonjs.com/extensions/sky
+         * @param name Define the name of the material in the scene
+         * @param scene Define the scene the material belong to
+         */
         constructor(name: string, scene: Scene) {
             super(name, scene);
         }
 
+        /**
+         * Specifies if the material will require alpha blending
+         * @returns a boolean specifying if alpha blending is needed
+         */
         public needAlphaBlending(): boolean {
             return (this.alpha < 1.0);
         }
 
+        /**
+         * Specifies if this material should be rendered in alpha test mode
+         * @returns false as the sky material doesn't need alpha testing.
+         */
         public needAlphaTesting(): boolean {
             return false;
         }
 
+        /**
+         * Get the texture used for alpha test purpose.
+         * @returns null as the sky material has no texture.
+         */
         public getAlphaTestTexture(): Nullable<BaseTexture> {
             return null;
         }
 
-        // Methods
+        /**
+         * Get if the submesh is ready to be used and all its information available.
+         * Child classes can use it to update shaders
+         * @param mesh defines the mesh to check
+         * @param subMesh defines which submesh to check
+         * @param useInstances specifies that instances should be used
+         * @returns a boolean indicating that the submesh is ready or not
+         */
         public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
             if (this.isFrozen) {
                 if (this._wasPreviouslyReady && subMesh.effect) {
@@ -123,7 +183,7 @@ module BABYLON {
                     ["world", "viewProjection", "view",
                         "vFogInfos", "vFogColor", "pointSize", "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4",
                         "luminance", "turbidity", "rayleigh", "mieCoefficient", "mieDirectionalG", "sunPosition",
-                        "cameraPosition"
+                        "cameraPosition", "cameraOffset"
                     ],
                     [],
                     join, fallbacks, this.onCompiled, this.onError), defines);
@@ -139,6 +199,12 @@ module BABYLON {
             return true;
         }
 
+        /**
+         * Binds the submesh to this material by preparing the effect and shader to draw
+         * @param world defines the world transformation matrix
+         * @param mesh defines the mesh containing the submesh
+         * @param subMesh defines the submesh to bind the material to
+         */
         public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
             var scene = this.getScene();
 
@@ -185,6 +251,8 @@ module BABYLON {
                 this._activeEffect.setVector3("cameraPosition", this._cameraPosition);
             }
 
+            this._activeEffect.setVector3("cameraOffset", this.cameraOffset);
+
             if (this.luminance > 0) {
                 this._activeEffect.setFloat("luminance", this.luminance);
             }
@@ -208,29 +276,57 @@ module BABYLON {
             this._afterBind(mesh, this._activeEffect);
         }
 
+        /**
+         * Get the list of animatables in the material.
+         * @returns the list of animatables object used in the material
+         */
         public getAnimatables(): IAnimatable[] {
             return [];
         }
 
+        /**
+         * Disposes the material
+         * @param forceDisposeEffect specifies if effects should be forcefully disposed
+         */
         public dispose(forceDisposeEffect?: boolean): void {
             super.dispose(forceDisposeEffect);
         }
 
+        /**
+         * Makes a duplicate of the material, and gives it a new name
+         * @param name defines the new name for the duplicated material
+         * @returns the cloned material
+         */
         public clone(name: string): SkyMaterial {
             return SerializationHelper.Clone<SkyMaterial>(() => new SkyMaterial(name, this.getScene()), this);
         }
 
+        /**
+         * Serializes this material in a JSON representation
+         * @returns the serialized material object
+         */
         public serialize(): any {
             var serializationObject = SerializationHelper.Serialize(this);
             serializationObject.customType  = "BABYLON.SkyMaterial";
             return serializationObject;
         }
 
+        /**
+         * Gets the current class name of the material e.g. "SkyMaterial"
+         * Mainly use in serialization.
+         * @returns the class name
+         */
         public getClassName(): string {
             return "SkyMaterial";
         }
 
-        // Statics
+        /**
+         * Creates a sky material from parsed material data
+         * @param source defines the JSON representation of the material
+         * @param scene defines the hosting scene
+         * @param rootUrl defines the root URL to use to load textures and relative dependencies
+         * @returns a new sky material
+         */
         public static Parse(source: any, scene: Scene, rootUrl: string): SkyMaterial {
             return SerializationHelper.Parse(() => new SkyMaterial(source.name, scene), source, scene, rootUrl);
         }

+ 3 - 2
materialsLibrary/src/sky/sky.fragment.fx

@@ -11,6 +11,7 @@ varying vec4 vColor;
 
 // Sky
 uniform vec3 cameraPosition;
+uniform vec3 cameraOffset;
 uniform float luminance;
 uniform float turbidity;
 uniform float rayleigh;
@@ -102,7 +103,7 @@ void main(void) {
 	float sunE = sunIntensity(dot(sunDirection, up));
 	vec3 betaR = simplifiedRayleigh() * rayleighCoefficient;
 	vec3 betaM = totalMie(lambda, K, turbidity) * mieCoefficient;
-	float zenithAngle = acos(max(0.0, dot(up, normalize(vPositionW - cameraPosition))));
+	float zenithAngle = acos(max(0.0, dot(up, normalize(vPositionW - cameraPosition + cameraOffset))));
 	float sR = rayleighZenithLength / (cos(zenithAngle) + 0.15 * pow(93.885 - ((zenithAngle * 180.0) / pi), -1.253));
 	float sM = mieZenithLength / (cos(zenithAngle) + 0.15 * pow(93.885 - ((zenithAngle * 180.0) / pi), -1.253));
 	vec3 Fex = exp(-(betaR * sR + betaM * sM));
@@ -125,7 +126,7 @@ void main(void) {
 	L0 += (sunE * 19000.0 * Fex) * sundisk;
 	
 	vec3 whiteScale = 1.0/Uncharted2Tonemap(vec3(W));
-	vec3 texColor = (Lin+L0);   
+	vec3 texColor = (Lin+L0);
 	texColor *= 0.04 ;
 	texColor += vec3(0.0,0.001,0.0025)*0.3;
 

+ 2 - 2
src/Materials/babylon.standardMaterial.ts

@@ -1674,10 +1674,10 @@ module BABYLON {
 
         /**
          * Creates a standard material from parsed material data
-         * @param source defines the JSON represnetation of the material
+         * @param source defines the JSON representation of the material
          * @param scene defines the hosting scene
          * @param rootUrl defines the root URL to use to load textures and relative dependencies
-         * @returns a new material
+         * @returns a new standard material
          */
         public static Parse(source: any, scene: Scene, rootUrl: string): StandardMaterial {
             return SerializationHelper.Parse(() => new StandardMaterial(source.name, scene), source, scene, rootUrl);