Appearance
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(): booleansetEnabled(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): booleangetSharedBuffers(): PostProcessSharedBuffers | null— color, depth, and normal targets for passes that need them.render(): boolean— called byViewerCore.render()when enabled. Returnstruewhen 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;
}