|
@@ -0,0 +1,296 @@
|
|
|
+/// <reference path="../../../dist/preview release/babylon.d.ts"/>
|
|
|
+
|
|
|
+module BABYLON {
|
|
|
+ class CellMaterialDefines extends MaterialDefines {
|
|
|
+ public DIFFUSE = false;
|
|
|
+ public CLIPPLANE = false;
|
|
|
+ public ALPHATEST = false;
|
|
|
+ public POINTSIZE = false;
|
|
|
+ public FOG = false;
|
|
|
+ public NORMAL = false;
|
|
|
+ public UV1 = false;
|
|
|
+ public UV2 = false;
|
|
|
+ public VERTEXCOLOR = false;
|
|
|
+ public VERTEXALPHA = false;
|
|
|
+ public NUM_BONE_INFLUENCERS = 0;
|
|
|
+ public BonesPerMesh = 0;
|
|
|
+ public INSTANCES = false;
|
|
|
+ public NDOTL = true;
|
|
|
+ public CUSTOMUSERLIGHTING = true;
|
|
|
+ public CELLBASIC = true;
|
|
|
+
|
|
|
+ constructor() {
|
|
|
+ super();
|
|
|
+ this.rebuild();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ export class CellMaterial extends PushMaterial {
|
|
|
+ @serializeAsTexture("diffuseTexture")
|
|
|
+ private _diffuseTexture: BaseTexture;
|
|
|
+ @expandToProperty("_markAllSubMeshesAsTexturesDirty")
|
|
|
+ public diffuseTexture: BaseTexture;
|
|
|
+
|
|
|
+ @serializeAsColor3("diffuseColor")
|
|
|
+ public diffuseColor = new Color3(1, 1, 1);
|
|
|
+
|
|
|
+ @serialize("computeHighLevel")
|
|
|
+ public _computeHighLevel: boolean = false;
|
|
|
+ @expandToProperty("_markAllSubMeshesAsTexturesDirty")
|
|
|
+ public computeHighLevel: boolean;
|
|
|
+
|
|
|
+ @serialize("disableLighting")
|
|
|
+ private _disableLighting = false;
|
|
|
+ @expandToProperty("_markAllSubMeshesAsLightsDirty")
|
|
|
+ public disableLighting: boolean;
|
|
|
+
|
|
|
+ @serialize("maxSimultaneousLights")
|
|
|
+ private _maxSimultaneousLights = 4;
|
|
|
+ @expandToProperty("_markAllSubMeshesAsLightsDirty")
|
|
|
+ public maxSimultaneousLights: number;
|
|
|
+
|
|
|
+ private _worldViewProjectionMatrix = Matrix.Zero();
|
|
|
+ private _scaledDiffuse = new Color3();
|
|
|
+ private _renderId: number;
|
|
|
+
|
|
|
+ constructor(name: string, scene: Scene) {
|
|
|
+ super(name, scene);
|
|
|
+ }
|
|
|
+
|
|
|
+ public needAlphaBlending(): boolean {
|
|
|
+ return (this.alpha < 1.0);
|
|
|
+ }
|
|
|
+
|
|
|
+ public needAlphaTesting(): boolean {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ public getAlphaTestTexture(): BaseTexture {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Methods
|
|
|
+ public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
|
|
|
+ if (this.isFrozen) {
|
|
|
+ if (this._wasPreviouslyReady && subMesh.effect) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!subMesh._materialDefines) {
|
|
|
+ subMesh._materialDefines = new CellMaterialDefines();
|
|
|
+ }
|
|
|
+
|
|
|
+ var defines = <CellMaterialDefines>subMesh._materialDefines;
|
|
|
+ var scene = this.getScene();
|
|
|
+
|
|
|
+ if (!this.checkReadyOnEveryCall && subMesh.effect) {
|
|
|
+ if (this._renderId === scene.getRenderId()) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ var engine = scene.getEngine();
|
|
|
+
|
|
|
+ // Textures
|
|
|
+ if (defines._areTexturesDirty) {
|
|
|
+ defines._needUVs = false;
|
|
|
+ if (scene.texturesEnabled) {
|
|
|
+ if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
|
|
|
+ if (!this._diffuseTexture.isReady()) {
|
|
|
+ return false;
|
|
|
+ } else {
|
|
|
+ defines._needUVs = true;
|
|
|
+ defines.DIFFUSE = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // High level
|
|
|
+ defines.CELLBASIC = !this.computeHighLevel;
|
|
|
+
|
|
|
+ // Misc.
|
|
|
+ MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
|
|
|
+
|
|
|
+ // Lights
|
|
|
+ defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
|
|
|
+
|
|
|
+ // Values that need to be evaluated on every frame
|
|
|
+ MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
|
|
|
+
|
|
|
+ // Attribs
|
|
|
+ MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
|
|
|
+
|
|
|
+ // Get correct effect
|
|
|
+ if (defines.isDirty) {
|
|
|
+ defines.markAsProcessed();
|
|
|
+ scene.resetCachedMaterial();
|
|
|
+
|
|
|
+ // Fallbacks
|
|
|
+ var fallbacks = new EffectFallbacks();
|
|
|
+ if (defines.FOG) {
|
|
|
+ fallbacks.addFallback(1, "FOG");
|
|
|
+ }
|
|
|
+
|
|
|
+ MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
|
|
|
+
|
|
|
+ if (defines.NUM_BONE_INFLUENCERS > 0) {
|
|
|
+ fallbacks.addCPUSkinningFallback(0, mesh);
|
|
|
+ }
|
|
|
+
|
|
|
+ //Attributes
|
|
|
+ var attribs = [VertexBuffer.PositionKind];
|
|
|
+
|
|
|
+ if (defines.NORMAL) {
|
|
|
+ attribs.push(VertexBuffer.NormalKind);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (defines.UV1) {
|
|
|
+ attribs.push(VertexBuffer.UVKind);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (defines.UV2) {
|
|
|
+ attribs.push(VertexBuffer.UV2Kind);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (defines.VERTEXCOLOR) {
|
|
|
+ attribs.push(VertexBuffer.ColorKind);
|
|
|
+ }
|
|
|
+
|
|
|
+ MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
|
|
|
+ MaterialHelper.PrepareAttributesForInstances(attribs, defines);
|
|
|
+
|
|
|
+ var shaderName = "cell";
|
|
|
+ var join = defines.toString();
|
|
|
+ var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
|
|
|
+ "vFogInfos", "vFogColor", "pointSize",
|
|
|
+ "vDiffuseInfos",
|
|
|
+ "mBones",
|
|
|
+ "vClipPlane", "diffuseMatrix", "depthValues"
|
|
|
+ ];
|
|
|
+ var samplers = ["diffuseSampler"];
|
|
|
+ var uniformBuffers = [];
|
|
|
+
|
|
|
+ MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
|
|
|
+ uniformsNames: uniforms,
|
|
|
+ uniformBuffersNames: uniformBuffers,
|
|
|
+ samplers: samplers,
|
|
|
+ defines: defines,
|
|
|
+ maxSimultaneousLights: this.maxSimultaneousLights
|
|
|
+ });
|
|
|
+ subMesh.setEffect(scene.getEngine().createEffect(shaderName,
|
|
|
+ <EffectCreationOptions>{
|
|
|
+ attributes: attribs,
|
|
|
+ uniformsNames: uniforms,
|
|
|
+ uniformBuffersNames: uniformBuffers,
|
|
|
+ samplers: samplers,
|
|
|
+ defines: join,
|
|
|
+ fallbacks: fallbacks,
|
|
|
+ onCompiled: this.onCompiled,
|
|
|
+ onError: this.onError,
|
|
|
+ indexParameters: { maxSimultaneousLights: this.maxSimultaneousLights - 1 }
|
|
|
+ }, engine), defines);
|
|
|
+
|
|
|
+ }
|
|
|
+ if (!subMesh.effect.isReady()) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ this._renderId = scene.getRenderId();
|
|
|
+ this._wasPreviouslyReady = true;
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
|
|
|
+ var scene = this.getScene();
|
|
|
+
|
|
|
+ var defines = <CellMaterialDefines>subMesh._materialDefines;
|
|
|
+ if (!defines) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ var effect = subMesh.effect;
|
|
|
+ this._activeEffect = effect;
|
|
|
+
|
|
|
+ // Matrices
|
|
|
+ this.bindOnlyWorldMatrix(world);
|
|
|
+ this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
|
|
|
+
|
|
|
+ // Bones
|
|
|
+ MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
|
|
|
+
|
|
|
+ if (this._mustRebind(scene, effect)) {
|
|
|
+ // Textures
|
|
|
+ if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
|
|
|
+ this._activeEffect.setTexture("diffuseSampler", this._diffuseTexture);
|
|
|
+
|
|
|
+ this._activeEffect.setFloat2("vDiffuseInfos", this._diffuseTexture.coordinatesIndex, this._diffuseTexture.level);
|
|
|
+ this._activeEffect.setMatrix("diffuseMatrix", this._diffuseTexture.getTextureMatrix());
|
|
|
+ }
|
|
|
+
|
|
|
+ // Clip plane
|
|
|
+ MaterialHelper.BindClipPlane(this._activeEffect, scene);
|
|
|
+
|
|
|
+ // Point size
|
|
|
+ if (this.pointsCloud) {
|
|
|
+ this._activeEffect.setFloat("pointSize", this.pointSize);
|
|
|
+ }
|
|
|
+
|
|
|
+ this._activeEffect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);
|
|
|
+ }
|
|
|
+
|
|
|
+ this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
|
|
|
+
|
|
|
+ // Lights
|
|
|
+ if (scene.lightsEnabled && !this.disableLighting) {
|
|
|
+ MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, this._maxSimultaneousLights);
|
|
|
+ }
|
|
|
+
|
|
|
+ // View
|
|
|
+ if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
|
|
|
+ this._activeEffect.setMatrix("view", scene.getViewMatrix());
|
|
|
+ }
|
|
|
+
|
|
|
+ // Fog
|
|
|
+ MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
|
|
|
+
|
|
|
+ this._afterBind(mesh, this._activeEffect);
|
|
|
+ }
|
|
|
+
|
|
|
+ public getAnimatables(): IAnimatable[] {
|
|
|
+ var results = [];
|
|
|
+
|
|
|
+ if (this._diffuseTexture && this._diffuseTexture.animations && this._diffuseTexture.animations.length > 0) {
|
|
|
+ results.push(this._diffuseTexture);
|
|
|
+ }
|
|
|
+
|
|
|
+ return results;
|
|
|
+ }
|
|
|
+
|
|
|
+ public dispose(forceDisposeEffect?: boolean): void {
|
|
|
+ if (this._diffuseTexture) {
|
|
|
+ this._diffuseTexture.dispose();
|
|
|
+ }
|
|
|
+
|
|
|
+ super.dispose(forceDisposeEffect);
|
|
|
+ }
|
|
|
+
|
|
|
+ public clone(name: string): CellMaterial {
|
|
|
+ return SerializationHelper.Clone<CellMaterial>(() => new CellMaterial(name, this.getScene()), this);
|
|
|
+ }
|
|
|
+
|
|
|
+ public serialize(): any {
|
|
|
+ var serializationObject = SerializationHelper.Serialize(this);
|
|
|
+ serializationObject.customType = "BABYLON.CellMaterial";
|
|
|
+ return serializationObject;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Statics
|
|
|
+ public static Parse(source: any, scene: Scene, rootUrl: string): CellMaterial {
|
|
|
+ return SerializationHelper.Parse(() => new CellMaterial(source.name, scene), source, scene, rootUrl);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|