Skip to content

PostProcessingService ​

Owns the postprocessing library EffectComposer pipeline and a registry of PostProcessPass adapters. Builds shared color, depth, and normal targets that custom passes can sample.

Access ​

Registered under the name "postprocessing". Depends on rendering. Only initialized when rendering.postProcessing.enabled is true in the viewer config (or when setEnabled(true) is called at runtime).

ts
import { PostProcessingService } from "@optellix/xviewr-sdk";

await viewer.ready();
const post = viewer.getService<PostProcessingService>("postprocessing");

Public API ​

  • isEnabled(): boolean
  • setEnabled(enabled: boolean): Promise<void> — lazily sets up the composer the first time it is enabled.
  • updateConfig(config: Partial<PostProcessingConfig>): Promise<void> — rebuilds the pipeline if pass config changed.
  • addPass(pass: PostProcessPass): Promise<boolean>
  • removePass(id: string): boolean
  • getSharedBuffers(): PostProcessSharedBuffers | null — color, depth, and normal targets for passes that need them.
  • render(): boolean — called by ViewerCore.render() when enabled. Returns true when it rendered the frame.
  • resize(width: number, height: number): void

Events ​

This service does not emit events of its own. It listens to viewer:resize to keep targets in sync.

Built-In Passes ​

There are no built-in ambient occlusion passes registered by configuration. Add AO or other effects through addPass() so the implementation can be owned by the application or a dedicated plugin.

Example ​

ts
const post = viewer.getService<PostProcessingService>("postprocessing");

await post.setEnabled(true);

await post.addPass({
  id: "my-pass",
  enabled: true,
  order: 20,
  needsDepthBuffer: true,
  async init(ctx) {
    // build your postprocessing Pass using ctx.sharedBuffers
  },
  getPass() {
    return myPass;
  },
  setSize(w, h) { myPass.setSize(w, h); },
  dispose() { myPass.dispose(); },
});

Pass interface ​

ts
interface PostProcessPass {
  readonly id: string;
  enabled: boolean;
  readonly order?: number;             // ascending render order, default 0
  readonly needsDepthBuffer?: boolean;
  readonly needsNormalBuffer?: boolean;

  init(context: PostProcessPassContext): Promise<void> | void;
  getPass(): any;                      // postprocessing.Pass
  beforeRender?(context: PostProcessPassContext): void;
  setSize?(width: number, height: number): void;
  dispose?(): void;
}

interface PostProcessPassContext {
  scene: THREE.Scene;
  camera: THREE.Camera;
  renderer: THREE.WebGLRenderer;
  width: number;
  height: number;
  sharedBuffers: PostProcessSharedBuffers;
}

interface PostProcessSharedBuffers {
  colorTarget: THREE.WebGLRenderTarget;
  depthTexture: THREE.DepthTexture;
  normalTarget: THREE.WebGLRenderTarget;
  normalTexture: THREE.Texture;
}

XViewr SDK and xConvert CLI documentation.