motionBlurPostProcess.ts 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import { Nullable } from "types";
  2. import { Logger } from "Misc/logger";
  3. import { Vector2 } from "Maths/math";
  4. import { Camera } from "Cameras/camera";
  5. import { Effect } from "Materials/effect";
  6. import { PostProcess, PostProcessOptions } from "./postProcess";
  7. import { Constants } from "Engines/constants";
  8. import { GeometryBufferRenderer } from "Rendering/geometryBufferRenderer";
  9. import { Scene } from "scene";
  10. declare type Engine = import("Engines/engine").Engine;
  11. /**
  12. * The Motion Blur Post Process which blurs an image based on the objects velocity in scene.
  13. * Velocity can be affected by each object's rotation, position and scale depending on the transformation speed.
  14. * As an example, all you have to do is to create the post-process:
  15. * var mb = new BABYLON.MotionBlurPostProcess(
  16. * 'mb', // The name of the effect.
  17. * scene, // The scene containing the objects to blur according to their velocity.
  18. * 1.0, // The required width/height ratio to downsize to before computing the render pass.
  19. * camera // The camera to apply the render pass to.
  20. * );
  21. * Then, all objects moving, rotating and/or scaling will be blurred depending on the transformation speed.
  22. */
  23. export class MotionBlurPostProcess extends PostProcess {
  24. /**
  25. * Defines how much the image is blurred by the movement. Default value is equal to 1
  26. */
  27. public motionStrength: number = 1;
  28. /**
  29. * Gets the number of iterations are used for motion blur quality. Default value is equal to 32
  30. */
  31. public get motionBlurSamples(): number {
  32. return this._motionBlurSamples;
  33. }
  34. /**
  35. * Sets the number of iterations to be used for motion blur quality
  36. */
  37. public set motionBlurSamples(samples: number) {
  38. this._motionBlurSamples = samples;
  39. if (this._geometryBufferRenderer) {
  40. this.updateEffect("#define GEOMETRY_SUPPORTED\n#define SAMPLES " + samples.toFixed(1));
  41. }
  42. }
  43. private _motionBlurSamples: number = 32;
  44. private _geometryBufferRenderer: Nullable<GeometryBufferRenderer>;
  45. /**
  46. * Creates a new instance MotionBlurPostProcess
  47. * @param name The name of the effect.
  48. * @param scene The scene containing the objects to blur according to their velocity.
  49. * @param options The required width/height ratio to downsize to before computing the render pass.
  50. * @param camera The camera to apply the render pass to.
  51. * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
  52. * @param engine The engine which the post process will be applied. (default: current engine)
  53. * @param reusable If the post process can be reused on the same frame. (default: false)
  54. * @param textureType Type of textures used when performing the post process. (default: 0)
  55. * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)
  56. */
  57. constructor(name: string, scene: Scene, options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Constants.TEXTURETYPE_UNSIGNED_INT, blockCompilation = false) {
  58. super(name, "motionBlur", ["motionStrength", "motionScale", "screenSize"], ["velocitySampler"], options, camera, samplingMode, engine, reusable, "#define GEOMETRY_SUPPORTED\n#define SAMPLES 64.0", textureType, undefined, null, blockCompilation);
  59. this._geometryBufferRenderer = scene.enableGeometryBufferRenderer();
  60. if (!this._geometryBufferRenderer) {
  61. // Geometry buffer renderer is not supported. So, work as a passthrough.
  62. Logger.Warn("Multiple Render Target support needed to compute object based motion blur");
  63. this.updateEffect();
  64. } else {
  65. // Geometry buffer renderer is supported.
  66. this._geometryBufferRenderer.enableVelocity = true;
  67. this.onApply = (effect: Effect) => {
  68. effect.setVector2("screenSize", new Vector2(this.width, this.height));
  69. effect.setFloat("motionScale", scene.getAnimationRatio());
  70. effect.setFloat("motionStrength", this.motionStrength);
  71. if (this._geometryBufferRenderer) {
  72. const velocityIndex = this._geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.VELOCITY_TEXTURE_TYPE);
  73. effect.setTexture("velocitySampler", this._geometryBufferRenderer.getGBuffer().textures[velocityIndex]);
  74. }
  75. };
  76. }
  77. }
  78. /**
  79. * Disposes the post process.
  80. * @param camera The camera to dispose the post process on.
  81. */
  82. public dispose(camera?: Camera): void {
  83. if (this._geometryBufferRenderer) {
  84. // Clear previous transformation matrices dictionary used to compute objects velocities
  85. this._geometryBufferRenderer._previousTransformationMatrices = { };
  86. }
  87. super.dispose(camera);
  88. }
  89. }