glowLayer.ts 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632
  1. import { serialize, SerializationHelper } from "../Misc/decorators";
  2. import { Nullable } from "../types";
  3. import { Camera } from "../Cameras/camera";
  4. import { Scene } from "../scene";
  5. import { Vector2 } from "../Maths/math.vector";
  6. import { VertexBuffer } from "../Meshes/buffer";
  7. import { SubMesh } from "../Meshes/subMesh";
  8. import { AbstractMesh } from "../Meshes/abstractMesh";
  9. import { Mesh } from "../Meshes/mesh";
  10. import { Texture } from "../Materials/Textures/texture";
  11. import { RenderTargetTexture } from "../Materials/Textures/renderTargetTexture";
  12. import { Effect } from "../Materials/effect";
  13. import { Material } from "../Materials/material";
  14. import { PostProcess } from "../PostProcesses/postProcess";
  15. import { BlurPostProcess } from "../PostProcesses/blurPostProcess";
  16. import { EffectLayer } from "./effectLayer";
  17. import { AbstractScene } from "../abstractScene";
  18. import { Constants } from "../Engines/constants";
  19. import { _TypeStore } from '../Misc/typeStore';
  20. import { Engine } from '../Engines/engine';
  21. import { Color4 } from '../Maths/math.color';
  22. import "../Shaders/glowMapMerge.fragment";
  23. import "../Shaders/glowMapMerge.vertex";
  24. import "../Layers/effectLayerSceneComponent";
  25. declare module "../abstractScene" {
  26. export interface AbstractScene {
  27. /**
  28. * Return a the first highlight layer of the scene with a given name.
  29. * @param name The name of the highlight layer to look for.
  30. * @return The highlight layer if found otherwise null.
  31. */
  32. getGlowLayerByName(name: string): Nullable<GlowLayer>;
  33. }
  34. }
  35. AbstractScene.prototype.getGlowLayerByName = function(name: string): Nullable<GlowLayer> {
  36. for (var index = 0; index < this.effectLayers.length; index++) {
  37. if (this.effectLayers[index].name === name && this.effectLayers[index].getEffectName() === GlowLayer.EffectName) {
  38. return (<any>this.effectLayers[index]) as GlowLayer;
  39. }
  40. }
  41. return null;
  42. };
  43. /**
  44. * Glow layer options. This helps customizing the behaviour
  45. * of the glow layer.
  46. */
  47. export interface IGlowLayerOptions {
  48. /**
  49. * Multiplication factor apply to the canvas size to compute the render target size
  50. * used to generated the glowing objects (the smaller the faster).
  51. */
  52. mainTextureRatio: number;
  53. /**
  54. * Enforces a fixed size texture to ensure resize independant blur.
  55. */
  56. mainTextureFixedSize?: number;
  57. /**
  58. * How big is the kernel of the blur texture.
  59. */
  60. blurKernelSize: number;
  61. /**
  62. * The camera attached to the layer.
  63. */
  64. camera: Nullable<Camera>;
  65. /**
  66. * Enable MSAA by chosing the number of samples.
  67. */
  68. mainTextureSamples?: number;
  69. /**
  70. * The rendering group to draw the layer in.
  71. */
  72. renderingGroupId: number;
  73. }
  74. /**
  75. * The glow layer Helps adding a glow effect around the emissive parts of a mesh.
  76. *
  77. * Once instantiated in a scene, by default, all the emissive meshes will glow.
  78. *
  79. * Documentation: https://doc.babylonjs.com/how_to/glow_layer
  80. */
  81. export class GlowLayer extends EffectLayer {
  82. /**
  83. * Effect Name of the layer.
  84. */
  85. public static readonly EffectName = "GlowLayer";
  86. /**
  87. * The default blur kernel size used for the glow.
  88. */
  89. public static DefaultBlurKernelSize = 32;
  90. /**
  91. * The default texture size ratio used for the glow.
  92. */
  93. public static DefaultTextureRatio = 0.5;
  94. /**
  95. * Sets the kernel size of the blur.
  96. */
  97. public set blurKernelSize(value: number) {
  98. this._horizontalBlurPostprocess1.kernel = value;
  99. this._verticalBlurPostprocess1.kernel = value;
  100. this._horizontalBlurPostprocess2.kernel = value;
  101. this._verticalBlurPostprocess2.kernel = value;
  102. }
  103. /**
  104. * Gets the kernel size of the blur.
  105. */
  106. @serialize()
  107. public get blurKernelSize(): number {
  108. return this._horizontalBlurPostprocess1.kernel;
  109. }
  110. /**
  111. * Sets the glow intensity.
  112. */
  113. public set intensity(value: number) {
  114. this._intensity = value;
  115. }
  116. /**
  117. * Gets the glow intensity.
  118. */
  119. @serialize()
  120. public get intensity(): number {
  121. return this._intensity;
  122. }
  123. @serialize("options")
  124. private _options: IGlowLayerOptions;
  125. private _intensity: number = 1.0;
  126. private _horizontalBlurPostprocess1: BlurPostProcess;
  127. private _verticalBlurPostprocess1: BlurPostProcess;
  128. private _horizontalBlurPostprocess2: BlurPostProcess;
  129. private _verticalBlurPostprocess2: BlurPostProcess;
  130. private _blurTexture1: RenderTargetTexture;
  131. private _blurTexture2: RenderTargetTexture;
  132. private _postProcesses1: PostProcess[];
  133. private _postProcesses2: PostProcess[];
  134. private _includedOnlyMeshes: number[] = [];
  135. private _excludedMeshes: number[] = [];
  136. private _meshesUsingTheirOwnMaterials: number[] = [];
  137. /**
  138. * Callback used to let the user override the color selection on a per mesh basis
  139. */
  140. public customEmissiveColorSelector: (mesh: Mesh, subMesh: SubMesh, material: Material, result: Color4) => void;
  141. /**
  142. * Callback used to let the user override the texture selection on a per mesh basis
  143. */
  144. public customEmissiveTextureSelector: (mesh: Mesh, subMesh: SubMesh, material: Material) => Texture;
  145. /**
  146. * Instantiates a new glow Layer and references it to the scene.
  147. * @param name The name of the layer
  148. * @param scene The scene to use the layer in
  149. * @param options Sets of none mandatory options to use with the layer (see IGlowLayerOptions for more information)
  150. */
  151. constructor(name: string, scene: Scene, options?: Partial<IGlowLayerOptions>) {
  152. super(name, scene);
  153. this.neutralColor = new Color4(0, 0, 0, 1);
  154. // Adapt options
  155. this._options = {
  156. mainTextureRatio: GlowLayer.DefaultTextureRatio,
  157. blurKernelSize: 32,
  158. mainTextureFixedSize: undefined,
  159. camera: null,
  160. mainTextureSamples: 1,
  161. renderingGroupId: -1,
  162. ...options,
  163. };
  164. // Initialize the layer
  165. this._init({
  166. alphaBlendingMode: Constants.ALPHA_ADD,
  167. camera: this._options.camera,
  168. mainTextureFixedSize: this._options.mainTextureFixedSize,
  169. mainTextureRatio: this._options.mainTextureRatio,
  170. renderingGroupId: this._options.renderingGroupId
  171. });
  172. }
  173. /**
  174. * Get the effect name of the layer.
  175. * @return The effect name
  176. */
  177. public getEffectName(): string {
  178. return GlowLayer.EffectName;
  179. }
  180. /**
  181. * Create the merge effect. This is the shader use to blit the information back
  182. * to the main canvas at the end of the scene rendering.
  183. */
  184. protected _createMergeEffect(): Effect {
  185. // Effect
  186. return this._engine.createEffect("glowMapMerge",
  187. [VertexBuffer.PositionKind],
  188. ["offset"],
  189. ["textureSampler", "textureSampler2"],
  190. "#define EMISSIVE \n");
  191. }
  192. /**
  193. * Creates the render target textures and post processes used in the glow layer.
  194. */
  195. protected _createTextureAndPostProcesses(): void {
  196. var blurTextureWidth = this._mainTextureDesiredSize.width;
  197. var blurTextureHeight = this._mainTextureDesiredSize.height;
  198. blurTextureWidth = this._engine.needPOTTextures ? Engine.GetExponentOfTwo(blurTextureWidth, this._maxSize) : blurTextureWidth;
  199. blurTextureHeight = this._engine.needPOTTextures ? Engine.GetExponentOfTwo(blurTextureHeight, this._maxSize) : blurTextureHeight;
  200. var textureType = 0;
  201. if (this._engine.getCaps().textureHalfFloatRender) {
  202. textureType = Constants.TEXTURETYPE_HALF_FLOAT;
  203. }
  204. else {
  205. textureType = Constants.TEXTURETYPE_UNSIGNED_INT;
  206. }
  207. this._blurTexture1 = new RenderTargetTexture("GlowLayerBlurRTT",
  208. {
  209. width: blurTextureWidth,
  210. height: blurTextureHeight
  211. },
  212. this._scene,
  213. false,
  214. true,
  215. textureType);
  216. this._blurTexture1.wrapU = Texture.CLAMP_ADDRESSMODE;
  217. this._blurTexture1.wrapV = Texture.CLAMP_ADDRESSMODE;
  218. this._blurTexture1.updateSamplingMode(Texture.BILINEAR_SAMPLINGMODE);
  219. this._blurTexture1.renderParticles = false;
  220. this._blurTexture1.ignoreCameraViewport = true;
  221. var blurTextureWidth2 = Math.floor(blurTextureWidth / 2);
  222. var blurTextureHeight2 = Math.floor(blurTextureHeight / 2);
  223. this._blurTexture2 = new RenderTargetTexture("GlowLayerBlurRTT2",
  224. {
  225. width: blurTextureWidth2,
  226. height: blurTextureHeight2
  227. },
  228. this._scene,
  229. false,
  230. true,
  231. textureType);
  232. this._blurTexture2.wrapU = Texture.CLAMP_ADDRESSMODE;
  233. this._blurTexture2.wrapV = Texture.CLAMP_ADDRESSMODE;
  234. this._blurTexture2.updateSamplingMode(Texture.BILINEAR_SAMPLINGMODE);
  235. this._blurTexture2.renderParticles = false;
  236. this._blurTexture2.ignoreCameraViewport = true;
  237. this._textures = [this._blurTexture1, this._blurTexture2];
  238. this._horizontalBlurPostprocess1 = new BlurPostProcess("GlowLayerHBP1", new Vector2(1.0, 0), this._options.blurKernelSize / 2, {
  239. width: blurTextureWidth,
  240. height: blurTextureHeight
  241. },
  242. null, Texture.BILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, textureType);
  243. this._horizontalBlurPostprocess1.width = blurTextureWidth;
  244. this._horizontalBlurPostprocess1.height = blurTextureHeight;
  245. this._horizontalBlurPostprocess1.onApplyObservable.add((effect) => {
  246. effect.setTexture("textureSampler", this._mainTexture);
  247. });
  248. this._verticalBlurPostprocess1 = new BlurPostProcess("GlowLayerVBP1", new Vector2(0, 1.0), this._options.blurKernelSize / 2, {
  249. width: blurTextureWidth,
  250. height: blurTextureHeight
  251. },
  252. null, Texture.BILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, textureType);
  253. this._horizontalBlurPostprocess2 = new BlurPostProcess("GlowLayerHBP2", new Vector2(1.0, 0), this._options.blurKernelSize / 2, {
  254. width: blurTextureWidth2,
  255. height: blurTextureHeight2
  256. },
  257. null, Texture.BILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, textureType);
  258. this._horizontalBlurPostprocess2.width = blurTextureWidth2;
  259. this._horizontalBlurPostprocess2.height = blurTextureHeight2;
  260. this._horizontalBlurPostprocess2.onApplyObservable.add((effect) => {
  261. effect.setTexture("textureSampler", this._blurTexture1);
  262. });
  263. this._verticalBlurPostprocess2 = new BlurPostProcess("GlowLayerVBP2", new Vector2(0, 1.0), this._options.blurKernelSize / 2, {
  264. width: blurTextureWidth2,
  265. height: blurTextureHeight2
  266. },
  267. null, Texture.BILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, textureType);
  268. this._postProcesses = [this._horizontalBlurPostprocess1, this._verticalBlurPostprocess1, this._horizontalBlurPostprocess2, this._verticalBlurPostprocess2];
  269. this._postProcesses1 = [this._horizontalBlurPostprocess1, this._verticalBlurPostprocess1];
  270. this._postProcesses2 = [this._horizontalBlurPostprocess2, this._verticalBlurPostprocess2];
  271. this._mainTexture.samples = this._options.mainTextureSamples!;
  272. this._mainTexture.onAfterUnbindObservable.add(() => {
  273. let internalTexture = this._blurTexture1.getInternalTexture();
  274. if (internalTexture) {
  275. this._scene.postProcessManager.directRender(
  276. this._postProcesses1,
  277. internalTexture,
  278. true);
  279. internalTexture = this._blurTexture2.getInternalTexture();
  280. if (internalTexture) {
  281. this._scene.postProcessManager.directRender(
  282. this._postProcesses2,
  283. internalTexture,
  284. true);
  285. }
  286. }
  287. });
  288. // Prevent autoClear.
  289. this._postProcesses.map((pp) => { pp.autoClear = false; });
  290. }
  291. /**
  292. * Checks for the readiness of the element composing the layer.
  293. * @param subMesh the mesh to check for
  294. * @param useInstances specify wether or not to use instances to render the mesh
  295. * @param emissiveTexture the associated emissive texture used to generate the glow
  296. * @return true if ready otherwise, false
  297. */
  298. public isReady(subMesh: SubMesh, useInstances: boolean): boolean {
  299. let material = subMesh.getMaterial();
  300. let mesh = subMesh.getRenderingMesh();
  301. if (!material || !mesh) {
  302. return false;
  303. }
  304. let emissiveTexture = (<any>material).emissiveTexture;
  305. return super._isReady(subMesh, useInstances, emissiveTexture);
  306. }
  307. /**
  308. * Returns whether or nood the layer needs stencil enabled during the mesh rendering.
  309. */
  310. public needStencil(): boolean {
  311. return false;
  312. }
  313. /**
  314. * Returns true if the mesh can be rendered, otherwise false.
  315. * @param mesh The mesh to render
  316. * @param material The material used on the mesh
  317. * @returns true if it can be rendered otherwise false
  318. */
  319. protected _canRenderMesh(mesh: AbstractMesh, material: Material): boolean {
  320. return true;
  321. }
  322. /**
  323. * Implementation specific of rendering the generating effect on the main canvas.
  324. * @param effect The effect used to render through
  325. */
  326. protected _internalRender(effect: Effect): void {
  327. // Texture
  328. effect.setTexture("textureSampler", this._blurTexture1);
  329. effect.setTexture("textureSampler2", this._blurTexture2);
  330. effect.setFloat("offset", this._intensity);
  331. // Cache
  332. var engine = this._engine;
  333. var previousStencilBuffer = engine.getStencilBuffer();
  334. // Draw order
  335. engine.setStencilBuffer(false);
  336. engine.drawElementsType(Material.TriangleFillMode, 0, 6);
  337. // Draw order
  338. engine.setStencilBuffer(previousStencilBuffer);
  339. }
  340. /**
  341. * Sets the required values for both the emissive texture and and the main color.
  342. */
  343. protected _setEmissiveTextureAndColor(mesh: Mesh, subMesh: SubMesh, material: Material): void {
  344. var textureLevel = 1.0;
  345. if (this.customEmissiveTextureSelector) {
  346. this._emissiveTextureAndColor.texture = this.customEmissiveTextureSelector(mesh, subMesh, material);
  347. } else {
  348. if (material) {
  349. this._emissiveTextureAndColor.texture = (<any>material).emissiveTexture;
  350. if (this._emissiveTextureAndColor.texture) {
  351. textureLevel = this._emissiveTextureAndColor.texture.level;
  352. }
  353. }
  354. else {
  355. this._emissiveTextureAndColor.texture = null;
  356. }
  357. }
  358. if (this.customEmissiveColorSelector) {
  359. this.customEmissiveColorSelector(mesh, subMesh, material, this._emissiveTextureAndColor.color);
  360. } else {
  361. if ((<any>material).emissiveColor) {
  362. this._emissiveTextureAndColor.color.set(
  363. (<any>material).emissiveColor.r * textureLevel,
  364. (<any>material).emissiveColor.g * textureLevel,
  365. (<any>material).emissiveColor.b * textureLevel,
  366. material.alpha);
  367. }
  368. else {
  369. this._emissiveTextureAndColor.color.set(
  370. this.neutralColor.r,
  371. this.neutralColor.g,
  372. this.neutralColor.b,
  373. this.neutralColor.a);
  374. }
  375. }
  376. }
  377. /**
  378. * Returns true if the mesh should render, otherwise false.
  379. * @param mesh The mesh to render
  380. * @returns true if it should render otherwise false
  381. */
  382. protected _shouldRenderMesh(mesh: Mesh): boolean {
  383. return this.hasMesh(mesh);
  384. }
  385. /**
  386. * Adds specific effects defines.
  387. * @param defines The defines to add specifics to.
  388. */
  389. protected _addCustomEffectDefines(defines: string[]): void {
  390. defines.push("#define GLOW");
  391. }
  392. /**
  393. * Add a mesh in the exclusion list to prevent it to impact or being impacted by the glow layer.
  394. * @param mesh The mesh to exclude from the glow layer
  395. */
  396. public addExcludedMesh(mesh: Mesh): void {
  397. if (this._excludedMeshes.indexOf(mesh.uniqueId) === -1) {
  398. this._excludedMeshes.push(mesh.uniqueId);
  399. }
  400. }
  401. /**
  402. * Remove a mesh from the exclusion list to let it impact or being impacted by the glow layer.
  403. * @param mesh The mesh to remove
  404. */
  405. public removeExcludedMesh(mesh: Mesh): void {
  406. var index = this._excludedMeshes.indexOf(mesh.uniqueId);
  407. if (index !== -1) {
  408. this._excludedMeshes.splice(index, 1);
  409. }
  410. }
  411. /**
  412. * Add a mesh in the inclusion list to impact or being impacted by the glow layer.
  413. * @param mesh The mesh to include in the glow layer
  414. */
  415. public addIncludedOnlyMesh(mesh: Mesh): void {
  416. if (this._includedOnlyMeshes.indexOf(mesh.uniqueId) === -1) {
  417. this._includedOnlyMeshes.push(mesh.uniqueId);
  418. }
  419. }
  420. /**
  421. * Remove a mesh from the Inclusion list to prevent it to impact or being impacted by the glow layer.
  422. * @param mesh The mesh to remove
  423. */
  424. public removeIncludedOnlyMesh(mesh: Mesh): void {
  425. var index = this._includedOnlyMeshes.indexOf(mesh.uniqueId);
  426. if (index !== -1) {
  427. this._includedOnlyMeshes.splice(index, 1);
  428. }
  429. }
  430. /**
  431. * Determine if a given mesh will be used in the glow layer
  432. * @param mesh The mesh to test
  433. * @returns true if the mesh will be highlighted by the current glow layer
  434. */
  435. public hasMesh(mesh: AbstractMesh): boolean {
  436. if (!super.hasMesh(mesh)) {
  437. return false;
  438. }
  439. // Included Mesh
  440. if (this._includedOnlyMeshes.length) {
  441. return this._includedOnlyMeshes.indexOf(mesh.uniqueId) !== -1;
  442. }
  443. // Excluded Mesh
  444. if (this._excludedMeshes.length) {
  445. return this._excludedMeshes.indexOf(mesh.uniqueId) === -1;
  446. }
  447. return true;
  448. }
  449. /**
  450. * Defines whether the current material of the mesh should be use to render the effect.
  451. * @param mesh defines the current mesh to render
  452. */
  453. protected _useMeshMaterial(mesh: AbstractMesh): boolean {
  454. if (this._meshesUsingTheirOwnMaterials.length == 0) {
  455. return false;
  456. }
  457. return this._meshesUsingTheirOwnMaterials.indexOf(mesh.uniqueId) > -1;
  458. }
  459. /**
  460. * Add a mesh to be rendered through its own material and not with emissive only.
  461. * @param mesh The mesh for which we need to use its material
  462. */
  463. public referenceMeshToUseItsOwnMaterial(mesh: AbstractMesh): void {
  464. this._meshesUsingTheirOwnMaterials.push(mesh.uniqueId);
  465. }
  466. /**
  467. * Remove a mesh from being rendered through its own material and not with emissive only.
  468. * @param mesh The mesh for which we need to not use its material
  469. */
  470. public unReferenceMeshFromUsingItsOwnMaterial(mesh: AbstractMesh): void {
  471. let index = this._meshesUsingTheirOwnMaterials.indexOf(mesh.uniqueId);
  472. while (index >= 0) {
  473. this._meshesUsingTheirOwnMaterials.splice(index, 1);
  474. index = this._meshesUsingTheirOwnMaterials.indexOf(mesh.uniqueId);
  475. }
  476. }
  477. /**
  478. * Free any resources and references associated to a mesh.
  479. * Internal use
  480. * @param mesh The mesh to free.
  481. * @hidden
  482. */
  483. public _disposeMesh(mesh: Mesh): void {
  484. this.removeIncludedOnlyMesh(mesh);
  485. this.removeExcludedMesh(mesh);
  486. }
  487. /**
  488. * Gets the class name of the effect layer
  489. * @returns the string with the class name of the effect layer
  490. */
  491. public getClassName(): string {
  492. return "GlowLayer";
  493. }
  494. /**
  495. * Serializes this glow layer
  496. * @returns a serialized glow layer object
  497. */
  498. public serialize(): any {
  499. var serializationObject = SerializationHelper.Serialize(this);
  500. serializationObject.customType = "BABYLON.GlowLayer";
  501. var index;
  502. // Included meshes
  503. serializationObject.includedMeshes = [];
  504. if (this._includedOnlyMeshes.length) {
  505. for (index = 0; index < this._includedOnlyMeshes.length; index++) {
  506. var mesh = this._scene.getMeshByUniqueID(this._includedOnlyMeshes[index]);
  507. if (mesh) {
  508. serializationObject.includedMeshes.push(mesh.id);
  509. }
  510. }
  511. }
  512. // Excluded meshes
  513. serializationObject.excludedMeshes = [];
  514. if (this._excludedMeshes.length) {
  515. for (index = 0; index < this._excludedMeshes.length; index++) {
  516. var mesh = this._scene.getMeshByUniqueID(this._excludedMeshes[index]);
  517. if (mesh) {
  518. serializationObject.excludedMeshes.push(mesh.id);
  519. }
  520. }
  521. }
  522. return serializationObject;
  523. }
  524. /**
  525. * Creates a Glow Layer from parsed glow layer data
  526. * @param parsedGlowLayer defines glow layer data
  527. * @param scene defines the current scene
  528. * @param rootUrl defines the root URL containing the glow layer information
  529. * @returns a parsed Glow Layer
  530. */
  531. public static Parse(parsedGlowLayer: any, scene: Scene, rootUrl: string): GlowLayer {
  532. var gl = SerializationHelper.Parse(() => new GlowLayer(parsedGlowLayer.name, scene, parsedGlowLayer.options), parsedGlowLayer, scene, rootUrl);
  533. var index;
  534. // Excluded meshes
  535. for (index = 0; index < parsedGlowLayer.excludedMeshes.length; index++) {
  536. var mesh = scene.getMeshByID(parsedGlowLayer.excludedMeshes[index]);
  537. if (mesh) {
  538. gl.addExcludedMesh(<Mesh>mesh);
  539. }
  540. }
  541. // Included meshes
  542. for (index = 0; index < parsedGlowLayer.includedMeshes.length; index++) {
  543. var mesh = scene.getMeshByID(parsedGlowLayer.includedMeshes[index]);
  544. if (mesh) {
  545. gl.addIncludedOnlyMesh(<Mesh>mesh);
  546. }
  547. }
  548. return gl;
  549. }
  550. }
  551. _TypeStore.RegisteredTypes["BABYLON.GlowLayer"] = GlowLayer;