Browse Source

2.0 alpha
Procedural Texture - first step

David Catuhe 10 năm trước cách đây
mục cha
commit
de2cd36a5a

+ 268 - 0
Babylon/Materials/textures/Procedurals/babylon.proceduralTexture.js

@@ -0,0 +1,268 @@
+var __extends = this.__extends || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    __.prototype = b.prototype;
+    d.prototype = new __();
+};
+var BABYLON;
+(function (BABYLON) {
+    var ProceduralTexture = (function (_super) {
+        __extends(ProceduralTexture, _super);
+        function ProceduralTexture(name, size, fragment, scene, fallbackTexture, generateMipMaps) {
+            _super.call(this, null, scene, !generateMipMaps);
+            this._currentRefreshId = -1;
+            this._refreshRate = 1;
+            this._vertexDeclaration = [2];
+            this._vertexStrideSize = 2 * 4;
+            this._uniforms = new Array();
+            this._samplers = new Array();
+            this._textures = new Array();
+            this._floats = new Array();
+            this._floatsArrays = {};
+            this._colors3 = new Array();
+            this._colors4 = new Array();
+            this._vectors2 = new Array();
+            this._vectors3 = new Array();
+            this._matrices = new Array();
+
+            scene._proceduralTextures.push(this);
+
+            this.name = name;
+            this.isRenderTarget = true;
+            this._size = size;
+            this._generateMipMaps = generateMipMaps;
+
+            this._fragment = fragment;
+
+            this._fallbackTexture = fallbackTexture;
+
+            this._texture = scene.getEngine().createRenderTargetTexture(size, generateMipMaps);
+
+            // VBO
+            var vertices = [];
+            vertices.push(1, 1);
+            vertices.push(-1, 1);
+            vertices.push(-1, -1);
+            vertices.push(1, -1);
+
+            this._vertexBuffer = scene.getEngine().createVertexBuffer(vertices);
+
+            // Indices
+            var indices = [];
+            indices.push(0);
+            indices.push(1);
+            indices.push(2);
+
+            indices.push(0);
+            indices.push(2);
+            indices.push(3);
+
+            this._indexBuffer = scene.getEngine().createIndexBuffer(indices);
+        }
+        ProceduralTexture.prototype.isReady = function () {
+            var _this = this;
+            var engine = this.getScene().getEngine();
+
+            this._effect = engine.createEffect({ vertex: "procedural", fragment: this._fragment }, ["position"], this._uniforms, this._samplers, "", null, null, function () {
+                _this.releaseInternalTexture();
+
+                _this._texture = _this._fallbackTexture._texture;
+                _this._texture.references++;
+            });
+
+            return this._effect.isReady();
+        };
+
+        ProceduralTexture.prototype.resetRefreshCounter = function () {
+            this._currentRefreshId = -1;
+        };
+
+        Object.defineProperty(ProceduralTexture.prototype, "refreshRate", {
+            get: function () {
+                return this._refreshRate;
+            },
+            // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
+            set: function (value) {
+                this._refreshRate = value;
+                this.resetRefreshCounter();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+
+        ProceduralTexture.prototype._shouldRender = function () {
+            if (!this.isReady() || !this._texture) {
+                return false;
+            }
+
+            if (this._currentRefreshId === -1) {
+                this._currentRefreshId = 1;
+                return true;
+            }
+
+            if (this.refreshRate == this._currentRefreshId) {
+                this._currentRefreshId = 1;
+                return true;
+            }
+
+            this._currentRefreshId++;
+            return false;
+        };
+
+        ProceduralTexture.prototype.getRenderSize = function () {
+            return this._size;
+        };
+
+        ProceduralTexture.prototype.resize = function (size, generateMipMaps) {
+            this.releaseInternalTexture();
+            this._texture = this.getScene().getEngine().createRenderTargetTexture(size, generateMipMaps);
+        };
+
+        ProceduralTexture.prototype._checkUniform = function (uniformName) {
+            if (this._uniforms.indexOf(uniformName) === -1) {
+                this._uniforms.push(uniformName);
+            }
+        };
+
+        ProceduralTexture.prototype.setTexture = function (name, texture) {
+            if (this._samplers.indexOf(name) === -1) {
+                this._samplers.push(name);
+            }
+            this._textures[name] = texture;
+
+            return this;
+        };
+
+        ProceduralTexture.prototype.setFloat = function (name, value) {
+            this._checkUniform(name);
+            this._floats[name] = value;
+
+            return this;
+        };
+
+        ProceduralTexture.prototype.setFloats = function (name, value) {
+            this._checkUniform(name);
+            this._floatsArrays[name] = value;
+
+            return this;
+        };
+
+        ProceduralTexture.prototype.setColor3 = function (name, value) {
+            this._checkUniform(name);
+            this._colors3[name] = value;
+
+            return this;
+        };
+
+        ProceduralTexture.prototype.setColor4 = function (name, value) {
+            this._checkUniform(name);
+            this._colors4[name] = value;
+
+            return this;
+        };
+
+        ProceduralTexture.prototype.setVector2 = function (name, value) {
+            this._checkUniform(name);
+            this._vectors2[name] = value;
+
+            return this;
+        };
+
+        ProceduralTexture.prototype.setVector3 = function (name, value) {
+            this._checkUniform(name);
+            this._vectors3[name] = value;
+
+            return this;
+        };
+
+        ProceduralTexture.prototype.setMatrix = function (name, value) {
+            this._checkUniform(name);
+            this._matrices[name] = value;
+
+            return this;
+        };
+
+        ProceduralTexture.prototype.render = function (useCameraPostProcess) {
+            var scene = this.getScene();
+            var engine = scene.getEngine();
+
+            engine.bindFramebuffer(this._texture);
+
+            // Clear
+            engine.clear(scene.clearColor, true, true);
+
+            // Render
+            engine.enableEffect(this._effect);
+            engine.setState(false);
+
+            for (var name in this._textures) {
+                this._effect.setTexture(name, this._textures[name]);
+            }
+
+            for (name in this._floats) {
+                this._effect.setFloat(name, this._floats[name]);
+            }
+
+            for (name in this._floatsArrays) {
+                this._effect.setArray(name, this._floatsArrays[name]);
+            }
+
+            for (name in this._colors3) {
+                this._effect.setColor3(name, this._colors3[name]);
+            }
+
+            for (name in this._colors4) {
+                var color = this._colors4[name];
+                this._effect.setFloat4(name, color.r, color.g, color.b, color.a);
+            }
+
+            for (name in this._vectors2) {
+                this._effect.setVector2(name, this._vectors2[name]);
+            }
+
+            for (name in this._vectors3) {
+                this._effect.setVector3(name, this._vectors3[name]);
+            }
+
+            for (name in this._matrices) {
+                this._effect.setMatrix(name, this._matrices[name]);
+            }
+
+            // VBOs
+            engine.bindBuffers(this._vertexBuffer, this._indexBuffer, this._vertexDeclaration, this._vertexStrideSize, this._effect);
+
+            // Draw order
+            engine.draw(true, 0, 6);
+
+            // Unbind
+            engine.unBindFramebuffer(this._texture);
+        };
+
+        ProceduralTexture.prototype.clone = function () {
+            var textureSize = this.getSize();
+            var newTexture = new BABYLON.ProceduralTexture(this.name, textureSize.width, this._fragment, this.getScene(), this._fallbackTexture, this._generateMipMaps);
+
+            // Base texture
+            newTexture.hasAlpha = this.hasAlpha;
+            newTexture.level = this.level;
+
+            // RenderTarget Texture
+            newTexture.coordinatesMode = this.coordinatesMode;
+
+            return newTexture;
+        };
+
+        ProceduralTexture.prototype.dispose = function () {
+            var index = this.getScene()._proceduralTextures.indexOf(this);
+
+            if (index >= 0) {
+                this.getScene()._proceduralTextures.splice(index, 1);
+            }
+            _super.prototype.dispose.call(this);
+        };
+        return ProceduralTexture;
+    })(BABYLON.Texture);
+    BABYLON.ProceduralTexture = ProceduralTexture;
+})(BABYLON || (BABYLON = {}));
+//# sourceMappingURL=babylon.proceduralTexture.js.map

+ 279 - 0
Babylon/Materials/textures/Procedurals/babylon.proceduralTexture.ts

@@ -0,0 +1,279 @@
+module BABYLON {
+    export class ProceduralTexture extends Texture {
+        private _size: number;
+        public _generateMipMaps: boolean;
+        private _doNotChangeAspectRatio: boolean;
+        private _currentRefreshId = -1;
+        private _refreshRate = 1;
+
+        private _vertexBuffer: WebGLBuffer;
+        private _indexBuffer: WebGLBuffer;
+        private _effect: Effect;
+
+        private _vertexDeclaration = [2];
+        private _vertexStrideSize = 2 * 4;
+
+        private _uniforms = new Array<string>();
+        private _samplers = new Array<string>();
+        private _fragment: any;
+
+        private _textures = new Array<Texture>();
+        private _floats = new Array<number>();
+        private _floatsArrays = {};
+        private _colors3 = new Array<Color3>();
+        private _colors4 = new Array<Color4>();
+        private _vectors2 = new Array<Vector2>();
+        private _vectors3 = new Array<Vector3>();
+        private _matrices = new Array<Matrix>();
+
+        private _fallbackTexture: Texture;
+
+        constructor(name: string, size: any, fragment: any, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean) {
+            super(null, scene, !generateMipMaps);
+
+            scene._proceduralTextures.push(this);
+
+            this.name = name;
+            this.isRenderTarget = true;
+            this._size = size;
+            this._generateMipMaps = generateMipMaps;
+
+            this._fragment = fragment;
+
+            this._fallbackTexture = fallbackTexture;
+
+            this._texture = scene.getEngine().createRenderTargetTexture(size, generateMipMaps);
+
+            // VBO
+            var vertices = [];
+            vertices.push(1, 1);
+            vertices.push(-1, 1);
+            vertices.push(-1, -1);
+            vertices.push(1, -1);
+
+            this._vertexBuffer = scene.getEngine().createVertexBuffer(vertices);
+
+            // Indices
+            var indices = [];
+            indices.push(0);
+            indices.push(1);
+            indices.push(2);
+
+            indices.push(0);
+            indices.push(2);
+            indices.push(3);
+
+            this._indexBuffer = scene.getEngine().createIndexBuffer(indices);
+        }
+
+        public isReady(): boolean {
+            var engine = this.getScene().getEngine();
+
+            this._effect = engine.createEffect({ vertex: "procedural", fragment: this._fragment },
+                ["position"],
+                this._uniforms,
+                this._samplers,
+                "", null, null, () => {
+                    this.releaseInternalTexture();
+
+                    this._texture = this._fallbackTexture._texture;
+                    this._texture.references++;
+                });
+
+            return this._effect.isReady();
+        }
+
+        public resetRefreshCounter(): void {
+            this._currentRefreshId = -1;
+        }
+
+        public get refreshRate(): number {
+            return this._refreshRate;
+        }
+
+        // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
+        public set refreshRate(value: number) {
+            this._refreshRate = value;
+            this.resetRefreshCounter();
+        }
+
+        public _shouldRender(): boolean {
+            if (!this.isReady() || !this._texture) {
+                return false;
+            }
+
+            if (this._currentRefreshId === -1) { // At least render once
+                this._currentRefreshId = 1;
+                return true;
+            }
+
+            if (this.refreshRate == this._currentRefreshId) {
+                this._currentRefreshId = 1;
+                return true;
+            }
+
+            this._currentRefreshId++;
+            return false;
+        }
+
+        public getRenderSize(): number {
+            return this._size;
+        }
+
+        public resize(size, generateMipMaps) {
+            this.releaseInternalTexture();
+            this._texture = this.getScene().getEngine().createRenderTargetTexture(size, generateMipMaps);
+        }
+
+        private _checkUniform(uniformName): void {
+            if (this._uniforms.indexOf(uniformName) === -1) {
+                this._uniforms.push(uniformName);
+            }
+        }
+
+        public setTexture(name: string, texture: Texture): ProceduralTexture {
+            if (this._samplers.indexOf(name) === -1) {
+                this._samplers.push(name);
+            }
+            this._textures[name] = texture;
+
+            return this;
+        }
+
+        public setFloat(name: string, value: number): ProceduralTexture {
+            this._checkUniform(name);
+            this._floats[name] = value;
+
+            return this;
+        }
+
+        public setFloats(name: string, value: number[]): ProceduralTexture {
+            this._checkUniform(name);
+            this._floatsArrays[name] = value;
+
+            return this;
+        }
+
+        public setColor3(name: string, value: Color3): ProceduralTexture {
+            this._checkUniform(name);
+            this._colors3[name] = value;
+
+            return this;
+        }
+
+        public setColor4(name: string, value: Color4): ProceduralTexture {
+            this._checkUniform(name);
+            this._colors4[name] = value;
+
+            return this;
+        }
+
+        public setVector2(name: string, value: Vector2): ProceduralTexture {
+            this._checkUniform(name);
+            this._vectors2[name] = value;
+
+            return this;
+        }
+
+        public setVector3(name: string, value: Vector3): ProceduralTexture {
+            this._checkUniform(name);
+            this._vectors3[name] = value;
+
+            return this;
+        }
+
+        public setMatrix(name: string, value: Matrix): ProceduralTexture {
+            this._checkUniform(name);
+            this._matrices[name] = value;
+
+            return this;
+        }
+
+        public render(useCameraPostProcess?: boolean) {
+            var scene = this.getScene();
+            var engine = scene.getEngine();
+
+            engine.bindFramebuffer(this._texture);
+
+            // Clear
+            engine.clear(scene.clearColor, true, true);
+
+            // Render
+            engine.enableEffect(this._effect);
+            engine.setState(false);
+
+            // Texture
+            for (var name in this._textures) {
+                this._effect.setTexture(name, this._textures[name]);
+            }
+
+            // Float    
+            for (name in this._floats) {
+                this._effect.setFloat(name, this._floats[name]);
+            }
+
+            // Float s   
+            for (name in this._floatsArrays) {
+                this._effect.setArray(name, this._floatsArrays[name]);
+            }
+
+            // Color3        
+            for (name in this._colors3) {
+                this._effect.setColor3(name, this._colors3[name]);
+            }
+
+            // Color4      
+            for (name in this._colors4) {
+                var color = this._colors4[name];
+                this._effect.setFloat4(name, color.r, color.g, color.b, color.a);
+            }
+
+            // Vector2        
+            for (name in this._vectors2) {
+                this._effect.setVector2(name, this._vectors2[name]);
+            }
+
+            // Vector3        
+            for (name in this._vectors3) {
+                this._effect.setVector3(name, this._vectors3[name]);
+            }
+
+            // Matrix      
+            for (name in this._matrices) {
+                this._effect.setMatrix(name, this._matrices[name]);
+            }
+
+            // VBOs
+            engine.bindBuffers(this._vertexBuffer, this._indexBuffer, this._vertexDeclaration, this._vertexStrideSize, this._effect);
+
+            // Draw order
+            engine.draw(true, 0, 6);
+
+            // Unbind
+            engine.unBindFramebuffer(this._texture);
+        }
+
+        public clone(): ProceduralTexture {
+            var textureSize = this.getSize();
+            var newTexture = new BABYLON.ProceduralTexture(this.name, textureSize.width, this._fragment, this.getScene(), this._fallbackTexture, this._generateMipMaps);
+
+            // Base texture
+            newTexture.hasAlpha = this.hasAlpha;
+            newTexture.level = this.level;
+
+            // RenderTarget Texture
+            newTexture.coordinatesMode = this.coordinatesMode;
+
+            return newTexture;
+        }
+
+        public dispose(): void {
+            var index = this.getScene()._proceduralTextures.indexOf(this);
+
+            if (index >= 0) {
+                this.getScene()._proceduralTextures.splice(index, 1);
+            }
+            super.dispose();
+        }
+    }
+} 

+ 252 - 0
Babylon/Materials/textures/Procedurals/babylon.standardProceduralTexture.js

@@ -0,0 +1,252 @@
+var __extends = this.__extends || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    __.prototype = b.prototype;
+    d.prototype = new __();
+};
+var BABYLON;
+(function (BABYLON) {
+    var WoodProceduralTexture = (function (_super) {
+        __extends(WoodProceduralTexture, _super);
+        function WoodProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
+            _super.call(this, name, size, "wood", scene, fallbackTexture, generateMipMaps);
+            this._ampScale = 0.03;
+            this._ringScale = 5;
+            this._woodColor1 = new BABYLON.Color3(0.80, 0.55, 0.01);
+            this._woodColor2 = new BABYLON.Color3(0.60, 0.41, 0.0);
+
+            this.updateShaderUniforms();
+
+            // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
+            this.refreshRate = 0;
+        }
+        WoodProceduralTexture.prototype.updateShaderUniforms = function () {
+            this.setFloat("ampScale", this._ampScale);
+            this.setFloat("ringScale", this._ringScale);
+            this.setColor3("woodColor1", this._woodColor1);
+            this.setColor3("woodColor2", this._woodColor2);
+        };
+
+        Object.defineProperty(WoodProceduralTexture.prototype, "ampScale", {
+            get: function () {
+                return this._ampScale;
+            },
+            set: function (value) {
+                this._ampScale = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+
+        Object.defineProperty(WoodProceduralTexture.prototype, "ringScale", {
+            get: function () {
+                return this._ringScale;
+            },
+            set: function (value) {
+                this._ringScale = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+
+        Object.defineProperty(WoodProceduralTexture.prototype, "woodColor1", {
+            get: function () {
+                return this._woodColor1;
+            },
+            set: function (value) {
+                this._woodColor1 = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+
+        Object.defineProperty(WoodProceduralTexture.prototype, "woodColor2", {
+            get: function () {
+                return this._woodColor2;
+            },
+            set: function (value) {
+                this._woodColor2 = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+        return WoodProceduralTexture;
+    })(BABYLON.ProceduralTexture);
+    BABYLON.WoodProceduralTexture = WoodProceduralTexture;
+
+    var FireProceduralTexture = (function (_super) {
+        __extends(FireProceduralTexture, _super);
+        function FireProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
+            _super.call(this, name, size, "fire", scene, fallbackTexture, generateMipMaps);
+            this._time = 0.0;
+            this._speed = new BABYLON.Vector2(0.5, 0.3);
+            this._shift = 1.6;
+            this._alpha = 1.0;
+            this._autoGenerateTime = true;
+
+            this._fireColors = FireProceduralTexture.RedFireColors;
+            this.updateShaderUniforms();
+
+            // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
+            this.refreshRate = 1;
+        }
+        FireProceduralTexture.prototype.updateShaderUniforms = function () {
+            this.setFloat("iGlobalTime", this._time);
+            this.setVector2("speed", this._speed);
+            this.setFloat("shift", this._shift);
+            this.setFloat("alpha", this._alpha);
+
+            this.setColor3("c1", new BABYLON.Color3(this._fireColors[0][0], this._fireColors[0][1], this._fireColors[0][2]));
+            this.setColor3("c2", new BABYLON.Color3(this._fireColors[1][0], this._fireColors[1][1], this._fireColors[1][2]));
+            this.setColor3("c3", new BABYLON.Color3(this._fireColors[2][0], this._fireColors[2][1], this._fireColors[2][2]));
+            this.setColor3("c4", new BABYLON.Color3(this._fireColors[3][0], this._fireColors[3][1], this._fireColors[3][2]));
+            this.setColor3("c5", new BABYLON.Color3(this._fireColors[4][0], this._fireColors[4][1], this._fireColors[4][2]));
+            this.setColor3("c6", new BABYLON.Color3(this._fireColors[5][0], this._fireColors[5][1], this._fireColors[5][2]));
+        };
+
+        FireProceduralTexture.prototype.render = function (useCameraPostProcess) {
+            if (this._autoGenerateTime) {
+                this._time += this.getScene().getAnimationRatio() * 0.03;
+                this.updateShaderUniforms();
+            }
+
+            _super.prototype.render.call(this, useCameraPostProcess);
+        };
+
+        Object.defineProperty(FireProceduralTexture, "PurpleFireColors", {
+            get: function () {
+                return [
+                    [0.5, 0.0, 1.0],
+                    [0.9, 0.0, 1.0],
+                    [0.2, 0.0, 1.0],
+                    [1.0, 0.9, 1.0],
+                    [0.1, 0.1, 1.0],
+                    [0.9, 0.9, 1.0]
+                ];
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+        Object.defineProperty(FireProceduralTexture, "GreenFireColors", {
+            get: function () {
+                return [
+                    [0.5, 1.0, 0.0],
+                    [0.5, 1.0, 0.0],
+                    [0.3, 0.4, 0.0],
+                    [0.5, 1.0, 0.0],
+                    [0.2, 0.0, 0.0],
+                    [0.5, 1.0, 0.0]
+                ];
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+        Object.defineProperty(FireProceduralTexture, "RedFireColors", {
+            get: function () {
+                return [
+                    [0.5, 0.0, 0.1],
+                    [0.9, 0.0, 0.0],
+                    [0.2, 0.0, 0.0],
+                    [1.0, 0.9, 0.0],
+                    [0.1, 0.1, 0.1],
+                    [0.9, 0.9, 0.9]
+                ];
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+        Object.defineProperty(FireProceduralTexture, "BlueFireColors", {
+            get: function () {
+                return [
+                    [0.1, 0.0, 0.5],
+                    [0.0, 0.0, 0.5],
+                    [0.1, 0.0, 0.2],
+                    [0.0, 0.0, 1.0],
+                    [0.1, 0.2, 0.3],
+                    [0.0, 0.2, 0.9]
+                ];
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+        Object.defineProperty(FireProceduralTexture.prototype, "fireColors", {
+            get: function () {
+                return this._fireColors;
+            },
+            set: function (value) {
+                this._fireColors = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+
+        Object.defineProperty(FireProceduralTexture.prototype, "time", {
+            get: function () {
+                return this._time;
+            },
+            set: function (value) {
+                this._time = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+
+        Object.defineProperty(FireProceduralTexture.prototype, "speed", {
+            get: function () {
+                return this._speed;
+            },
+            set: function (value) {
+                this._speed = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+
+        Object.defineProperty(FireProceduralTexture.prototype, "shift", {
+            get: function () {
+                return this._shift;
+            },
+            set: function (value) {
+                this._shift = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+
+        Object.defineProperty(FireProceduralTexture.prototype, "alpha", {
+            get: function () {
+                return this._alpha;
+            },
+            set: function (value) {
+                this._alpha = value;
+                this.updateShaderUniforms();
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+        return FireProceduralTexture;
+    })(BABYLON.ProceduralTexture);
+    BABYLON.FireProceduralTexture = FireProceduralTexture;
+})(BABYLON || (BABYLON = {}));
+//# sourceMappingURL=babylon.standardProceduralTexture.js.map

+ 202 - 0
Babylon/Materials/textures/Procedurals/babylon.standardProceduralTexture.ts

@@ -0,0 +1,202 @@
+module BABYLON {
+    export class WoodProceduralTexture extends ProceduralTexture {
+
+        private _ampScale: number = 0.03;
+        private _ringScale: number = 5;
+        private _woodColor1: BABYLON.Color3 = new BABYLON.Color3(0.80, 0.55, 0.01);
+        private _woodColor2: BABYLON.Color3 = new BABYLON.Color3(0.60, 0.41, 0.0);
+
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture,  generateMipMaps?: boolean) {
+            super(name, size, "wood", scene, fallbackTexture, generateMipMaps);
+
+            this.updateShaderUniforms();
+
+            // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
+            this.refreshRate = 0;
+
+        }
+
+        public updateShaderUniforms() {
+            this.setFloat("ampScale", this._ampScale);
+            this.setFloat("ringScale", this._ringScale);
+            this.setColor3("woodColor1", this._woodColor1);
+            this.setColor3("woodColor2", this._woodColor2);
+        }
+
+        public get ampScale(): number {
+            return this._ampScale;
+        }
+
+        public set ampScale(value: number) {
+            this._ampScale = value;
+            this.updateShaderUniforms();
+        }
+
+        public get ringScale(): number {
+            return this._ringScale;
+        }
+
+        public set ringScale(value: number) {
+            this._ringScale = value;
+            this.updateShaderUniforms();
+        }
+
+        public get woodColor1(): BABYLON.Color3 {
+            return this._woodColor1;
+        }
+
+        public set woodColor1(value: BABYLON.Color3) {
+            this._woodColor1 = value;
+            this.updateShaderUniforms();
+        }
+
+        public get woodColor2(): BABYLON.Color3 {
+            return this._woodColor2;
+        }
+
+        public set woodColor2(value: BABYLON.Color3) {
+            this._woodColor2 = value;
+            this.updateShaderUniforms();
+        }
+
+    }
+
+    export class FireProceduralTexture extends ProceduralTexture {
+
+        private _time: number = 0.0;
+        private _speed: BABYLON.Vector2 = new BABYLON.Vector2(0.5, 0.3);
+        private _shift: number = 1.6;
+        private _alpha: number = 1.0;
+        private _autoGenerateTime: boolean = true;
+
+        private _fireColors: number[][];
+
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean) {
+            super(name, size, "fire", scene, fallbackTexture, generateMipMaps);
+
+            this._fireColors = FireProceduralTexture.RedFireColors;
+            this.updateShaderUniforms();
+
+            // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
+            this.refreshRate = 1;
+
+        }
+
+        public updateShaderUniforms() {
+
+            this.setFloat("iGlobalTime", this._time);
+            this.setVector2("speed", this._speed);
+            this.setFloat("shift", this._shift);
+            this.setFloat("alpha", this._alpha);
+
+            this.setColor3("c1", new BABYLON.Color3(this._fireColors[0][0], this._fireColors[0][1], this._fireColors[0][2]));
+            this.setColor3("c2", new BABYLON.Color3(this._fireColors[1][0], this._fireColors[1][1], this._fireColors[1][2]));
+            this.setColor3("c3", new BABYLON.Color3(this._fireColors[2][0], this._fireColors[2][1], this._fireColors[2][2]));
+            this.setColor3("c4", new BABYLON.Color3(this._fireColors[3][0], this._fireColors[3][1], this._fireColors[3][2]));
+            this.setColor3("c5", new BABYLON.Color3(this._fireColors[4][0], this._fireColors[4][1], this._fireColors[4][2]));
+            this.setColor3("c6", new BABYLON.Color3(this._fireColors[5][0], this._fireColors[5][1], this._fireColors[5][2]));
+
+        }
+
+        public render(useCameraPostProcess?: boolean) {
+
+            if (this._autoGenerateTime) {
+                this._time += this.getScene().getAnimationRatio() * 0.03;
+                this.updateShaderUniforms();
+            }
+
+            super.render(useCameraPostProcess);
+        }
+
+        public static get PurpleFireColors(): number[][] {
+            return [
+                [0.5, 0.0, 1.0],
+                [0.9, 0.0, 1.0],
+                [0.2, 0.0, 1.0],
+                [1.0, 0.9, 1.0],
+                [0.1, 0.1, 1.0],
+                [0.9, 0.9, 1.0]
+            ];
+        }
+
+        public static get GreenFireColors(): number[][] {
+            return [
+                [0.5, 1.0, 0.0],
+                [0.5, 1.0, 0.0],
+                [0.3, 0.4, 0.0],
+                [0.5, 1.0, 0.0],
+                [0.2, 0.0, 0.0],
+                [0.5, 1.0, 0.0]
+            ];
+        }
+
+        public static get RedFireColors(): number[][] {
+            return [
+                [0.5, 0.0, 0.1],
+                [0.9, 0.0, 0.0],
+                [0.2, 0.0, 0.0],
+                [1.0, 0.9, 0.0],
+                [0.1, 0.1, 0.1],
+                [0.9, 0.9, 0.9]
+            ];
+        }
+
+        public static get BlueFireColors(): number[][] {
+            return [
+                [0.1, 0.0, 0.5],
+                [0.0, 0.0, 0.5],
+                [0.1, 0.0, 0.2],
+                [0.0, 0.0, 1.0],
+                [0.1, 0.2, 0.3],
+                [0.0, 0.2, 0.9]
+            ];
+        }
+       
+
+        public get fireColors(): number[][] {
+            return this._fireColors;
+        }
+
+        public set fireColors(value: number[][]) {
+            this._fireColors = value;
+            this.updateShaderUniforms();
+        }
+
+        public get time(): number {
+            return this._time;
+        }
+
+        public set time(value: number) {
+            this._time = value;
+            this.updateShaderUniforms();
+        }
+
+        public get speed(): BABYLON.Vector2 {
+            return this._speed;
+        }
+
+        public set speed(value: BABYLON.Vector2) {
+            this._speed = value;
+            this.updateShaderUniforms();
+        }
+
+        public get shift(): number {
+            return this._shift;
+        }
+
+        public set shift(value: number) {
+            this._shift = value;
+            this.updateShaderUniforms();
+        }
+
+        public get alpha(): number {
+            return this._alpha;
+        }
+
+        public set alpha(value: number) {
+            this._alpha = value;
+            this.updateShaderUniforms();
+        }
+
+    }
+}

+ 46 - 0
Babylon/Shaders/fire.fragment.fx

@@ -0,0 +1,46 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+
+uniform float iGlobalTime;
+uniform vec3 c1;
+uniform vec3 c2;
+uniform vec3 c3;
+uniform vec3 c4;
+uniform vec3 c5;
+uniform vec3 c6;
+uniform vec2 speed;
+uniform float shift;
+uniform float alpha;
+
+varying vec2 vUV;
+
+float rand(vec2 n) {
+	return fract(cos(dot(n, vec2(12.9898, 4.1414))) * 43758.5453);
+}
+
+float noise(vec2 n) {
+	const vec2 d = vec2(0.0, 1.0);
+	vec2 b = floor(n), f = smoothstep(vec2(0.0), vec2(1.0), fract(n));
+	return mix(mix(rand(b), rand(b + d.yx), f.x), mix(rand(b + d.xy), rand(b + d.yy), f.x), f.y);
+}
+
+float fbm(vec2 n) {
+	float total = 0.0, amplitude = 1.0;
+	for (int i = 0; i < 4; i++) {
+		total += noise(n) * amplitude;
+		n += n;
+		amplitude *= 0.5;
+	}
+	return total;
+}
+
+void main() {
+
+	vec2 p = vUV * 8.0;
+	float q = fbm(p - iGlobalTime * 0.1);
+	vec2 r = vec2(fbm(p + q + iGlobalTime * speed.x - p.x - p.y), fbm(p + q - iGlobalTime * speed.y));
+	vec3 c = mix(c1, c2, fbm(p + r)) + mix(c3, c4, r.x) - mix(c5, c6, r.y);
+	gl_FragColor = vec4(c * cos(shift * vUV.y), alpha);
+
+}

+ 18 - 0
Babylon/Shaders/procedural.vertex.fx

@@ -0,0 +1,18 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+
+// Attributes
+attribute vec2 position;
+
+// Output
+varying vec2 vPosition;
+varying vec2 vUV;
+
+const vec2 madd = vec2(0.5, 0.5);
+
+void main(void) {	
+	vPosition = position;
+	vUV = position * madd + madd;
+	gl_Position = vec4(position, 0.0, 1.0);
+}

+ 43 - 0
Babylon/Shaders/wood.fragment.fx

@@ -0,0 +1,43 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+
+varying vec2 vPosition;              
+varying vec2 vUV;                    
+
+uniform float ampScale;
+uniform float ringScale;
+uniform vec3 woodColor1;
+uniform vec3 woodColor2;
+
+
+float rand(vec2 n) {
+	return fract(cos(dot(n, vec2(12.9898, 4.1414))) * 43758.5453);
+}
+
+float noise(vec2 n) {
+	const vec2 d = vec2(0.0, 1.0);
+	vec2 b = floor(n), f = smoothstep(vec2(0.0), vec2(1.0), fract(n));
+	return mix(mix(rand(b), rand(b + d.yx), f.x), mix(rand(b + d.xy), rand(b + d.yy), f.x), f.y);
+}
+
+float fbm(vec2 n) {
+	float total = 0.0, amplitude = 1.0;
+	for (int i = 0; i < 4; i++) {
+		total += noise(n) * amplitude;
+		n += n;
+		amplitude *= 0.5;
+	}
+	return total;
+}
+
+void main(void) {
+
+	vec2 positionWood = vPosition;
+	float r = ringScale * sqrt(dot(positionWood.xy, positionWood.xy));
+	r = r + fbm(vPosition);
+	r = r - floor(r);
+	r = smoothstep(0.0, 0.8, r) - smoothstep(0.8, 1.0, r);
+
+	gl_FragColor = vec4(mix(woodColor1, woodColor2, r), 1.0);
+}

+ 15 - 8
Babylon/babylon.engine.js

@@ -320,18 +320,16 @@
         scene._removePendingData(texture);
     };
 
-    // ANY
-    var cascadeLoad = function (rootUrl, index, loadedImages, scene, onfinish, extensions) {
+    var partialLoad = function (url, index, loadedImages, scene, onfinish) {
         var img;
 
         var onload = function () {
-            loadedImages.push(img);
+            loadedImages[index] = img;
+            loadedImages._internalCount++;
 
             scene._removePendingData(img);
 
-            if (index != extensions.length - 1) {
-                cascadeLoad(rootUrl, index + 1, loadedImages, scene, onfinish, extensions);
-            } else {
+            if (loadedImages._internalCount == 6) {
                 onfinish(loadedImages);
             }
         };
@@ -340,10 +338,19 @@
             scene._removePendingData(img);
         };
 
-        img = BABYLON.Tools.LoadImage(rootUrl + extensions[index], onload, onerror, scene.database);
+        img = BABYLON.Tools.LoadImage(url, onload, onerror, scene.database);
         scene._addPendingData(img);
     };
 
+    var cascadeLoad = function (rootUrl, scene, onfinish, extensions) {
+        var loadedImages = [];
+        loadedImages._internalCount = 0;
+
+        for (var index = 0; index < 6; index++) {
+            partialLoad(rootUrl + extensions[index], index, loadedImages, scene, onfinish);
+        }
+    };
+
     var EngineCapabilities = (function () {
         function EngineCapabilities() {
         }
@@ -1461,7 +1468,7 @@
                     texture.isReady = true;
                 }, null, null, true);
             } else {
-                cascadeLoad(rootUrl, 0, [], scene, function (imgs) {
+                cascadeLoad(rootUrl, scene, function (imgs) {
                     var width = BABYLON.Tools.GetExponantOfTwo(imgs[0].width, _this._caps.maxCubemapTextureSize);
                     var height = width;
 

+ 19 - 9
Babylon/babylon.engine.ts

@@ -295,19 +295,18 @@
         scene._removePendingData(texture);
     };
 
-    // ANY
-    var cascadeLoad = (rootUrl: string, index: number, loadedImages: HTMLImageElement[], scene,
-        onfinish: (images: HTMLImageElement[]) => void, extensions: string[]) => {
+    var partialLoad = (url: string, index: number, loadedImages: any, scene,
+        onfinish: (images: HTMLImageElement[]) => void) => {
+
         var img: HTMLImageElement;
 
         var onload = () => {
-            loadedImages.push(img);
+            loadedImages[index] = img;
+            loadedImages._internalCount++;
 
             scene._removePendingData(img);
 
-            if (index != extensions.length - 1) {
-                cascadeLoad(rootUrl, index + 1, loadedImages, scene, onfinish, extensions);
-            } else {
+            if (loadedImages._internalCount == 6) {
                 onfinish(loadedImages);
             }
         };
@@ -316,8 +315,19 @@
             scene._removePendingData(img);
         };
 
-        img = BABYLON.Tools.LoadImage(rootUrl + extensions[index], onload, onerror, scene.database);
+        img = BABYLON.Tools.LoadImage(url, onload, onerror, scene.database);
         scene._addPendingData(img);
+    }
+
+    var cascadeLoad = (rootUrl: string, scene,
+        onfinish: (images: HTMLImageElement[]) => void, extensions: string[]) => {
+
+        var loadedImages:any = [];
+        loadedImages._internalCount = 0;
+
+        for (var index = 0; index < 6; index++) {
+            partialLoad(rootUrl + extensions[index], index, loadedImages, scene, onfinish);
+        }
     };
 
     export class EngineCapabilities {
@@ -1470,7 +1480,7 @@
                     texture.isReady = true;
                 }, null, null, true);
             } else {
-                cascadeLoad(rootUrl, 0, [], scene, imgs => {
+                cascadeLoad(rootUrl, scene, imgs => {
                     var width = Tools.GetExponantOfTwo(imgs[0].width, this._caps.maxCubemapTextureSize);
                     var height = width;
 

+ 13 - 0
Babylon/babylon.scene.js

@@ -54,6 +54,9 @@
             this.importedMeshesFiles = new Array();
             this._actionManagers = new Array();
             this._meshesForIntersections = new BABYLON.SmartArray(256);
+            // Procedural textures
+            this.proceduralTexturesEnabled = true;
+            this._proceduralTextures = new Array();
             this._totalVertices = 0;
             this._activeVertices = 0;
             this._activeParticles = 0;
@@ -1006,6 +1009,16 @@
             }
             this._renderTargetsDuration += new Date().getTime() - beforeRenderTargetDate;
 
+            // Procedural textures
+            if (this.proceduralTexturesEnabled) {
+                for (var proceduralIndex = 0; proceduralIndex < this._proceduralTextures.length; proceduralIndex++) {
+                    var proceduralTexture = this._proceduralTextures[proceduralIndex];
+                    if (proceduralTexture._shouldRender()) {
+                        proceduralTexture.render();
+                    }
+                }
+            }
+
             // Clear
             this._engine.clear(this.clearColor, this.autoClear || this.forceWireframe, true);
 

+ 13 - 0
Babylon/babylon.scene.ts

@@ -111,6 +111,10 @@
         public _actionManagers = new Array<ActionManager>();
         private _meshesForIntersections = new SmartArray<AbstractMesh>(256);
 
+        // Procedural textures
+        public proceduralTexturesEnabled = true;
+        public _proceduralTextures = new Array<ProceduralTexture>();
+
         // Private
         private _engine: Engine;
         private _totalVertices = 0;
@@ -1085,6 +1089,15 @@
             }
             this._renderTargetsDuration += new Date().getTime() - beforeRenderTargetDate;
 
+            // Procedural textures
+            if (this.proceduralTexturesEnabled) {
+                for (var proceduralIndex = 0; proceduralIndex < this._proceduralTextures.length; proceduralIndex++) {
+                    var proceduralTexture = this._proceduralTextures[proceduralIndex];
+                    if (proceduralTexture._shouldRender()) {
+                        proceduralTexture.render();
+                    }
+                }
+            }
 
             // Clear
             this._engine.clear(this.clearColor, this.autoClear || this.forceWireframe, true);

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 26628 - 0
babylon.2.0-alpha.debug.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 17 - 0
babylon.2.0-alpha.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 3753 - 0
babylon.2.0.d.ts