--- prev: text: 'Exporting Files' link: './exporting-files' next: text: 'Material Extension' link: './material-extension' --- # Render pipeline Threepipe includes a [RenderManager](https://threepipe.org/docs/classes/RenderManager.html) for managing the composition pipeline, and provides helpers for rendering and render target management. The `RenderManager` includes an [EffectComposer](https://threejs.org/docs/#api/en/postprocessing/EffectComposer) from three.js for rendering passes and a [WebGLRenderer](https://threejs.org/docs/#api/en/renderers/WebGLRenderer) for rendering, but the pass management and sorting is managed by the `RenderManager` itself. The `RenderManager` inherits from [RenderTargetManager](https://threepipe.org/docs/classes/RenderTargetManager.html) which provides utilities for creating, tracking and destroying dedicated and temporary render targets. The main render pipeline supports progressive rendering and is fully configurable. Plugins and applications can add custom passes, effects, and shaders to the pipeline. Plugins like [GBufferPlugin](https://threepipe.org/docs/classes/GBufferPlugin.html), [SSAOPlugin](https://threepipe.org/docs/classes/SSAOPlugin.html), [TonemapPlugin](https://threepipe.org/docs/classes/TonemapPlugin.html), etc interact and extend the render pipeline by adding custom passes to the render pipeline and material extensions to the material manager. ## Render Targets Render targets can be created using the `viewer.renderManager.createTarget` and `viewer.renderManager.createTargetCustom` methods. These can then be disposed using the `viewer.renderManager.disposeTarget` method when not needed anymore. Or to create temp targets for one time/temporary use `viewer.renderManager.getTempTarget` and `viewer.renderManager.releaseTempTarget` methods can be used. All created render targets are tracked in the `RenderManager`, and are resized and disposed automatically when needed along with the viewer. ```typescript const newTarget = viewer.renderManager.createTarget({sizeMultiplier: 1}) // or const newTarget2 = viewer.renderManager.createTarget({size: { width: 1024, height: 1024, }, type: HalfFloatType }) // or clone an existing target const newTarget3 = viewer.renderManager.composerTarget.clone() // for multi-sample render target const newTarget4 = viewer.renderManager.createTarget({sizeMultiplier: 1, samples: 4}) // or create a custom target const newTarget5 = viewer.renderManager.createTargetCustom( {width: 1024, height: 1024}, {type: HalfFloatType}, WebGLCubeRenderTarget ) // dispose targets viewer.renderManager.disposeTarget(newTarget) viewer.renderManager.disposeTarget(newTarget2) viewer.renderManager.disposeTarget(newTarget3) viewer.renderManager.disposeTarget(newTarget4) viewer.renderManager.disposeTarget(newTarget5) // get a temporary target const tempTarget = viewer.renderManager.getTempTarget({sizeMultiplier: 1}) // release the temporary target viewer.renderManager.releaseTempTarget(tempTarget) ``` ::: tip Render targets created with a `sizeMultiplier` are automatically resized when the canvas is resized. ::: ## Passes By default, the render pipeline([`ViewerRenderManager`](https://threepipe.org/docs/classes/ViewerRenderManager.html) includes 2 passes - [RenderPass](https://threepipe.org/docs/classes/ExtendedRenderPass.html) for rendering the scene hierarchy and [ScreenPass](https://threepipe.org/docs/classes/ShaderPass) for rendering the final output on the canvas. More passes can be added and removed from the pipeline using the [registerPass](https://threepipe.org/docs/classes/RenderManager.html#registerPass) and [unregisterPass](https://threepipe.org/docs/classes/RenderManager.html#unregisterPass) methods. The pipeline passes need to follow the interface of [IPipelinePass](https://threepipe.org/docs/interfaces/IPipelinePass.html) and [IPipelinePassPlugin](https://threepipe.org/docs/interfaces/IPipelinePassPlugin.html). Which adds some important parameters over the three.js Pass, like pass id and support for defining where the pass should be added in the pipeline and it's dependants. ```typescript const pass = new GBufferRenderPass('customPass', viewer.renderManager.createTarget({sizeMultiplier: 1})) pass.before = ['render'] // Add the pass before the render pass pass.after = [] // Add the pass after these passes (none in this case) pass.required = ['render'] // render pass is required to be in the pipeline for this. throws an error if not found viewer.renderManager.registerPass(pass) ``` ::: info See [PipelinePassPlugin](https://threepipe.org/docs/classes/PipelinePassPlugin.html) for an abstract plugin that provides the boilerplate to create a plugin that registers a custom pass in the pipeline. Check [NormalBufferPlugin](https://threepipe.org/docs/classes/NormalBufferPlugin.html) for an example of that. ::: ::: tip All effects in post-processing or material extension need not be a separate pass in the pipeline. Most effects can be achieved with either extending the scene object material shaders or the Screen Pass material shader using [Material extension](./material-extension) system :::