prePassRendererSceneComponent.ts 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. import { Nullable } from "../types";
  2. import { Scene } from "../scene";
  3. import { ISceneSerializableComponent, SceneComponentConstants } from "../sceneComponent";
  4. import { PrePassRenderer } from "./prePassRenderer";
  5. import { AbstractScene } from "../abstractScene";
  6. import { Color3 } from "../Maths/math.color";
  7. import { Logger } from "../Misc/logger";
  8. // Adds the parser to the scene parsers.
  9. AbstractScene.AddParser(SceneComponentConstants.NAME_PREPASSRENDERER, (parsedData: any, scene: Scene) => {
  10. // Diffusion profiles
  11. if (parsedData.ssDiffusionProfileColors !== undefined && parsedData.ssDiffusionProfileColors !== null) {
  12. scene.enablePrePassRenderer();
  13. if (scene.prePassRenderer) {
  14. for (var index = 0, cache = parsedData.ssDiffusionProfileColors.length; index < cache; index++) {
  15. var color = parsedData.ssDiffusionProfileColors[index];
  16. scene.prePassRenderer.subSurfaceConfiguration.addDiffusionProfile(new Color3(color.r, color.g, color.b));
  17. }
  18. }
  19. }
  20. });
  21. declare module "../abstractScene" {
  22. export interface AbstractScene {
  23. /** @hidden (Backing field) */
  24. _prePassRenderer: Nullable<PrePassRenderer>;
  25. /**
  26. * Gets or Sets the current prepass renderer associated to the scene.
  27. */
  28. prePassRenderer: Nullable<PrePassRenderer>;
  29. /**
  30. * Enables the prepass and associates it with the scene
  31. * @returns the PrePassRenderer
  32. */
  33. enablePrePassRenderer(): Nullable<PrePassRenderer>;
  34. /**
  35. * Disables the prepass associated with the scene
  36. */
  37. disablePrePassRenderer(): void;
  38. }
  39. }
  40. Object.defineProperty(Scene.prototype, "prePassRenderer", {
  41. get: function(this: Scene) {
  42. return this._prePassRenderer;
  43. },
  44. set: function(this: Scene, value: Nullable<PrePassRenderer>) {
  45. if (value && value.isSupported) {
  46. this._prePassRenderer = value;
  47. }
  48. },
  49. enumerable: true,
  50. configurable: true
  51. });
  52. Scene.prototype.enablePrePassRenderer = function(): Nullable<PrePassRenderer> {
  53. if (this._prePassRenderer) {
  54. return this._prePassRenderer;
  55. }
  56. this._prePassRenderer = new PrePassRenderer(this);
  57. if (!this._prePassRenderer.isSupported) {
  58. this._prePassRenderer = null;
  59. Logger.Error("PrePassRenderer needs WebGL 2 support.\n" +
  60. "Maybe you tried to use the following features that need the PrePassRenderer :\n" +
  61. " + Subsurface Scattering");
  62. }
  63. return this._prePassRenderer;
  64. };
  65. Scene.prototype.disablePrePassRenderer = function(): void {
  66. if (!this._prePassRenderer) {
  67. return;
  68. }
  69. this._prePassRenderer.dispose();
  70. this._prePassRenderer = null;
  71. };
  72. /**
  73. * Defines the Geometry Buffer scene component responsible to manage a G-Buffer useful
  74. * in several rendering techniques.
  75. */
  76. export class PrePassRendererSceneComponent implements ISceneSerializableComponent {
  77. /**
  78. * The component name helpful to identify the component in the list of scene components.
  79. */
  80. public readonly name = SceneComponentConstants.NAME_PREPASSRENDERER;
  81. /**
  82. * The scene the component belongs to.
  83. */
  84. public scene: Scene;
  85. /**
  86. * Creates a new instance of the component for the given scene
  87. * @param scene Defines the scene to register the component in
  88. */
  89. constructor(scene: Scene) {
  90. this.scene = scene;
  91. }
  92. /**
  93. * Registers the component in a given scene
  94. */
  95. public register(): void {
  96. this.scene._beforeCameraDrawStage.registerStep(SceneComponentConstants.STEP_BEFORECAMERADRAW_PREPASS, this, this._beforeCameraDraw);
  97. this.scene._afterCameraDrawStage.registerStep(SceneComponentConstants.STEP_AFTERCAMERADRAW_PREPASS, this, this._afterCameraDraw);
  98. this.scene._beforeClearStage.registerStep(SceneComponentConstants.STEP_BEFORECLEARSTAGE_PREPASS, this, this._beforeClearStage);
  99. }
  100. private _beforeCameraDraw() {
  101. if (this.scene.prePassRenderer) {
  102. this.scene.prePassRenderer._beforeCameraDraw();
  103. }
  104. }
  105. private _afterCameraDraw() {
  106. if (this.scene.prePassRenderer) {
  107. this.scene.prePassRenderer._afterCameraDraw();
  108. }
  109. }
  110. private _beforeClearStage() {
  111. if (this.scene.prePassRenderer) {
  112. this.scene.prePassRenderer.clear();
  113. }
  114. }
  115. /**
  116. * Serializes the component data to the specified json object
  117. * @param serializationObject The object to serialize to
  118. */
  119. public serialize(serializationObject: any): void {
  120. if (!this.scene.prePassRenderer) {
  121. return;
  122. }
  123. const ssDiffusionProfileColors = this.scene.prePassRenderer.subSurfaceConfiguration.ssDiffusionProfileColors;
  124. serializationObject.ssDiffusionProfileColors = [];
  125. for (let i = 0; i < ssDiffusionProfileColors.length; i++) {
  126. serializationObject.ssDiffusionProfileColors.push({ r: ssDiffusionProfileColors[i].r,
  127. g: ssDiffusionProfileColors[i].g,
  128. b: ssDiffusionProfileColors[i].b });
  129. }
  130. }
  131. /**
  132. * Adds all the elements from the container to the scene
  133. * @param container the container holding the elements
  134. */
  135. public addFromContainer(container: AbstractScene): void {
  136. // Nothing to do
  137. }
  138. /**
  139. * Removes all the elements in the container from the scene
  140. * @param container contains the elements to remove
  141. * @param dispose if the removed element should be disposed (default: false)
  142. */
  143. public removeFromContainer(container: AbstractScene, dispose?: boolean): void {
  144. // Make sure nothing will be serialized
  145. if (this.scene.prePassRenderer) {
  146. this.scene.prePassRenderer.subSurfaceConfiguration.clearAllDiffusionProfiles();
  147. }
  148. }
  149. /**
  150. * Rebuilds the elements related to this component in case of
  151. * context lost for instance.
  152. */
  153. public rebuild(): void {
  154. // Nothing to do for this component
  155. }
  156. /**
  157. * Disposes the component and the associated ressources
  158. */
  159. public dispose(): void {
  160. // Nothing to do for this component
  161. }
  162. }
  163. PrePassRenderer._SceneComponentInitialization = (scene: Scene) => {
  164. // Register the G Buffer component to the scene.
  165. let component = scene._getComponent(SceneComponentConstants.NAME_PREPASSRENDERER) as PrePassRendererSceneComponent;
  166. if (!component) {
  167. component = new PrePassRendererSceneComponent(scene);
  168. scene._addComponent(component);
  169. }
  170. };