瀏覽代碼

New NoiseProceduralTexture in core

David Catuhe 7 年之前
父節點
當前提交
7930b77097

+ 12 - 2
Tools/Gulp/config.json

@@ -122,7 +122,8 @@
             "behaviors",
             "imageProcessing",
             "occlusionQuery",
-            "transformFeedback"     
+            "transformFeedback",
+            "noise"
         ],
         "minimal": [
             "meshBuilder",
@@ -271,7 +272,16 @@
             "dependUpon": [
                 "core"
             ]
-        },        
+        },  
+        "noise" : {
+            "files": [
+                "../../src/Materials/Textures/Procedurals/babylon.noiseProceduralTexture.js"
+            ],
+            "dependUpon": [
+                "core",
+                "procedural"
+            ]
+        },      
         "particles": {
             "files": [
                 "../../src/Particles/babylon.particle.js",

文件差異過大導致無法顯示
+ 12144 - 12144
dist/preview release/babylon.d.ts


文件差異過大導致無法顯示
+ 1 - 1
dist/preview release/viewer/babylon.viewer.js


+ 8 - 0
dist/preview release/viewer/babylon.viewer.max.js

@@ -104536,11 +104536,15 @@ var BABYLON;
             else {
                 _this._useDirectMapping = options.useDirectMapping;
             }
+            _this._setReady(false);
             // create
             var tempOptions = { loop: options.loop, autoPlay: options.autoPlay, autoUpdateTexture: true, poster: options.poster };
             var material = _this._material = new BABYLON.BackgroundMaterial(name + "_material", scene);
             var texture = _this._videoTexture = new BABYLON.VideoTexture(name + "_texture", urlsOrVideo, scene, false, _this._useDirectMapping, BABYLON.Texture.TRILINEAR_SAMPLINGMODE, tempOptions);
             _this._mesh = BABYLON.Mesh.CreateSphere(name + "_mesh", options.resolution, options.size, scene, false, BABYLON.Mesh.BACKSIDE);
+            texture.onLoadObservable.addOnce(function () {
+                _this._setReady(true);
+            });
             // configure material
             material.useEquirectangularFOV = true;
             material.fovMultiplier = 1.0;
@@ -104639,6 +104643,7 @@ var BABYLON;
             else {
                 _this._useDirectMapping = options.useDirectMapping;
             }
+            _this._setReady(false);
             // create
             var material = _this._material = new BABYLON.BackgroundMaterial(name + "_material", scene);
             _this._mesh = BABYLON.Mesh.CreateSphere(name + "_mesh", options.resolution, options.size, scene, false, BABYLON.Mesh.BACKSIDE);
@@ -104647,6 +104652,9 @@ var BABYLON;
             material.useEquirectangularFOV = true;
             material.fovMultiplier = 1.0;
             _this.photoTexture = new BABYLON.Texture(urlOfPhoto, scene, true, !_this._useDirectMapping);
+            _this.photoTexture.onLoadObservable.addOnce(function () {
+                _this._setReady(true);
+            });
             // configure mesh
             _this._mesh.material = material;
             _this._mesh.parent = _this;

+ 83 - 0
src/Materials/Textures/Procedurals/babylon.noiseProceduralTexture.ts

@@ -0,0 +1,83 @@
+module BABYLON {
+    /**
+     * Class used to generate noise procedural textures
+     */
+    export class NoiseProceduralTexture extends ProceduralTexture {
+        private _time = new Vector2();
+
+        /** Gets or sets a value between 0 and 1 indicating the overall brightness of the texture (default is 0.2) */
+        public brightness = 0.2;
+
+        /** Defines the first octave to start from (default is 3) */
+        public firstOctave = 3;
+
+        /** Defines the number of octaves to process */
+        public octaves = 8;
+
+        /** Defines the level of persistence (0.8 by default) */
+        public persistence = 0.8;
+
+        public animationSpeedFactorX = 1;
+        public animationSpeedFactorY = 1;
+
+        /**
+         * Creates a new NoiseProceduralTexture
+         * @param name defines the name fo the texture
+         * @param size defines the size of the texture (default is 256)
+         * @param scene defines the hosting scene
+         * @param fallbackTexture defines the texture to use if the NoiseProceduralTexture can't be created
+         * @param generateMipMaps defines if mipmaps must be generated (true by default)
+         */
+        constructor(name: string, size: number = 256, scene: Nullable<Scene> = Engine.LastCreatedScene, fallbackTexture?: Texture, generateMipMaps?: boolean) {
+            super(name, size, "noise", scene, fallbackTexture, generateMipMaps);
+            this._updateShaderUniforms();
+        }
+
+        private _updateShaderUniforms() {
+            let scene = this.getScene();
+
+            if (!scene) {
+                return;
+            }
+
+            this._time.x += scene.getAnimationRatio() * this.animationSpeedFactorX * 0.001;
+            this._time.y += scene.getAnimationRatio() * this.animationSpeedFactorY * 0.001;
+
+            this.setFloat("brightness", this.brightness);
+            this.setInt("firstOctave", this.firstOctave);
+            this.setInt("octaves", this.octaves);
+            this.setFloat("persistence", this.persistence);
+            this.setVector2("timeScale", this._time);
+        }
+
+        /** Generate the current state of the procedural texture */
+        public render(useCameraPostProcess?: boolean) {
+            this._updateShaderUniforms();
+            super.render(useCameraPostProcess);
+        }
+
+        /**
+         * Serializes this noise procedural texture
+         * @returns a serialized noise procedural texture object
+         */
+        public serialize(): any {
+            var serializationObject = SerializationHelper.Serialize(this, super.serialize());
+            serializationObject.customType = "BABYLON.NoiseProceduralTexture";
+
+            return serializationObject;
+        }
+
+        /**
+         * Creates a NoiseProceduralTexture from parsed noise procedural texture data
+         * @param parsedTexture defines parsed texture data
+         * @param scene defines the current scene
+         * @param rootUrl defines the root URL containing noise procedural texture information
+         * @returns a parsed NoiseProceduralTexture
+         */
+        public static Parse(parsedTexture: any, scene: Scene, rootUrl: string): NoiseProceduralTexture {
+            var texture = SerializationHelper.Parse(() => new NoiseProceduralTexture(parsedTexture.name, parsedTexture._size, scene, undefined, parsedTexture._generateMipMaps), parsedTexture, scene, rootUrl);
+
+            return texture;
+        }        
+    }
+}

+ 17 - 1
src/Materials/Textures/Procedurals/babylon.proceduralTexture.ts

@@ -23,6 +23,7 @@
 
         public _textures: {[key: string]: Texture} = {};
         private _floats: {[key: string]: number} = {};
+        private _ints: {[key: string]: number} = {};
         private _floatsArrays: {[key: string]: number[]} = {};
         private _colors3: {[key: string]: Color3} = {};
         private _colors4: {[key: string]: Color4} = {};
@@ -35,9 +36,11 @@
         private _fallbackTextureUsed = false;
         private _engine: Engine;
 
-        constructor(name: string, size: any, fragment: any, scene: Scene, fallbackTexture: Nullable<Texture> = null, generateMipMaps = true, public isCube = false) {
+        constructor(name: string, size: any, fragment: any, scene: Nullable<Scene>, fallbackTexture: Nullable<Texture> = null, generateMipMaps = true, public isCube = false) {
             super(null, scene, !generateMipMaps);
 
+            scene = this.getScene()!;
+
             scene.proceduralTextures.push(this);
 
             this._engine = scene.getEngine();
@@ -232,6 +235,14 @@
             return this;
         }
 
+        
+        public setInt(name: string, value: number): ProceduralTexture {
+            this._checkUniform(name);
+            this._ints[name] = value;
+
+            return this;
+        }
+
         public setFloats(name: string, value: number[]): ProceduralTexture {
             this._checkUniform(name);
             this._floatsArrays[name] = value;
@@ -293,6 +304,11 @@
             }
 
             // Float    
+            for (name in this._ints) {
+                this._effect.setInt(name, this._ints[name]);
+            }            
+
+            // Float    
             for (name in this._floats) {
                 this._effect.setFloat(name, this._floats[name]);
             }

+ 78 - 0
src/Shaders/noise.fragment.fx

@@ -0,0 +1,78 @@
+// Source: https://www.shadertoy.com/view/4lB3zz
+
+// Uniforms
+uniform float brightness;
+uniform int firstOctave;
+uniform int octaves;
+uniform float persistence;
+uniform vec2 timeScale;
+
+// Varyings
+varying vec2 vUV;
+
+// Functions
+float noise(int x,int y)
+{   
+    float fx = float(x);
+    float fy = float(y);
+    
+    return 2.0 * fract(sin(dot(vec2(fx, fy), vec2(12.9898, 78.233))) * 43758.5453) - 1.0;
+}
+
+float smoothNoise(int x,int y)
+{
+    return noise(x, y) / 4.0 + (noise(x + 1, y) + noise(x - 1,y) + 
+           noise(x, y + 1) + noise(x, y - 1)) / 8.0 + (noise(x + 1, y + 1) +
+           noise(x + 1,y - 1) + noise(x - 1, y + 1) + noise(x - 1,y - 1)) / 16.0;
+}
+
+float cosInterpolation(float x,float y,float n)
+{
+    float r = n * 3.1415926;
+    float f = (1.0 - cos(r)) * 0.5;
+    return x * (1.0 - f) + y * f;    
+}
+
+float interpolationNoise(float x, float y)
+{
+    int ix = int(x);
+    int iy = int(y);
+    float fracx = x - float(int(x));
+    float fracy = y - float(int(y));
+    
+    float v1 = smoothNoise(ix, iy);
+    float v2 = smoothNoise(ix + 1, iy);
+    float v3 = smoothNoise(ix, iy + 1);
+    float v4 = smoothNoise(ix + 1, iy + 1);
+    
+   	float i1 = cosInterpolation(v1, v2, fracx);
+    float i2 = cosInterpolation(v3, v4, fracx);
+    
+    return cosInterpolation(i1, i2, fracy);    
+}
+
+float perlinNoise2D(float x,float y)
+{
+    float sum = 0.0;
+    float frequency = 0.0;
+    float amplitude = 0.0;
+    for(int i = firstOctave; i < octaves + firstOctave; i++)
+    {
+        frequency = pow(2.0, float(i));
+        amplitude = pow(persistence, float(i));
+        sum = sum + interpolationNoise(x * frequency, y * frequency) * amplitude;
+    }
+    
+    return sum;
+}
+
+// Main
+void main(void)
+{
+    float x = abs(vUV.x + timeScale.x);
+    float y = abs(vUV.y + timeScale.y);
+
+    float noise = brightness + (1.0 - brightness) * perlinNoise2D(x,y);
+
+	gl_FragColor = vec4(noise, noise, noise, 1.0);
+}

+ 1 - 1
src/babylon.scene.ts

@@ -1513,7 +1513,7 @@
          * @returns a number
          */
         public getAnimationRatio(): number {
-            return this._animationRatio;
+            return this._animationRatio !== undefined ? this._animationRatio : 1;
         }
 
         /**