fluidRenderingTargetRenderer.js 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. import { Color3, Color4 } from "../../Maths/math.color.js";
  2. import { Matrix, Vector2, Vector3 } from "../../Maths/math.vector.js";
  3. import { Observable } from "../../Misc/observable.js";
  4. import { PostProcess } from "../../PostProcesses/postProcess.js";
  5. import { FluidRenderingTextures } from "./fluidRenderingTextures.js";
  6. /**
  7. * Textures that can be displayed as a debugging tool
  8. */
  9. export var FluidRenderingDebug;
  10. (function (FluidRenderingDebug) {
  11. FluidRenderingDebug[FluidRenderingDebug["DepthTexture"] = 0] = "DepthTexture";
  12. FluidRenderingDebug[FluidRenderingDebug["DepthBlurredTexture"] = 1] = "DepthBlurredTexture";
  13. FluidRenderingDebug[FluidRenderingDebug["ThicknessTexture"] = 2] = "ThicknessTexture";
  14. FluidRenderingDebug[FluidRenderingDebug["ThicknessBlurredTexture"] = 3] = "ThicknessBlurredTexture";
  15. FluidRenderingDebug[FluidRenderingDebug["DiffuseTexture"] = 4] = "DiffuseTexture";
  16. FluidRenderingDebug[FluidRenderingDebug["Normals"] = 5] = "Normals";
  17. FluidRenderingDebug[FluidRenderingDebug["DiffuseRendering"] = 6] = "DiffuseRendering";
  18. })(FluidRenderingDebug || (FluidRenderingDebug = {}));
  19. /**
  20. * Class used to render an object as a fluid thanks to different render target textures (depth, thickness, diffuse)
  21. */
  22. export class FluidRenderingTargetRenderer {
  23. /**
  24. * Returns true if the class needs to be reinitialized (because of changes in parameterization)
  25. */
  26. get needInitialization() {
  27. return this._needInitialization;
  28. }
  29. /**
  30. * Gets or sets a boolean indicating that the diffuse texture should be generated and used for the rendering
  31. */
  32. get generateDiffuseTexture() {
  33. return this._generateDiffuseTexture;
  34. }
  35. set generateDiffuseTexture(generate) {
  36. if (this._generateDiffuseTexture === generate) {
  37. return;
  38. }
  39. this._generateDiffuseTexture = generate;
  40. this._needInitialization = true;
  41. }
  42. /**
  43. * Gets or sets the feature (texture) to be debugged. Not used if debug is false
  44. */
  45. get debugFeature() {
  46. return this._debugFeature;
  47. }
  48. set debugFeature(feature) {
  49. if (this._debugFeature === feature) {
  50. return;
  51. }
  52. this._needInitialization = true;
  53. this._debugFeature = feature;
  54. }
  55. /**
  56. * Gets or sets a boolean indicating if we should display a specific texture (given by debugFeature) for debugging purpose
  57. */
  58. get debug() {
  59. return this._debug;
  60. }
  61. set debug(debug) {
  62. if (this._debug === debug) {
  63. return;
  64. }
  65. this._debug = debug;
  66. this._needInitialization = true;
  67. }
  68. /**
  69. * Gets or sets the environment map used for the reflection part of the shading
  70. * If null, no map will be used. If undefined, the scene.environmentMap will be used (if defined)
  71. */
  72. get environmentMap() {
  73. return this._environmentMap;
  74. }
  75. set environmentMap(map) {
  76. if (this._environmentMap === map) {
  77. return;
  78. }
  79. this._needInitialization = true;
  80. this._environmentMap = map;
  81. }
  82. /**
  83. * Gets or sets a boolean indicating that the depth texture should be blurred
  84. */
  85. get enableBlurDepth() {
  86. return this._enableBlurDepth;
  87. }
  88. set enableBlurDepth(enable) {
  89. if (this._enableBlurDepth === enable) {
  90. return;
  91. }
  92. this._enableBlurDepth = enable;
  93. this._needInitialization = true;
  94. }
  95. /**
  96. * Gets or sets the depth size divisor (positive number, generally between 1 and 4), which is used as a divisor when creating the texture used for blurring the depth
  97. * For eg. if blurDepthSizeDivisor=2, the texture used to blur the depth will be half the size of the depth texture
  98. */
  99. get blurDepthSizeDivisor() {
  100. return this._blurDepthSizeDivisor;
  101. }
  102. set blurDepthSizeDivisor(scale) {
  103. if (this._blurDepthSizeDivisor === scale) {
  104. return;
  105. }
  106. this._blurDepthSizeDivisor = scale;
  107. this._needInitialization = true;
  108. }
  109. /**
  110. * Size of the kernel used to filter the depth blur texture (positive number, generally between 1 and 20 - higher values will require more processing power from the GPU)
  111. */
  112. get blurDepthFilterSize() {
  113. return this._blurDepthFilterSize;
  114. }
  115. set blurDepthFilterSize(filterSize) {
  116. if (this._blurDepthFilterSize === filterSize) {
  117. return;
  118. }
  119. this._blurDepthFilterSize = filterSize;
  120. this._setBlurParameters();
  121. }
  122. /**
  123. * Number of blurring iterations used to generate the depth blur texture (positive number, generally between 1 and 10 - higher values will require more processing power from the GPU)
  124. */
  125. get blurDepthNumIterations() {
  126. return this._blurDepthNumIterations;
  127. }
  128. set blurDepthNumIterations(numIterations) {
  129. if (this._blurDepthNumIterations === numIterations) {
  130. return;
  131. }
  132. this._blurDepthNumIterations = numIterations;
  133. this._setBlurParameters();
  134. }
  135. /**
  136. * Maximum size of the kernel used to blur the depth texture (positive number, generally between 1 and 200 - higher values will require more processing power from the GPU when the particles are larger on screen)
  137. */
  138. get blurDepthMaxFilterSize() {
  139. return this._blurDepthMaxFilterSize;
  140. }
  141. set blurDepthMaxFilterSize(maxFilterSize) {
  142. if (this._blurDepthMaxFilterSize === maxFilterSize) {
  143. return;
  144. }
  145. this._blurDepthMaxFilterSize = maxFilterSize;
  146. this._setBlurParameters();
  147. }
  148. /**
  149. * Depth weight in the calculation when applying the bilateral blur to generate the depth blur texture (positive number, generally between 0 and 100)
  150. */
  151. get blurDepthDepthScale() {
  152. return this._blurDepthDepthScale;
  153. }
  154. set blurDepthDepthScale(scale) {
  155. if (this._blurDepthDepthScale === scale) {
  156. return;
  157. }
  158. this._blurDepthDepthScale = scale;
  159. this._setBlurParameters();
  160. }
  161. /**
  162. * Gets or sets a boolean indicating that the thickness texture should be blurred
  163. */
  164. get enableBlurThickness() {
  165. return this._enableBlurThickness;
  166. }
  167. set enableBlurThickness(enable) {
  168. if (this._enableBlurThickness === enable) {
  169. return;
  170. }
  171. this._enableBlurThickness = enable;
  172. this._needInitialization = true;
  173. }
  174. /**
  175. * Gets or sets the thickness size divisor (positive number, generally between 1 and 4), which is used as a divisor when creating the texture used for blurring the thickness
  176. * For eg. if blurThicknessSizeDivisor=2, the texture used to blur the thickness will be half the size of the thickness texture
  177. */
  178. get blurThicknessSizeDivisor() {
  179. return this._blurThicknessSizeDivisor;
  180. }
  181. set blurThicknessSizeDivisor(scale) {
  182. if (this._blurThicknessSizeDivisor === scale) {
  183. return;
  184. }
  185. this._blurThicknessSizeDivisor = scale;
  186. this._needInitialization = true;
  187. }
  188. /**
  189. * Size of the kernel used to filter the thickness blur texture (positive number, generally between 1 and 20 - higher values will require more processing power from the GPU)
  190. */
  191. get blurThicknessFilterSize() {
  192. return this._blurThicknessFilterSize;
  193. }
  194. set blurThicknessFilterSize(filterSize) {
  195. if (this._blurThicknessFilterSize === filterSize) {
  196. return;
  197. }
  198. this._blurThicknessFilterSize = filterSize;
  199. this._setBlurParameters();
  200. }
  201. /**
  202. * Number of blurring iterations used to generate the thickness blur texture (positive number, generally between 1 and 10 - higher values will require more processing power from the GPU)
  203. */
  204. get blurThicknessNumIterations() {
  205. return this._blurThicknessNumIterations;
  206. }
  207. set blurThicknessNumIterations(numIterations) {
  208. if (this._blurThicknessNumIterations === numIterations) {
  209. return;
  210. }
  211. this._blurThicknessNumIterations = numIterations;
  212. this._setBlurParameters();
  213. }
  214. /**
  215. * Gets or sets a boolean indicating that a fixed thickness should be used instead of generating a thickness texture
  216. */
  217. get useFixedThickness() {
  218. return this._useFixedThickness;
  219. }
  220. set useFixedThickness(use) {
  221. if (this._useFixedThickness === use) {
  222. return;
  223. }
  224. this._useFixedThickness = use;
  225. this._needInitialization = true;
  226. }
  227. /**
  228. * Gets or sets a boolean indicating that the velocity should be used when rendering the particles as a fluid.
  229. * Note: the vertex buffers must contain a "velocity" buffer for this to work!
  230. */
  231. get useVelocity() {
  232. return this._useVelocity;
  233. }
  234. set useVelocity(use) {
  235. if (this._useVelocity === use) {
  236. return;
  237. }
  238. this._useVelocity = use;
  239. this._needInitialization = true;
  240. this._onUseVelocityChanged.notifyObservers(this);
  241. }
  242. /**
  243. * Defines the size of the depth texture.
  244. * If null, the texture will have the size of the screen
  245. */
  246. get depthMapSize() {
  247. return this._depthMapSize;
  248. }
  249. set depthMapSize(size) {
  250. if (this._depthMapSize === size) {
  251. return;
  252. }
  253. this._depthMapSize = size;
  254. this._needInitialization = true;
  255. }
  256. /**
  257. * Defines the size of the thickness texture.
  258. * If null, the texture will have the size of the screen
  259. */
  260. get thicknessMapSize() {
  261. return this._thicknessMapSize;
  262. }
  263. set thicknessMapSize(size) {
  264. if (this._thicknessMapSize === size) {
  265. return;
  266. }
  267. this._thicknessMapSize = size;
  268. this._needInitialization = true;
  269. }
  270. /**
  271. * Defines the size of the diffuse texture.
  272. * If null, the texture will have the size of the screen
  273. */
  274. get diffuseMapSize() {
  275. return this._diffuseMapSize;
  276. }
  277. set diffuseMapSize(size) {
  278. if (this._diffuseMapSize === size) {
  279. return;
  280. }
  281. this._diffuseMapSize = size;
  282. this._needInitialization = true;
  283. }
  284. /**
  285. * Gets or sets the number of samples used by MSAA
  286. * Note: changing this value in WebGL does not work because depth/stencil textures can't be created with MSAA (see https://github.com/BabylonJS/Babylon.js/issues/12444)
  287. */
  288. get samples() {
  289. return this._samples;
  290. }
  291. set samples(samples) {
  292. if (this._samples === samples) {
  293. return;
  294. }
  295. this._samples = samples;
  296. this._needInitialization = true;
  297. }
  298. /**
  299. * Gets the camera used for the rendering
  300. */
  301. get camera() {
  302. return this._camera;
  303. }
  304. /**
  305. * Creates an instance of the class
  306. * @param scene Scene used to render the fluid object into
  307. * @param camera Camera used to render the fluid object. If not provided, use the active camera of the scene instead
  308. */
  309. constructor(scene, camera) {
  310. this._generateDiffuseTexture = false;
  311. /**
  312. * Fluid color. Not used if generateDiffuseTexture is true
  313. */
  314. this.fluidColor = new Color3(0.085, 0.6375, 0.765);
  315. /**
  316. * Density of the fluid (positive number). The higher the value, the more opaque the fluid.
  317. */
  318. this.density = 2;
  319. /**
  320. * Strength of the refraction (positive number, but generally between 0 and 0.3).
  321. */
  322. this.refractionStrength = 0.1;
  323. /**
  324. * Strength of the fresnel effect (value between 0 and 1). Lower the value if you want to soften the specular effect
  325. */
  326. this.fresnelClamp = 1.0;
  327. /**
  328. * Strength of the specular power (positive number). Increase the value to make the specular effect more concentrated
  329. */
  330. this.specularPower = 250;
  331. /**
  332. * Minimum thickness of the particles (positive number). If useFixedThickness is true, minimumThickness is the thickness used
  333. */
  334. this.minimumThickness = 0;
  335. /**
  336. * Direction of the light. The fluid is assumed to be lit by a directional light
  337. */
  338. this.dirLight = new Vector3(-2, -1, 1).normalize();
  339. this._debugFeature = FluidRenderingDebug.DepthBlurredTexture;
  340. this._debug = false;
  341. this._enableBlurDepth = true;
  342. this._blurDepthSizeDivisor = 1;
  343. this._blurDepthFilterSize = 7;
  344. this._blurDepthNumIterations = 3;
  345. this._blurDepthMaxFilterSize = 100;
  346. this._blurDepthDepthScale = 10;
  347. this._enableBlurThickness = true;
  348. this._blurThicknessSizeDivisor = 1;
  349. this._blurThicknessFilterSize = 5;
  350. this._blurThicknessNumIterations = 1;
  351. this._useFixedThickness = false;
  352. /** @internal */
  353. this._onUseVelocityChanged = new Observable();
  354. this._useVelocity = false;
  355. this._depthMapSize = null;
  356. this._thicknessMapSize = null;
  357. this._diffuseMapSize = null;
  358. this._samples = 1;
  359. this._scene = scene;
  360. this._engine = scene.getEngine();
  361. this._camera = camera ?? scene.activeCamera;
  362. this._needInitialization = true;
  363. this._bgDepthTexture = null;
  364. this._invProjectionMatrix = new Matrix();
  365. this._depthClearColor = new Color4(1e6, 1e6, 1e6, 1);
  366. this._thicknessClearColor = new Color4(0, 0, 0, 1);
  367. this._depthRenderTarget = null;
  368. this._diffuseRenderTarget = null;
  369. this._thicknessRenderTarget = null;
  370. this._renderPostProcess = null;
  371. }
  372. /** @internal */
  373. _initialize() {
  374. this.dispose();
  375. this._needInitialization = false;
  376. const depthWidth = this._depthMapSize ?? this._engine.getRenderWidth();
  377. const depthHeight = this._depthMapSize !== null ? Math.round((this._depthMapSize * this._engine.getRenderHeight()) / this._engine.getRenderWidth()) : this._engine.getRenderHeight();
  378. this._depthRenderTarget = new FluidRenderingTextures("Depth", this._scene, depthWidth, depthHeight, depthWidth, depthHeight, 1, 7, 1, 7, false, this._camera, true, this._samples);
  379. this._initializeRenderTarget(this._depthRenderTarget);
  380. if (this.generateDiffuseTexture) {
  381. const diffuseWidth = this._diffuseMapSize ?? this._engine.getRenderWidth();
  382. const diffuseHeight = this._diffuseMapSize !== null
  383. ? Math.round((this._diffuseMapSize * this._engine.getRenderHeight()) / this._engine.getRenderWidth())
  384. : this._engine.getRenderHeight();
  385. this._diffuseRenderTarget = new FluidRenderingTextures("Diffuse", this._scene, diffuseWidth, diffuseHeight, 0, 0, 0, 5, 0, 5, true, this._camera, true, this._samples);
  386. this._initializeRenderTarget(this._diffuseRenderTarget);
  387. }
  388. const thicknessWidth = this._thicknessMapSize ?? this._engine.getRenderWidth();
  389. const thicknessHeight = this._thicknessMapSize !== null
  390. ? Math.round((this._thicknessMapSize * this._engine.getRenderHeight()) / this._engine.getRenderWidth())
  391. : this._engine.getRenderHeight();
  392. if (!this._useFixedThickness) {
  393. this._thicknessRenderTarget = new FluidRenderingTextures("Thickness", this._scene, thicknessWidth, thicknessHeight, thicknessWidth, thicknessHeight, 2, 6, 2, 6, true, this._camera, false, this._samples);
  394. this._initializeRenderTarget(this._thicknessRenderTarget);
  395. }
  396. this._createLiquidRenderingPostProcess();
  397. }
  398. _setBlurParameters(renderTarget = null) {
  399. if (renderTarget === null || renderTarget === this._depthRenderTarget) {
  400. this._setBlurDepthParameters();
  401. }
  402. if (renderTarget === null || renderTarget === this._thicknessRenderTarget) {
  403. this._setBlurThicknessParameters();
  404. }
  405. }
  406. _setBlurDepthParameters() {
  407. if (!this._depthRenderTarget) {
  408. return;
  409. }
  410. this._depthRenderTarget.blurFilterSize = this.blurDepthFilterSize;
  411. this._depthRenderTarget.blurMaxFilterSize = this.blurDepthMaxFilterSize;
  412. this._depthRenderTarget.blurNumIterations = this.blurDepthNumIterations;
  413. this._depthRenderTarget.blurDepthScale = this.blurDepthDepthScale;
  414. }
  415. _setBlurThicknessParameters() {
  416. if (!this._thicknessRenderTarget) {
  417. return;
  418. }
  419. this._thicknessRenderTarget.blurFilterSize = this.blurThicknessFilterSize;
  420. this._thicknessRenderTarget.blurNumIterations = this.blurThicknessNumIterations;
  421. }
  422. _initializeRenderTarget(renderTarget) {
  423. if (renderTarget !== this._diffuseRenderTarget) {
  424. renderTarget.enableBlur = renderTarget === this._depthRenderTarget ? this.enableBlurDepth : this.enableBlurThickness;
  425. renderTarget.blurSizeDivisor = renderTarget === this._depthRenderTarget ? this.blurDepthSizeDivisor : this.blurThicknessSizeDivisor;
  426. }
  427. this._setBlurParameters(renderTarget);
  428. renderTarget.initialize();
  429. }
  430. _createLiquidRenderingPostProcess() {
  431. const engine = this._scene.getEngine();
  432. const uniformNames = [
  433. "viewMatrix",
  434. "projectionMatrix",
  435. "invProjectionMatrix",
  436. "texelSize",
  437. "dirLight",
  438. "cameraFar",
  439. "density",
  440. "refractionStrength",
  441. "fresnelClamp",
  442. "specularPower",
  443. ];
  444. const samplerNames = ["depthSampler"];
  445. const defines = [];
  446. this.dispose(true);
  447. if (!this._camera) {
  448. return;
  449. }
  450. const texture = this._depthRenderTarget.enableBlur ? this._depthRenderTarget.textureBlur : this._depthRenderTarget.texture;
  451. const texelSize = new Vector2(1 / texture.getSize().width, 1 / texture.getSize().height);
  452. if (this._scene.useRightHandedSystem) {
  453. defines.push("#define FLUIDRENDERING_RHS");
  454. }
  455. if (this._environmentMap !== null) {
  456. const envMap = this._environmentMap ?? this._scene.environmentTexture;
  457. if (envMap) {
  458. samplerNames.push("reflectionSampler");
  459. defines.push("#define FLUIDRENDERING_ENVIRONMENT");
  460. }
  461. }
  462. if (this._diffuseRenderTarget) {
  463. samplerNames.push("diffuseSampler");
  464. defines.push("#define FLUIDRENDERING_DIFFUSETEXTURE");
  465. }
  466. else {
  467. uniformNames.push("diffuseColor");
  468. }
  469. if (this._useVelocity) {
  470. samplerNames.push("velocitySampler");
  471. defines.push("#define FLUIDRENDERING_VELOCITY");
  472. }
  473. if (this._useFixedThickness) {
  474. uniformNames.push("thickness");
  475. samplerNames.push("bgDepthSampler");
  476. defines.push("#define FLUIDRENDERING_FIXED_THICKNESS");
  477. }
  478. else {
  479. uniformNames.push("minimumThickness");
  480. samplerNames.push("thicknessSampler");
  481. }
  482. if (this._debug) {
  483. defines.push("#define FLUIDRENDERING_DEBUG");
  484. if (this._debugFeature === FluidRenderingDebug.Normals) {
  485. defines.push("#define FLUIDRENDERING_DEBUG_SHOWNORMAL");
  486. }
  487. else if (this._debugFeature === FluidRenderingDebug.DiffuseRendering) {
  488. defines.push("#define FLUIDRENDERING_DEBUG_DIFFUSERENDERING");
  489. }
  490. else {
  491. defines.push("#define FLUIDRENDERING_DEBUG_TEXTURE");
  492. samplerNames.push("debugSampler");
  493. if (this._debugFeature === FluidRenderingDebug.DepthTexture || this._debugFeature === FluidRenderingDebug.DepthBlurredTexture) {
  494. defines.push("#define FLUIDRENDERING_DEBUG_DEPTH");
  495. }
  496. }
  497. }
  498. this._renderPostProcess = new PostProcess("FluidRendering", "fluidRenderingRender", uniformNames, samplerNames, 1, null, 2, engine, false, null, 0, undefined, undefined, true, undefined);
  499. this._renderPostProcess.updateEffect(defines.join("\n"));
  500. this._renderPostProcess.samples = this._samples;
  501. this._renderPostProcess.onApplyObservable.add((effect) => {
  502. this._invProjectionMatrix.copyFrom(this._scene.getProjectionMatrix());
  503. this._invProjectionMatrix.invert();
  504. if (engine.isWebGPU) {
  505. effect.setTextureSampler("textureSamplerSampler", this._renderPostProcess.inputTexture.texture);
  506. }
  507. if (!this._depthRenderTarget.enableBlur) {
  508. effect.setTexture("depthSampler", this._depthRenderTarget.texture);
  509. if (engine.isWebGPU) {
  510. effect.setTextureSampler("depthSamplerSampler", this._depthRenderTarget.texture?.getInternalTexture() ?? null);
  511. }
  512. }
  513. else {
  514. effect.setTexture("depthSampler", this._depthRenderTarget.textureBlur);
  515. if (engine.isWebGPU) {
  516. effect.setTextureSampler("depthSamplerSampler", this._depthRenderTarget.textureBlur?.getInternalTexture() ?? null);
  517. }
  518. }
  519. if (this._diffuseRenderTarget) {
  520. if (!this._diffuseRenderTarget.enableBlur) {
  521. effect.setTexture("diffuseSampler", this._diffuseRenderTarget.texture);
  522. if (engine.isWebGPU) {
  523. effect.setTextureSampler("diffuseSamplerSampler", this._diffuseRenderTarget.texture?.getInternalTexture() ?? null);
  524. }
  525. }
  526. else {
  527. effect.setTexture("diffuseSampler", this._diffuseRenderTarget.textureBlur);
  528. if (engine.isWebGPU) {
  529. effect.setTextureSampler("diffuseSamplerSampler", this._diffuseRenderTarget.textureBlur?.getInternalTexture() ?? null);
  530. }
  531. }
  532. }
  533. else {
  534. effect.setColor3("diffuseColor", this.fluidColor);
  535. }
  536. if (this._useFixedThickness) {
  537. effect.setFloat("thickness", this.minimumThickness);
  538. effect._bindTexture("bgDepthSampler", this._bgDepthTexture);
  539. if (engine.isWebGPU) {
  540. effect.setTextureSampler("bgDepthSamplerSampler", this._bgDepthTexture ?? null);
  541. }
  542. }
  543. else {
  544. if (!this._thicknessRenderTarget.enableBlur) {
  545. effect.setTexture("thicknessSampler", this._thicknessRenderTarget.texture);
  546. if (engine.isWebGPU) {
  547. effect.setTextureSampler("thicknessSamplerSampler", this._thicknessRenderTarget.texture?.getInternalTexture() ?? null);
  548. }
  549. }
  550. else {
  551. effect.setTexture("thicknessSampler", this._thicknessRenderTarget.textureBlur);
  552. if (engine.isWebGPU) {
  553. effect.setTextureSampler("thicknessSamplerSampler", this._thicknessRenderTarget.textureBlur?.getInternalTexture() ?? null);
  554. }
  555. }
  556. effect.setFloat("minimumThickness", this.minimumThickness);
  557. }
  558. if (this._environmentMap !== null) {
  559. const envMap = this._environmentMap ?? this._scene.environmentTexture;
  560. if (envMap) {
  561. effect.setTexture("reflectionSampler", envMap);
  562. if (engine.isWebGPU) {
  563. effect.setTextureSampler("reflectionSamplerSampler", envMap?.getInternalTexture() ?? null);
  564. }
  565. }
  566. }
  567. effect.setMatrix("viewMatrix", this._scene.getViewMatrix());
  568. effect.setMatrix("invProjectionMatrix", this._invProjectionMatrix);
  569. effect.setMatrix("projectionMatrix", this._scene.getProjectionMatrix());
  570. effect.setVector2("texelSize", texelSize);
  571. effect.setFloat("density", this.density);
  572. effect.setFloat("refractionStrength", this.refractionStrength);
  573. effect.setFloat("fresnelClamp", this.fresnelClamp);
  574. effect.setFloat("specularPower", this.specularPower);
  575. effect.setVector3("dirLight", this.dirLight);
  576. effect.setFloat("cameraFar", this._camera.maxZ);
  577. if (this._debug) {
  578. let texture = null;
  579. switch (this._debugFeature) {
  580. case FluidRenderingDebug.DepthTexture:
  581. texture = this._depthRenderTarget.texture;
  582. break;
  583. case FluidRenderingDebug.DepthBlurredTexture:
  584. texture = this._depthRenderTarget.enableBlur ? this._depthRenderTarget.textureBlur : this._depthRenderTarget.texture;
  585. break;
  586. case FluidRenderingDebug.ThicknessTexture:
  587. texture = this._thicknessRenderTarget?.texture ?? null;
  588. break;
  589. case FluidRenderingDebug.ThicknessBlurredTexture:
  590. texture = this._thicknessRenderTarget?.enableBlur ? this._thicknessRenderTarget?.textureBlur ?? null : this._thicknessRenderTarget?.texture ?? null;
  591. break;
  592. case FluidRenderingDebug.DiffuseTexture:
  593. if (this._diffuseRenderTarget) {
  594. texture = this._diffuseRenderTarget.texture;
  595. }
  596. break;
  597. }
  598. if (this._debugFeature !== FluidRenderingDebug.Normals) {
  599. effect.setTexture("debugSampler", texture);
  600. if (engine.isWebGPU) {
  601. effect.setTextureSampler("debugSamplerSampler", texture?.getInternalTexture() ?? null);
  602. }
  603. }
  604. }
  605. });
  606. }
  607. /** @internal */
  608. _clearTargets() {
  609. if (this._depthRenderTarget?.renderTarget) {
  610. this._engine.bindFramebuffer(this._depthRenderTarget.renderTarget);
  611. this._engine.clear(this._depthClearColor, true, true, false);
  612. this._engine.unBindFramebuffer(this._depthRenderTarget.renderTarget);
  613. }
  614. if (this._diffuseRenderTarget?.renderTarget) {
  615. this._engine.bindFramebuffer(this._diffuseRenderTarget.renderTarget);
  616. this._engine.clear(this._thicknessClearColor, true, true, false);
  617. this._engine.unBindFramebuffer(this._diffuseRenderTarget.renderTarget);
  618. }
  619. if (this._thicknessRenderTarget?.renderTarget) {
  620. this._engine.bindFramebuffer(this._thicknessRenderTarget.renderTarget);
  621. // we don't clear the depth buffer because it is the depth buffer that is coming from the scene and that we reuse in the thickness rendering pass
  622. this._engine.clear(this._thicknessClearColor, true, false, false);
  623. this._engine.unBindFramebuffer(this._thicknessRenderTarget.renderTarget);
  624. }
  625. }
  626. /** @internal */
  627. _render(fluidObject) {
  628. if (this._needInitialization || !fluidObject.isReady()) {
  629. return;
  630. }
  631. const currentRenderTarget = this._engine._currentRenderTarget;
  632. this._engine.setState(false, undefined, undefined, undefined, true);
  633. this._engine.setDepthBuffer(true);
  634. this._engine.setDepthWrite(true);
  635. this._engine.setAlphaMode(0);
  636. // Render the particles in the depth texture
  637. if (this._depthRenderTarget?.renderTarget) {
  638. this._engine.bindFramebuffer(this._depthRenderTarget.renderTarget);
  639. fluidObject.renderDepthTexture();
  640. this._engine.unbindInstanceAttributes();
  641. this._engine.unBindFramebuffer(this._depthRenderTarget.renderTarget);
  642. }
  643. // Render the particles in the diffuse texture
  644. if (this._diffuseRenderTarget?.renderTarget) {
  645. this._engine.bindFramebuffer(this._diffuseRenderTarget.renderTarget);
  646. fluidObject.renderDiffuseTexture();
  647. this._engine.unbindInstanceAttributes();
  648. this._engine.unBindFramebuffer(this._diffuseRenderTarget.renderTarget);
  649. }
  650. // Render the particles in the thickness texture
  651. if (this._thicknessRenderTarget?.renderTarget) {
  652. this._engine.bindFramebuffer(this._thicknessRenderTarget.renderTarget);
  653. fluidObject.renderThicknessTexture();
  654. this._engine.unbindInstanceAttributes();
  655. this._engine.unBindFramebuffer(this._thicknessRenderTarget.renderTarget);
  656. }
  657. // Run the blur post processes
  658. this._depthRenderTarget?.applyBlurPostProcesses();
  659. this._diffuseRenderTarget?.applyBlurPostProcesses();
  660. this._thicknessRenderTarget?.applyBlurPostProcesses();
  661. if (currentRenderTarget) {
  662. this._engine.bindFramebuffer(currentRenderTarget);
  663. }
  664. }
  665. /**
  666. * Releases all the ressources used by the class
  667. * @param onlyPostProcesses If true, releases only the ressources used by the render post processes
  668. */
  669. dispose(onlyPostProcesses = false) {
  670. if (!onlyPostProcesses) {
  671. this._depthRenderTarget?.dispose();
  672. this._depthRenderTarget = null;
  673. this._diffuseRenderTarget?.dispose();
  674. this._diffuseRenderTarget = null;
  675. this._thicknessRenderTarget?.dispose();
  676. this._thicknessRenderTarget = null;
  677. }
  678. if (this._renderPostProcess && this._camera) {
  679. this._camera.detachPostProcess(this._renderPostProcess);
  680. }
  681. this._renderPostProcess?.dispose();
  682. this._renderPostProcess = null;
  683. this._needInitialization = false;
  684. }
  685. }
  686. //# sourceMappingURL=fluidRenderingTargetRenderer.js.map