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.