SubSurfaceScatteringPostProcess.ts 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import { Nullable } from "../types";
  2. import { Camera } from "../Cameras/camera";
  3. import { Effect } from "../Materials/effect";
  4. import { Texture } from "../Materials/Textures/texture";
  5. import { PostProcess, PostProcessOptions } from "./postProcess";
  6. import { Engine } from "../Engines/engine";
  7. import { Scene } from "../scene";
  8. import { Constants } from "../Engines/constants";
  9. import { Logger } from "../Misc/logger";
  10. import "../Shaders/imageProcessing.fragment";
  11. import "../Shaders/subSurfaceScattering.fragment";
  12. import "../Shaders/postprocess.vertex";
  13. /**
  14. * Scene compositor post process
  15. */
  16. export class SubSurfaceScatteringPostProcess extends PostProcess {
  17. /** @hidden */
  18. public texelWidth: number;
  19. /** @hidden */
  20. public texelHeight: number;
  21. constructor(name: string, scene: Scene, options: number | PostProcessOptions, camera: Nullable<Camera> = null, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Constants.TEXTURETYPE_UNSIGNED_INT) {
  22. super(name, "subSurfaceScattering", ["texelSize", "viewportSize", "metersPerUnit"], ["diffusionS", "diffusionD", "filterRadii", "irradianceSampler", "depthSampler", "albedoSampler"], options, camera, samplingMode || Texture.BILINEAR_SAMPLINGMODE, engine, reusable, null, textureType, "postprocess", undefined, true);
  23. this._scene = scene;
  24. const defines = this._getDefines();
  25. this.updateEffect(defines);
  26. this.onApplyObservable.add((effect: Effect) => {
  27. if (!scene.prePassRenderer) {
  28. Logger.Error("PrePass needs to be enabled for subsurface scattering.");
  29. return;
  30. }
  31. var texelSize = this.texelSize;
  32. effect.setFloat("metersPerUnit", scene.metersPerUnit);
  33. effect.setFloat2("texelSize", texelSize.x, texelSize.y);
  34. effect.setTexture("irradianceSampler", scene.prePassRenderer.prePassRT.textures[1]);
  35. effect.setTexture("depthSampler", scene.prePassRenderer.prePassRT.textures[2]);
  36. effect.setTexture("albedoSampler", scene.prePassRenderer.prePassRT.textures[3]);
  37. effect.setFloat2("viewportSize",
  38. Math.tan(scene.activeCamera!.fov / 2) * scene.getEngine().getAspectRatio(scene.activeCamera!, true),
  39. Math.tan(scene.activeCamera!.fov / 2));
  40. effect.setArray3("diffusionS", scene.prePassRenderer.ssDiffusionS);
  41. effect.setArray("diffusionD", scene.prePassRenderer.ssDiffusionD);
  42. effect.setArray("filterRadii", scene.prePassRenderer.ssFilterRadii);
  43. });
  44. }
  45. private _getDefines(): Nullable<string> {
  46. const engine = this.getEngine();
  47. if (!engine) {
  48. return null;
  49. }
  50. let defines = "";
  51. // if (this._scene.imageProcessingConfiguration.applyByPostProcess) {
  52. // // We must output linear color for post process
  53. // defines = defines + "#define LINEAR_OUTPUT\n";
  54. // }
  55. return defines;
  56. }
  57. }