rgbdTextureTools.ts 3.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import { Constants } from "../Engines/constants";
  2. import { PostProcess } from "../PostProcesses/postProcess";
  3. import "../Shaders/rgbdDecode.fragment";
  4. import { Engine } from '../Engines/engine';
  5. import "../Engines/Extensions/engine.renderTarget";
  6. declare type Texture = import("../Materials/Textures/texture").Texture;
  7. /**
  8. * Class used to host RGBD texture specific utilities
  9. */
  10. export class RGBDTextureTools {
  11. /**
  12. * Expand the RGBD Texture from RGBD to Half Float if possible.
  13. * @param texture the texture to expand.
  14. */
  15. public static ExpandRGBDTexture(texture: Texture) {
  16. const internalTexture = texture._texture;
  17. if (!internalTexture || !texture.isRGBD) {
  18. return;
  19. }
  20. // Gets everything ready.
  21. const engine = internalTexture.getEngine() as Engine;
  22. const caps = engine.getCaps();
  23. let expandTexture = false;
  24. // If half float available we can uncompress the texture
  25. if (caps.textureHalfFloatRender && caps.textureHalfFloatLinearFiltering) {
  26. expandTexture = true;
  27. internalTexture.type = Constants.TEXTURETYPE_HALF_FLOAT;
  28. }
  29. // If full float available we can uncompress the texture
  30. else if (caps.textureFloatRender && caps.textureFloatLinearFiltering) {
  31. expandTexture = true;
  32. internalTexture.type = Constants.TEXTURETYPE_FLOAT;
  33. }
  34. if (expandTexture) {
  35. // Do not use during decode.
  36. internalTexture.isReady = false;
  37. internalTexture._isRGBD = false;
  38. internalTexture.invertY = false;
  39. }
  40. texture.onLoadObservable.addOnce(() => {
  41. // Expand the texture if possible
  42. if (expandTexture) {
  43. // Simply run through the decode PP.
  44. const rgbdPostProcess = new PostProcess("rgbdDecode", "rgbdDecode", null, null, 1, null, Constants.TEXTURE_TRILINEAR_SAMPLINGMODE, engine, false, undefined, internalTexture.type, undefined, null, false);
  45. // Hold the output of the decoding.
  46. const expandedTexture = engine.createRenderTargetTexture(internalTexture.width, {
  47. generateDepthBuffer: false,
  48. generateMipMaps: false,
  49. generateStencilBuffer: false,
  50. samplingMode: internalTexture.samplingMode,
  51. type: internalTexture.type,
  52. format: Constants.TEXTUREFORMAT_RGBA
  53. });
  54. rgbdPostProcess.getEffect().executeWhenCompiled(() => {
  55. // PP Render Pass
  56. rgbdPostProcess.onApply = (effect) => {
  57. effect._bindTexture("textureSampler", internalTexture);
  58. effect.setFloat2("scale", 1, 1);
  59. };
  60. texture.getScene()!.postProcessManager.directRender([rgbdPostProcess!], expandedTexture, true);
  61. // Cleanup
  62. engine.restoreDefaultFramebuffer();
  63. engine._releaseTexture(internalTexture);
  64. engine._releaseFramebufferObjects(expandedTexture);
  65. if (rgbdPostProcess) {
  66. rgbdPostProcess.dispose();
  67. }
  68. // Internal Swap
  69. expandedTexture._swapAndDie(internalTexture);
  70. // Ready to get rolling again.
  71. internalTexture.isReady = true;
  72. });
  73. }
  74. });
  75. }
  76. }