123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436 |
- module BABYLON {
- export class ShaderMaterial extends Material {
- private _shaderPath: any;
- private _options: any;
- private _textures: { [name: string]: Texture } = {};
- private _floats: { [name: string]: number } = {};
- private _floatsArrays: { [name: string]: number[] } = {};
- private _colors3: { [name: string]: Color3 } = {};
- private _colors4: { [name: string]: Color4 } = {};
- private _vectors2: { [name: string]: Vector2 } = {};
- private _vectors3: { [name: string]: Vector3 } = {};
- private _vectors4: { [name: string]: Vector4 } = {};
- private _matrices: { [name: string]: Matrix } = {};
- private _matrices3x3: { [name: string]: Float32Array } = {};
- private _matrices2x2: { [name: string]: Float32Array } = {};
- private _cachedWorldViewMatrix = new Matrix();
- private _renderId: number;
- constructor(name: string, scene: Scene, shaderPath: any, options: any) {
- super(name, scene);
- this._shaderPath = shaderPath;
- options.needAlphaBlending = options.needAlphaBlending || false;
- options.needAlphaTesting = options.needAlphaTesting || false;
- options.attributes = options.attributes || ["position", "normal", "uv"];
- options.uniforms = options.uniforms || ["worldViewProjection"];
- options.samplers = options.samplers || [];
- options.defines = options.defines || [];
- this._options = options;
- }
- public needAlphaBlending(): boolean {
- return this._options.needAlphaBlending;
- }
- public needAlphaTesting(): boolean {
- return this._options.needAlphaTesting;
- }
- private _checkUniform(uniformName): void {
- if (this._options.uniforms.indexOf(uniformName) === -1) {
- this._options.uniforms.push(uniformName);
- }
- }
- public setTexture(name: string, texture: Texture): ShaderMaterial {
- if (this._options.samplers.indexOf(name) === -1) {
- this._options.samplers.push(name);
- }
- this._textures[name] = texture;
- return this;
- }
- public setFloat(name: string, value: number): ShaderMaterial {
- this._checkUniform(name);
- this._floats[name] = value;
- return this;
- }
- public setFloats(name: string, value: number[]): ShaderMaterial {
- this._checkUniform(name);
- this._floatsArrays[name] = value;
- return this;
- }
- public setColor3(name: string, value: Color3): ShaderMaterial {
- this._checkUniform(name);
- this._colors3[name] = value;
- return this;
- }
- public setColor4(name: string, value: Color4): ShaderMaterial {
- this._checkUniform(name);
- this._colors4[name] = value;
- return this;
- }
- public setVector2(name: string, value: Vector2): ShaderMaterial {
- this._checkUniform(name);
- this._vectors2[name] = value;
- return this;
- }
- public setVector3(name: string, value: Vector3): ShaderMaterial {
- this._checkUniform(name);
- this._vectors3[name] = value;
- return this;
- }
- public setVector4(name: string, value: Vector4): ShaderMaterial {
- this._checkUniform(name);
- this._vectors4[name] = value;
- return this;
- }
- public setMatrix(name: string, value: Matrix): ShaderMaterial {
- this._checkUniform(name);
- this._matrices[name] = value;
- return this;
- }
- public setMatrix3x3(name: string, value: Float32Array): ShaderMaterial {
- this._checkUniform(name);
- this._matrices3x3[name] = value;
- return this;
- }
- public setMatrix2x2(name: string, value: Float32Array): ShaderMaterial {
- this._checkUniform(name);
- this._matrices2x2[name] = value;
- return this;
- }
- public isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean {
- var scene = this.getScene();
- var engine = scene.getEngine();
- if (!this.checkReadyOnEveryCall) {
- if (this._renderId === scene.getRenderId()) {
- return true;
- }
- }
- // Instances
- var defines = [];
- var fallbacks = new EffectFallbacks();
- if (useInstances) {
- defines.push("#define INSTANCES");
- }
- for (var index = 0; index < this._options.defines.length; index++) {
- defines.push(this._options.defines[index]);
- }
- // Bones
- if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
- defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
- defines.push("#define BonesPerMesh " + (mesh.skeleton.bones.length + 1));
- fallbacks.addCPUSkinningFallback(0, mesh);
- }
- // Alpha test
- if (engine.getAlphaTesting()) {
- defines.push("#define ALPHATEST");
- }
- var previousEffect = this._effect;
- var join = defines.join("\n");
- this._effect = engine.createEffect(this._shaderPath,
- this._options.attributes,
- this._options.uniforms,
- this._options.samplers,
- join, fallbacks, this.onCompiled, this.onError);
- if (!this._effect.isReady()) {
- return false;
- }
- if (previousEffect !== this._effect) {
- scene.resetCachedMaterial();
- }
- this._renderId = scene.getRenderId();
- return true;
- }
- public bindOnlyWorldMatrix(world: Matrix): void {
- var scene = this.getScene();
- if (this._options.uniforms.indexOf("world") !== -1) {
- this._effect.setMatrix("world", world);
- }
- if (this._options.uniforms.indexOf("worldView") !== -1) {
- world.multiplyToRef(scene.getViewMatrix(), this._cachedWorldViewMatrix);
- this._effect.setMatrix("worldView", this._cachedWorldViewMatrix);
- }
- if (this._options.uniforms.indexOf("worldViewProjection") !== -1) {
- this._effect.setMatrix("worldViewProjection", world.multiply(scene.getTransformMatrix()));
- }
- }
- public bind(world: Matrix, mesh?: Mesh): void {
- // Std values
- this.bindOnlyWorldMatrix(world);
- if (this.getScene().getCachedMaterial() !== this) {
- if (this._options.uniforms.indexOf("view") !== -1) {
- this._effect.setMatrix("view", this.getScene().getViewMatrix());
- }
- if (this._options.uniforms.indexOf("projection") !== -1) {
- this._effect.setMatrix("projection", this.getScene().getProjectionMatrix());
- }
- if (this._options.uniforms.indexOf("viewProjection") !== -1) {
- this._effect.setMatrix("viewProjection", this.getScene().getTransformMatrix());
- }
- // Bones
- if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
- this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
- }
- // 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]);
- }
- // Vector4
- for (name in this._vectors4) {
- this._effect.setVector4(name, this._vectors4[name]);
- }
- // Matrix
- for (name in this._matrices) {
- this._effect.setMatrix(name, this._matrices[name]);
- }
- // Matrix 3x3
- for (name in this._matrices3x3) {
- this._effect.setMatrix3x3(name, this._matrices3x3[name]);
- }
- // Matrix 2x2
- for (name in this._matrices2x2) {
- this._effect.setMatrix2x2(name, this._matrices2x2[name]);
- }
- }
- super.bind(world, mesh);
- }
- public clone(name: string): ShaderMaterial {
- var newShaderMaterial = new ShaderMaterial(name, this.getScene(), this._shaderPath, this._options);
- return newShaderMaterial;
- }
- public dispose(forceDisposeEffect?: boolean, forceDisposeTextures?: boolean): void {
- if (forceDisposeTextures) {
- for (var name in this._textures) {
- this._textures[name].dispose();
- }
- }
- this._textures = {};
- super.dispose(forceDisposeEffect, forceDisposeTextures);
- }
- public serialize(): any {
- var serializationObject = SerializationHelper.Serialize(this);
- serializationObject.customType = "BABYLON.ShaderMaterial";
-
- serializationObject.options = this._options;
- serializationObject.shaderPath = this._shaderPath;
- // Texture
- serializationObject.textures = {};
- for (var name in this._textures) {
- serializationObject.textures[name] = this._textures[name].serialize();
- }
- // Float
- serializationObject.floats = {};
- for (name in this._floats) {
- serializationObject.floats[name] = this._floats[name];
- }
- // Float s
- serializationObject.floatArrays = {};
- for (name in this._floatsArrays) {
- serializationObject.floatArrays[name] = this._floatsArrays[name];
- }
- // Color3
- serializationObject.colors3 = {};
- for (name in this._colors3) {
- serializationObject.colors3[name] = this._colors3[name].asArray();
- }
- // Color4
- serializationObject.colors4 = {};
- for (name in this._colors4) {
- serializationObject.colors4[name] = this._colors4[name].asArray();
- }
- // Vector2
- serializationObject.vectors2 = {};
- for (name in this._vectors2) {
- serializationObject.vectors2[name] = this._vectors2[name].asArray();
- }
- // Vector3
- serializationObject.vectors3 = {};
- for (name in this._vectors3) {
- serializationObject.vectors3[name] = this._vectors3[name].asArray();
- }
- // Vector4
- serializationObject.vectors4 = {};
- for (name in this._vectors4) {
- serializationObject.vectors4[name] = this._vectors4[name].asArray();
- }
- // Matrix
- serializationObject.matrices = {};
- for (name in this._matrices) {
- serializationObject.matrices[name] = this._matrices[name].asArray();
- }
- // Matrix 3x3
- serializationObject.matrices3x3 = {};
- for (name in this._matrices3x3) {
- serializationObject.matrices3x3[name] = this._matrices3x3[name];
- }
- // Matrix 2x2
- serializationObject.matrices2x2 = {};
- for (name in this._matrices2x2) {
- serializationObject.matrices2x2[name] = this._matrices2x2[name];
- }
- return serializationObject;
- }
- public static Parse(source: any, scene: Scene, rootUrl: string): ShaderMaterial {
- var material = SerializationHelper.Parse(() => new ShaderMaterial(source.name, scene, source.shaderPath, source.options), source, scene, rootUrl);
-
- // Texture
- for (var name in source.textures) {
- material.setTexture(name, <Texture>Texture.Parse(source.textures[name], scene, rootUrl));
- }
- // Float
- for (name in source.floats) {
- material.setFloat(name, source.floats[name]);
- }
- // Float s
- for (name in source.floatsArrays) {
- material.setFloats(name, source.floatsArrays[name]);
- }
- // Color3
- for (name in source.colors3) {
- material.setColor3(name, Color3.FromArray(source.colors3[name]));
- }
- // Color4
- for (name in source.colors4) {
- material.setColor4(name, Color4.FromArray(source.colors4[name]));
- }
- // Vector2
- for (name in source.vectors2) {
- material.setVector2(name, Vector2.FromArray(source.vectors2[name]));
- }
- // Vector3
- for (name in source.vectors3) {
- material.setVector3(name, Vector3.FromArray(source.vectors3[name]));
- }
- // Vector4
- for (name in source.vectors4) {
- material.setVector4(name, Vector4.FromArray(source.vectors4[name]));
- }
- // Matrix
- for (name in source.matrices) {
- material.setMatrix(name, Matrix.FromArray(source.matrices[name]));
- }
- // Matrix 3x3
- for (name in source.matrices3x3) {
- material.setMatrix3x3(name, source.matrices3x3[name]);
- }
- // Matrix 2x2
- for (name in source.matrices2x2) {
- material.setMatrix2x2(name, source.matrices2x2[name]);
- }
- return material;
- }
- }
- }
|