prePassRendererSceneComponent.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. import { Scene } from "../scene.js";
  2. import { SceneComponentConstants } from "../sceneComponent.js";
  3. import { PrePassRenderer } from "./prePassRenderer.js";
  4. import { Logger } from "../Misc/logger.js";
  5. Object.defineProperty(Scene.prototype, "prePassRenderer", {
  6. get: function () {
  7. return this._prePassRenderer;
  8. },
  9. set: function (value) {
  10. if (value && value.isSupported) {
  11. this._prePassRenderer = value;
  12. }
  13. },
  14. enumerable: true,
  15. configurable: true,
  16. });
  17. Scene.prototype.enablePrePassRenderer = function () {
  18. if (this._prePassRenderer) {
  19. return this._prePassRenderer;
  20. }
  21. this._prePassRenderer = new PrePassRenderer(this);
  22. if (!this._prePassRenderer.isSupported) {
  23. this._prePassRenderer = null;
  24. Logger.Error("PrePassRenderer needs WebGL 2 support.\n" + "Maybe you tried to use the following features that need the PrePassRenderer :\n" + " + Subsurface Scattering");
  25. }
  26. return this._prePassRenderer;
  27. };
  28. Scene.prototype.disablePrePassRenderer = function () {
  29. if (!this._prePassRenderer) {
  30. return;
  31. }
  32. this._prePassRenderer.dispose();
  33. this._prePassRenderer = null;
  34. };
  35. /**
  36. * Defines the Geometry Buffer scene component responsible to manage a G-Buffer useful
  37. * in several rendering techniques.
  38. */
  39. export class PrePassRendererSceneComponent {
  40. /**
  41. * Creates a new instance of the component for the given scene
  42. * @param scene Defines the scene to register the component in
  43. */
  44. constructor(scene) {
  45. /**
  46. * The component name helpful to identify the component in the list of scene components.
  47. */
  48. this.name = SceneComponentConstants.NAME_PREPASSRENDERER;
  49. this.scene = scene;
  50. }
  51. /**
  52. * Registers the component in a given scene
  53. */
  54. register() {
  55. this.scene._beforeCameraDrawStage.registerStep(SceneComponentConstants.STEP_BEFORECAMERADRAW_PREPASS, this, this._beforeCameraDraw);
  56. this.scene._afterCameraDrawStage.registerStep(SceneComponentConstants.STEP_AFTERCAMERADRAW_PREPASS, this, this._afterCameraDraw);
  57. this.scene._beforeRenderTargetDrawStage.registerStep(SceneComponentConstants.STEP_BEFORERENDERTARGETDRAW_PREPASS, this, this._beforeRenderTargetDraw);
  58. this.scene._afterRenderTargetDrawStage.registerStep(SceneComponentConstants.STEP_AFTERCAMERADRAW_PREPASS, this, this._afterRenderTargetDraw);
  59. this.scene._beforeClearStage.registerStep(SceneComponentConstants.STEP_BEFORECLEAR_PREPASS, this, this._beforeClearStage);
  60. this.scene._beforeRenderTargetClearStage.registerStep(SceneComponentConstants.STEP_BEFORERENDERTARGETCLEAR_PREPASS, this, this._beforeRenderTargetClearStage);
  61. this.scene._beforeRenderingMeshStage.registerStep(SceneComponentConstants.STEP_BEFORERENDERINGMESH_PREPASS, this, this._beforeRenderingMeshStage);
  62. this.scene._afterRenderingMeshStage.registerStep(SceneComponentConstants.STEP_AFTERRENDERINGMESH_PREPASS, this, this._afterRenderingMeshStage);
  63. }
  64. _beforeRenderTargetDraw(renderTarget, faceIndex, layer) {
  65. if (this.scene.prePassRenderer && !renderTarget.noPrePassRenderer) {
  66. this.scene.prePassRenderer._setRenderTarget(renderTarget._prePassRenderTarget);
  67. this.scene.prePassRenderer._beforeDraw(undefined, faceIndex, layer);
  68. }
  69. }
  70. _afterRenderTargetDraw(renderTarget, faceIndex, layer) {
  71. if (this.scene.prePassRenderer && !renderTarget.noPrePassRenderer) {
  72. this.scene.prePassRenderer._afterDraw(faceIndex, layer);
  73. }
  74. }
  75. _beforeRenderTargetClearStage(renderTarget) {
  76. if (this.scene.prePassRenderer && !renderTarget.noPrePassRenderer) {
  77. if (!renderTarget._prePassRenderTarget) {
  78. renderTarget._prePassRenderTarget = this.scene.prePassRenderer._createRenderTarget(renderTarget.name + "_prePassRTT", renderTarget);
  79. }
  80. this.scene.prePassRenderer._setRenderTarget(renderTarget._prePassRenderTarget);
  81. this.scene.prePassRenderer._clear();
  82. }
  83. }
  84. _beforeCameraDraw(camera) {
  85. if (this.scene.prePassRenderer) {
  86. this.scene.prePassRenderer._setRenderTarget(null);
  87. this.scene.prePassRenderer._beforeDraw(camera);
  88. }
  89. }
  90. _afterCameraDraw() {
  91. if (this.scene.prePassRenderer) {
  92. this.scene.prePassRenderer._afterDraw();
  93. }
  94. }
  95. _beforeClearStage() {
  96. if (this.scene.prePassRenderer) {
  97. this.scene.prePassRenderer._setRenderTarget(null);
  98. this.scene.prePassRenderer._clear();
  99. }
  100. }
  101. _beforeRenderingMeshStage(mesh, subMesh, batch, effect) {
  102. if (!effect) {
  103. return;
  104. }
  105. // Render to MRT
  106. const scene = mesh.getScene();
  107. if (scene.prePassRenderer) {
  108. scene.prePassRenderer.bindAttachmentsForEffect(effect, subMesh);
  109. }
  110. }
  111. _afterRenderingMeshStage(mesh) {
  112. const scene = mesh.getScene();
  113. if (scene.prePassRenderer) {
  114. scene.prePassRenderer.restoreAttachments();
  115. }
  116. }
  117. /**
  118. * Rebuilds the elements related to this component in case of
  119. * context lost for instance.
  120. */
  121. rebuild() {
  122. // Nothing to do for this component
  123. }
  124. /**
  125. * Disposes the component and the associated resources
  126. */
  127. dispose() {
  128. this.scene.disablePrePassRenderer();
  129. }
  130. }
  131. PrePassRenderer._SceneComponentInitialization = (scene) => {
  132. // Register the G Buffer component to the scene.
  133. let component = scene._getComponent(SceneComponentConstants.NAME_PREPASSRENDERER);
  134. if (!component) {
  135. component = new PrePassRendererSceneComponent(scene);
  136. scene._addComponent(component);
  137. }
  138. };
  139. //# sourceMappingURL=prePassRendererSceneComponent.js.map