babylon.waterMaterial.ts 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675
  1. /// <reference path="../../../dist/preview release/babylon.d.ts"/>
  2. module BABYLON {
  3. class WaterMaterialDefines extends MaterialDefines {
  4. public BUMP = false;
  5. public REFLECTION = false;
  6. public CLIPPLANE = false;
  7. public CLIPPLANE2 = false;
  8. public CLIPPLANE3 = false;
  9. public CLIPPLANE4 = false;
  10. public ALPHATEST = false;
  11. public DEPTHPREPASS = false;
  12. public POINTSIZE = false;
  13. public FOG = false;
  14. public NORMAL = false;
  15. public UV1 = false;
  16. public UV2 = false;
  17. public VERTEXCOLOR = false;
  18. public VERTEXALPHA = false;
  19. public NUM_BONE_INFLUENCERS = 0;
  20. public BonesPerMesh = 0;
  21. public INSTANCES = false;
  22. public SPECULARTERM = false;
  23. public LOGARITHMICDEPTH = false;
  24. public FRESNELSEPARATE = false;
  25. public BUMPSUPERIMPOSE = false;
  26. public BUMPAFFECTSREFLECTION = false;
  27. constructor() {
  28. super();
  29. this.rebuild();
  30. }
  31. }
  32. export class WaterMaterial extends PushMaterial {
  33. /*
  34. * Public members
  35. */
  36. @serializeAsTexture("bumpTexture")
  37. private _bumpTexture: BaseTexture;
  38. @expandToProperty("_markAllSubMeshesAsTexturesDirty")
  39. public bumpTexture: BaseTexture;
  40. @serializeAsColor3()
  41. public diffuseColor = new Color3(1, 1, 1);
  42. @serializeAsColor3()
  43. public specularColor = new Color3(0, 0, 0);
  44. @serialize()
  45. public specularPower = 64;
  46. @serialize("disableLighting")
  47. private _disableLighting = false;
  48. @expandToProperty("_markAllSubMeshesAsLightsDirty")
  49. public disableLighting: boolean;
  50. @serialize("maxSimultaneousLights")
  51. private _maxSimultaneousLights = 4;
  52. @expandToProperty("_markAllSubMeshesAsLightsDirty")
  53. public maxSimultaneousLights: number;
  54. /**
  55. * @param {number}: Represents the wind force
  56. */
  57. @serialize()
  58. public windForce: number = 6;
  59. /**
  60. * @param {Vector2}: The direction of the wind in the plane (X, Z)
  61. */
  62. @serializeAsVector2()
  63. public windDirection: Vector2 = new Vector2(0, 1);
  64. /**
  65. * @param {number}: Wave height, represents the height of the waves
  66. */
  67. @serialize()
  68. public waveHeight: number = 0.4;
  69. /**
  70. * @param {number}: Bump height, represents the bump height related to the bump map
  71. */
  72. @serialize()
  73. public bumpHeight: number = 0.4;
  74. /**
  75. * @param {boolean}: Add a smaller moving bump to less steady waves.
  76. */
  77. @serialize("bumpSuperimpose")
  78. private _bumpSuperimpose = false;
  79. @expandToProperty("_markAllSubMeshesAsMiscDirty")
  80. public bumpSuperimpose: boolean;
  81. /**
  82. * @param {boolean}: Color refraction and reflection differently with .waterColor2 and .colorBlendFactor2. Non-linear (physically correct) fresnel.
  83. */
  84. @serialize("fresnelSeparate")
  85. private _fresnelSeparate = false;
  86. @expandToProperty("_markAllSubMeshesAsMiscDirty")
  87. public fresnelSeparate: boolean;
  88. /**
  89. * @param {boolean}: bump Waves modify the reflection.
  90. */
  91. @serialize("bumpAffectsReflection")
  92. private _bumpAffectsReflection = false;
  93. @expandToProperty("_markAllSubMeshesAsMiscDirty")
  94. public bumpAffectsReflection: boolean;
  95. /**
  96. * @param {number}: The water color blended with the refraction (near)
  97. */
  98. @serializeAsColor3()
  99. public waterColor: Color3 = new Color3(0.1, 0.1, 0.6);
  100. /**
  101. * @param {number}: The blend factor related to the water color
  102. */
  103. @serialize()
  104. public colorBlendFactor: number = 0.2;
  105. /**
  106. * @param {number}: The water color blended with the reflection (far)
  107. */
  108. @serializeAsColor3()
  109. public waterColor2: Color3 = new Color3(0.1, 0.1, 0.6);
  110. /**
  111. * @param {number}: The blend factor related to the water color (reflection, far)
  112. */
  113. @serialize()
  114. public colorBlendFactor2: number = 0.2;
  115. /**
  116. * @param {number}: Represents the maximum length of a wave
  117. */
  118. @serialize()
  119. public waveLength: number = 0.1;
  120. /**
  121. * @param {number}: Defines the waves speed
  122. */
  123. @serialize()
  124. public waveSpeed: number = 1.0;
  125. protected _renderTargets = new SmartArray<RenderTargetTexture>(16);
  126. /*
  127. * Private members
  128. */
  129. private _mesh: Nullable<AbstractMesh> = null;
  130. private _refractionRTT: Nullable<RenderTargetTexture>;
  131. private _reflectionRTT: Nullable<RenderTargetTexture>;
  132. private _reflectionTransform: Matrix = Matrix.Zero();
  133. private _lastTime: number = 0;
  134. private _lastDeltaTime: number = 0;
  135. private _renderId: number;
  136. private _useLogarithmicDepth: boolean;
  137. private _waitingRenderList: Nullable<string[]>;
  138. /**
  139. * Constructor
  140. */
  141. constructor(name: string, scene: Scene, public renderTargetSize: Vector2 = new Vector2(512, 512)) {
  142. super(name, scene);
  143. this._createRenderTargets(scene, renderTargetSize);
  144. // Create render targets
  145. this.getRenderTargetTextures = (): SmartArray<RenderTargetTexture> => {
  146. this._renderTargets.reset();
  147. this._renderTargets.push(<RenderTargetTexture>this._reflectionRTT);
  148. this._renderTargets.push(<RenderTargetTexture>this._refractionRTT);
  149. return this._renderTargets;
  150. }
  151. }
  152. @serialize()
  153. public get useLogarithmicDepth(): boolean {
  154. return this._useLogarithmicDepth;
  155. }
  156. public set useLogarithmicDepth(value: boolean) {
  157. this._useLogarithmicDepth = value && this.getScene().getEngine().getCaps().fragmentDepthSupported;
  158. this._markAllSubMeshesAsMiscDirty();
  159. }
  160. // Get / Set
  161. public get refractionTexture(): Nullable<RenderTargetTexture> {
  162. return this._refractionRTT;
  163. }
  164. public get reflectionTexture(): Nullable<RenderTargetTexture> {
  165. return this._reflectionRTT;
  166. }
  167. // Methods
  168. public addToRenderList(node: any): void {
  169. if (this._refractionRTT && this._refractionRTT.renderList) {
  170. this._refractionRTT.renderList.push(node);
  171. }
  172. if (this._reflectionRTT && this._reflectionRTT.renderList) {
  173. this._reflectionRTT.renderList.push(node);
  174. }
  175. }
  176. public enableRenderTargets(enable: boolean): void {
  177. var refreshRate = enable ? 1 : 0;
  178. if (this._refractionRTT) {
  179. this._refractionRTT.refreshRate = refreshRate;
  180. }
  181. if (this._reflectionRTT) {
  182. this._reflectionRTT.refreshRate = refreshRate;
  183. }
  184. }
  185. public getRenderList(): Nullable<AbstractMesh[]> {
  186. return this._refractionRTT ? this._refractionRTT.renderList : [];
  187. }
  188. public get renderTargetsEnabled(): boolean {
  189. return !(this._refractionRTT && this._refractionRTT.refreshRate === 0);
  190. }
  191. public needAlphaBlending(): boolean {
  192. return (this.alpha < 1.0);
  193. }
  194. public needAlphaTesting(): boolean {
  195. return false;
  196. }
  197. public getAlphaTestTexture(): Nullable<BaseTexture> {
  198. return null;
  199. }
  200. public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
  201. if (this.isFrozen) {
  202. if (this._wasPreviouslyReady && subMesh.effect) {
  203. return true;
  204. }
  205. }
  206. if (!subMesh._materialDefines) {
  207. subMesh._materialDefines = new WaterMaterialDefines();
  208. }
  209. var defines = <WaterMaterialDefines>subMesh._materialDefines;
  210. var scene = this.getScene();
  211. if (!this.checkReadyOnEveryCall && subMesh.effect) {
  212. if (this._renderId === scene.getRenderId()) {
  213. return true;
  214. }
  215. }
  216. var engine = scene.getEngine();
  217. // Textures
  218. if (defines._areTexturesDirty) {
  219. defines._needUVs = false;
  220. if (scene.texturesEnabled) {
  221. if (this.bumpTexture && StandardMaterial.BumpTextureEnabled) {
  222. if (!this.bumpTexture.isReady()) {
  223. return false;
  224. } else {
  225. defines._needUVs = true;
  226. defines.BUMP = true;
  227. }
  228. }
  229. if (StandardMaterial.ReflectionTextureEnabled) {
  230. defines.REFLECTION = true;
  231. }
  232. }
  233. }
  234. MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
  235. MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
  236. if (defines._areMiscDirty) {
  237. if (this._fresnelSeparate) {
  238. defines.FRESNELSEPARATE = true;
  239. }
  240. if (this._bumpSuperimpose) {
  241. defines.BUMPSUPERIMPOSE = true;
  242. }
  243. if (this._bumpAffectsReflection) {
  244. defines.BUMPAFFECTSREFLECTION = true;
  245. }
  246. }
  247. // Lights
  248. defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, true, this._maxSimultaneousLights, this._disableLighting);
  249. // Attribs
  250. MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
  251. // Configure this
  252. this._mesh = mesh;
  253. if (this._waitingRenderList) {
  254. for (var i = 0; i < this._waitingRenderList.length; i++) {
  255. this.addToRenderList(scene.getNodeByID(this._waitingRenderList[i]));
  256. }
  257. this._waitingRenderList = null;
  258. }
  259. // Get correct effect
  260. if (defines.isDirty) {
  261. defines.markAsProcessed();
  262. scene.resetCachedMaterial();
  263. // Fallbacks
  264. var fallbacks = new EffectFallbacks();
  265. if (defines.FOG) {
  266. fallbacks.addFallback(1, "FOG");
  267. }
  268. if (defines.LOGARITHMICDEPTH) {
  269. fallbacks.addFallback(0, "LOGARITHMICDEPTH");
  270. }
  271. MaterialHelper.HandleFallbacksForShadows(defines, fallbacks, this.maxSimultaneousLights);
  272. if (defines.NUM_BONE_INFLUENCERS > 0) {
  273. fallbacks.addCPUSkinningFallback(0, mesh);
  274. }
  275. //Attributes
  276. var attribs = [VertexBuffer.PositionKind];
  277. if (defines.NORMAL) {
  278. attribs.push(VertexBuffer.NormalKind);
  279. }
  280. if (defines.UV1) {
  281. attribs.push(VertexBuffer.UVKind);
  282. }
  283. if (defines.UV2) {
  284. attribs.push(VertexBuffer.UV2Kind);
  285. }
  286. if (defines.VERTEXCOLOR) {
  287. attribs.push(VertexBuffer.ColorKind);
  288. }
  289. MaterialHelper.PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
  290. MaterialHelper.PrepareAttributesForInstances(attribs, defines);
  291. // Legacy browser patch
  292. var shaderName = "water";
  293. var join = defines.toString();
  294. var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
  295. "vFogInfos", "vFogColor", "pointSize",
  296. "vNormalInfos",
  297. "mBones",
  298. "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "normalMatrix",
  299. "logarithmicDepthConstant",
  300. // Water
  301. "worldReflectionViewProjection", "windDirection", "waveLength", "time", "windForce",
  302. "cameraPosition", "bumpHeight", "waveHeight", "waterColor", "waterColor2", "colorBlendFactor", "colorBlendFactor2", "waveSpeed"
  303. ]
  304. var samplers = ["normalSampler",
  305. // Water
  306. "refractionSampler", "reflectionSampler"
  307. ];
  308. var uniformBuffers = new Array<string>()
  309. MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
  310. uniformsNames: uniforms,
  311. uniformBuffersNames: uniformBuffers,
  312. samplers: samplers,
  313. defines: defines,
  314. maxSimultaneousLights: this.maxSimultaneousLights
  315. });
  316. subMesh.setEffect(scene.getEngine().createEffect(shaderName,
  317. <EffectCreationOptions>{
  318. attributes: attribs,
  319. uniformsNames: uniforms,
  320. uniformBuffersNames: uniformBuffers,
  321. samplers: samplers,
  322. defines: join,
  323. fallbacks: fallbacks,
  324. onCompiled: this.onCompiled,
  325. onError: this.onError,
  326. indexParameters: { maxSimultaneousLights: this._maxSimultaneousLights }
  327. }, engine), defines);
  328. }
  329. if (!subMesh.effect || !subMesh.effect.isReady()) {
  330. return false;
  331. }
  332. this._renderId = scene.getRenderId();
  333. this._wasPreviouslyReady = true;
  334. return true;
  335. }
  336. public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
  337. var scene = this.getScene();
  338. var defines = <WaterMaterialDefines>subMesh._materialDefines;
  339. if (!defines) {
  340. return;
  341. }
  342. var effect = subMesh.effect;
  343. if (!effect || !this._mesh) {
  344. return;
  345. }
  346. this._activeEffect = effect;
  347. // Matrices
  348. this.bindOnlyWorldMatrix(world);
  349. this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
  350. // Bones
  351. MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
  352. if (this._mustRebind(scene, effect)) {
  353. // Textures
  354. if (this.bumpTexture && StandardMaterial.BumpTextureEnabled) {
  355. this._activeEffect.setTexture("normalSampler", this.bumpTexture);
  356. this._activeEffect.setFloat2("vNormalInfos", this.bumpTexture.coordinatesIndex, this.bumpTexture.level);
  357. this._activeEffect.setMatrix("normalMatrix", this.bumpTexture.getTextureMatrix());
  358. }
  359. // Clip plane
  360. MaterialHelper.BindClipPlane(this._activeEffect, scene);
  361. // Point size
  362. if (this.pointsCloud) {
  363. this._activeEffect.setFloat("pointSize", this.pointSize);
  364. }
  365. MaterialHelper.BindEyePosition(effect, scene);
  366. }
  367. this._activeEffect.setColor4("vDiffuseColor", this.diffuseColor, this.alpha * mesh.visibility);
  368. if (defines.SPECULARTERM) {
  369. this._activeEffect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
  370. }
  371. if (scene.lightsEnabled && !this.disableLighting) {
  372. MaterialHelper.BindLights(scene, mesh, this._activeEffect, defines, this.maxSimultaneousLights);
  373. }
  374. // View
  375. if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
  376. this._activeEffect.setMatrix("view", scene.getViewMatrix());
  377. }
  378. // Fog
  379. MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
  380. // Log. depth
  381. MaterialHelper.BindLogDepth(defines, this._activeEffect, scene);
  382. // Water
  383. if (StandardMaterial.ReflectionTextureEnabled) {
  384. this._activeEffect.setTexture("refractionSampler", this._refractionRTT);
  385. this._activeEffect.setTexture("reflectionSampler", this._reflectionRTT);
  386. }
  387. var wrvp = this._mesh.getWorldMatrix().multiply(this._reflectionTransform).multiply(scene.getProjectionMatrix());
  388. // Add delta time. Prevent adding delta time if it hasn't changed.
  389. let deltaTime = scene.getEngine().getDeltaTime();
  390. if (deltaTime !== this._lastDeltaTime) {
  391. this._lastDeltaTime = deltaTime;
  392. this._lastTime += this._lastDeltaTime;
  393. }
  394. this._activeEffect.setMatrix("worldReflectionViewProjection", wrvp);
  395. this._activeEffect.setVector2("windDirection", this.windDirection);
  396. this._activeEffect.setFloat("waveLength", this.waveLength);
  397. this._activeEffect.setFloat("time", this._lastTime / 100000);
  398. this._activeEffect.setFloat("windForce", this.windForce);
  399. this._activeEffect.setFloat("waveHeight", this.waveHeight);
  400. this._activeEffect.setFloat("bumpHeight", this.bumpHeight);
  401. this._activeEffect.setColor4("waterColor", this.waterColor, 1.0);
  402. this._activeEffect.setFloat("colorBlendFactor", this.colorBlendFactor);
  403. this._activeEffect.setColor4("waterColor2", this.waterColor2, 1.0);
  404. this._activeEffect.setFloat("colorBlendFactor2", this.colorBlendFactor2);
  405. this._activeEffect.setFloat("waveSpeed", this.waveSpeed);
  406. this._afterBind(mesh, this._activeEffect);
  407. }
  408. private _createRenderTargets(scene: Scene, renderTargetSize: Vector2): void {
  409. // Render targets
  410. this._refractionRTT = new RenderTargetTexture(name + "_refraction", { width: renderTargetSize.x, height: renderTargetSize.y }, scene, false, true);
  411. this._refractionRTT.wrapU = BABYLON.Texture.MIRROR_ADDRESSMODE;
  412. this._refractionRTT.wrapV = BABYLON.Texture.MIRROR_ADDRESSMODE;
  413. this._refractionRTT.ignoreCameraViewport = true;
  414. this._reflectionRTT = new RenderTargetTexture(name + "_reflection", { width: renderTargetSize.x, height: renderTargetSize.y }, scene, false, true);
  415. this._reflectionRTT.wrapU = BABYLON.Texture.MIRROR_ADDRESSMODE;
  416. this._reflectionRTT.wrapV = BABYLON.Texture.MIRROR_ADDRESSMODE;
  417. this._reflectionRTT.ignoreCameraViewport = true;
  418. var isVisible: boolean;
  419. var clipPlane: Nullable<Plane> = null;
  420. var savedViewMatrix: Matrix;
  421. var mirrorMatrix = Matrix.Zero();
  422. this._refractionRTT.onBeforeRender = () => {
  423. if (this._mesh) {
  424. isVisible = this._mesh.isVisible;
  425. this._mesh.isVisible = false;
  426. }
  427. // Clip plane
  428. clipPlane = scene.clipPlane;
  429. var positiony = this._mesh ? this._mesh.position.y : 0.0;
  430. scene.clipPlane = Plane.FromPositionAndNormal(new Vector3(0, positiony + 0.05, 0), new Vector3(0, 1, 0));
  431. };
  432. this._refractionRTT.onAfterRender = () => {
  433. if (this._mesh) {
  434. this._mesh.isVisible = isVisible;
  435. }
  436. // Clip plane
  437. scene.clipPlane = clipPlane;
  438. };
  439. this._reflectionRTT.onBeforeRender = () => {
  440. if (this._mesh) {
  441. isVisible = this._mesh.isVisible;
  442. this._mesh.isVisible = false;
  443. }
  444. // Clip plane
  445. clipPlane = scene.clipPlane;
  446. var positiony = this._mesh ? this._mesh.position.y : 0.0;
  447. scene.clipPlane = Plane.FromPositionAndNormal(new Vector3(0, positiony - 0.05, 0), new Vector3(0, -1, 0));
  448. // Transform
  449. Matrix.ReflectionToRef(scene.clipPlane, mirrorMatrix);
  450. savedViewMatrix = scene.getViewMatrix();
  451. mirrorMatrix.multiplyToRef(savedViewMatrix, this._reflectionTransform);
  452. scene.setTransformMatrix(this._reflectionTransform, scene.getProjectionMatrix());
  453. scene.getEngine().cullBackFaces = false;
  454. scene._mirroredCameraPosition = Vector3.TransformCoordinates((<Camera>scene.activeCamera).position, mirrorMatrix);
  455. };
  456. this._reflectionRTT.onAfterRender = () => {
  457. if (this._mesh) {
  458. this._mesh.isVisible = isVisible;
  459. }
  460. // Clip plane
  461. scene.clipPlane = clipPlane;
  462. // Transform
  463. scene.setTransformMatrix(savedViewMatrix, scene.getProjectionMatrix());
  464. scene.getEngine().cullBackFaces = true;
  465. scene._mirroredCameraPosition = null;
  466. };
  467. }
  468. public getAnimatables(): IAnimatable[] {
  469. var results = [];
  470. if (this.bumpTexture && this.bumpTexture.animations && this.bumpTexture.animations.length > 0) {
  471. results.push(this.bumpTexture);
  472. }
  473. if (this._reflectionRTT && this._reflectionRTT.animations && this._reflectionRTT.animations.length > 0) {
  474. results.push(this._reflectionRTT);
  475. }
  476. if (this._refractionRTT && this._refractionRTT.animations && this._refractionRTT.animations.length > 0) {
  477. results.push(this._refractionRTT);
  478. }
  479. return results;
  480. }
  481. public getActiveTextures(): BaseTexture[] {
  482. var activeTextures = super.getActiveTextures();
  483. if (this._bumpTexture) {
  484. activeTextures.push(this._bumpTexture);
  485. }
  486. return activeTextures;
  487. }
  488. public hasTexture(texture: BaseTexture): boolean {
  489. if (super.hasTexture(texture)) {
  490. return true;
  491. }
  492. if (this._bumpTexture === texture) {
  493. return true;
  494. }
  495. return false;
  496. }
  497. public dispose(forceDisposeEffect?: boolean): void {
  498. if (this.bumpTexture) {
  499. this.bumpTexture.dispose();
  500. }
  501. var index = this.getScene().customRenderTargets.indexOf(<RenderTargetTexture>this._refractionRTT);
  502. if (index != -1) {
  503. this.getScene().customRenderTargets.splice(index, 1);
  504. }
  505. index = -1;
  506. index = this.getScene().customRenderTargets.indexOf(<RenderTargetTexture>this._reflectionRTT);
  507. if (index != -1) {
  508. this.getScene().customRenderTargets.splice(index, 1);
  509. }
  510. if (this._reflectionRTT) {
  511. this._reflectionRTT.dispose();
  512. }
  513. if (this._refractionRTT) {
  514. this._refractionRTT.dispose();
  515. }
  516. super.dispose(forceDisposeEffect);
  517. }
  518. public clone(name: string): WaterMaterial {
  519. return SerializationHelper.Clone(() => new WaterMaterial(name, this.getScene()), this);
  520. }
  521. public serialize(): any {
  522. var serializationObject = SerializationHelper.Serialize(this);
  523. serializationObject.customType = "BABYLON.WaterMaterial";
  524. serializationObject.renderList = [];
  525. if (this._refractionRTT && this._refractionRTT.renderList) {
  526. for (var i = 0; i < this._refractionRTT.renderList.length; i++) {
  527. serializationObject.renderList.push(this._refractionRTT.renderList[i].id);
  528. }
  529. }
  530. return serializationObject;
  531. }
  532. public getClassName(): string {
  533. return "WaterMaterial";
  534. }
  535. // Statics
  536. public static Parse(source: any, scene: Scene, rootUrl: string): WaterMaterial {
  537. var mat = SerializationHelper.Parse(() => new WaterMaterial(source.name, scene), source, scene, rootUrl);
  538. mat._waitingRenderList = source.renderList;
  539. return mat;
  540. }
  541. public static CreateDefaultMesh(name: string, scene: Scene): Mesh {
  542. var mesh = Mesh.CreateGround(name, 512, 512, 32, scene, false);
  543. return mesh;
  544. }
  545. }
  546. }