waterMaterial.ts 27 KB

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