From 370c256318796d3f54ff13fae444770817faa694 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Guimmara?= Date: Fri, 11 Apr 2025 10:19:25 +0200 Subject: [PATCH 1/3] wip: custom render passes --- src/renderer/RenderPipeline.ts | 15 +++++++++++++-- src/renderer/RenderingOptions.ts | 8 ++++++++ src/renderer/c3DEngine.ts | 7 ++++++- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/renderer/RenderPipeline.ts b/src/renderer/RenderPipeline.ts index 7573af91d0..6fb0055267 100644 --- a/src/renderer/RenderPipeline.ts +++ b/src/renderer/RenderPipeline.ts @@ -85,7 +85,7 @@ export default class RenderPipeline { this.sceneRenderTarget = null; } - prepareRenderTargets(width: number, height: number, samples: number) { + prepareRenderTargets(width: number, height: number, samples: number, customPasses?: Pass[]) { if ( !this.sceneRenderTarget || this.sceneRenderTarget.width !== width || @@ -114,6 +114,12 @@ export default class RenderPipeline { // the effect composer will render this render target to the canvas. this.effectComposer.addPass(new TexturePass(this.sceneRenderTarget.texture)); + if (customPasses) { + for (const pass of customPasses) { + this.effectComposer.addPass(pass); + } + } + // Final pass to output to the canvas (including colorspace transformation). this.effectComposer.addPass(new OutputPass()); } @@ -144,7 +150,12 @@ export default class RenderPipeline { const requiredSamples = 4; // No need for more const samples = options.enableMSAA ? Math.min(maxSamples, requiredSamples) : 0; - const { composer, target } = this.prepareRenderTargets(width, height, samples); + const { composer, target } = this.prepareRenderTargets( + width, + height, + samples, + options.customPasses, + ); renderer.setRenderTarget(this.sceneRenderTarget); diff --git a/src/renderer/RenderingOptions.ts b/src/renderer/RenderingOptions.ts index 93ebd85d29..e60f5e6308 100644 --- a/src/renderer/RenderingOptions.ts +++ b/src/renderer/RenderingOptions.ts @@ -1,3 +1,5 @@ +import type { Pass } from 'three/examples/jsm/postprocessing/Pass.js'; + /** * Exposes rendering options for the current Giro3D instance. * @@ -53,6 +55,11 @@ class RenderingOptions { */ enableMSAA: boolean; + /** + * Custom render passes to use in the render pipeline. + */ + customPasses?: Pass[]; + constructor() { this.enableEDL = false; this.EDLStrength = 0.7; @@ -62,6 +69,7 @@ class RenderingOptions { this.inpaintingDepthContribution = 0.5; this.enablePointCloudOcclusion = false; this.enableMSAA = true; + this.customPasses = undefined; } } diff --git a/src/renderer/c3DEngine.ts b/src/renderer/c3DEngine.ts index e2e72c4b04..64bf8aaaad 100644 --- a/src/renderer/c3DEngine.ts +++ b/src/renderer/c3DEngine.ts @@ -55,7 +55,12 @@ function createRenderTarget( * @returns True if the options requires a custom pipeline. */ function requiresCustomPipeline(options: RenderingOptions) { - return options.enableEDL || options.enableInpainting || options.enablePointCloudOcclusion; + return ( + options.enableEDL || + options.enableInpainting || + options.enablePointCloudOcclusion || + (options.customPasses !== undefined && options.customPasses.length > 0) + ); } function createErrorMessage() { -- GitLab From 0accf00daa6b27ef19dd54d94841bfb1543176d6 Mon Sep 17 00:00:00 2001 From: Augustin Trancart Date: Fri, 11 Apr 2025 10:46:09 +0200 Subject: [PATCH 2/3] wip examples postprocessing --- examples/ign_data.js | 16 ++++++++++++++++ examples/point_cloud_classification.js | 14 +++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/examples/ign_data.js b/examples/ign_data.js index 08f5a13341..972db385f7 100644 --- a/examples/ign_data.js +++ b/examples/ign_data.js @@ -1,4 +1,5 @@ import { + Vector2, Vector3, CubeTextureLoader, DirectionalLight, @@ -8,6 +9,8 @@ import { MathUtils, DoubleSide, } from 'three'; +import { Pass } from 'three/examples/jsm/postprocessing/Pass.js'; +import { DotScreenPass } from 'three/examples/jsm/postprocessing/DotScreenPass.js'; import { MapControls } from 'three/examples/jsm/controls/MapControls.js'; import GeoJSON from 'ol/format/GeoJSON.js'; @@ -25,6 +28,7 @@ import Giro3dMap from '@giro3d/giro3d/entities/Map.js'; import Inspector from '@giro3d/giro3d/gui/Inspector.js'; import BilFormat from '@giro3d/giro3d/formats/BilFormat.js'; import FeatureCollection from '@giro3d/giro3d/entities/FeatureCollection.js'; +import { BokehPass } from 'three/examples/jsm/postprocessing/BokehPass.js'; import StatusBar from './widgets/StatusBar.js'; @@ -45,6 +49,18 @@ const instance = new Instance({ backgroundColor: SKY_COLOR, }); +function initPass() { + // const pass = new DotScreenPass(new Vector2(0, 0), 0.1, 80); + instance.engine._renderPipeline.effectComposer.addPass(pass); + instance.removeEventListener('after-render', initPass); +} +const pass = new BokehPass(instance.scene, instance.view.camera, { + focus: 50, + aperture: 0.05 * 0.00001, + maxblur: 0.05, +}); +instance.engine.renderingOptions.customPasses = [pass]; + const extent = new Extent('EPSG:2154', -111629.52, 1275028.84, 5976033.79, 7230161.64); // create a map diff --git a/examples/point_cloud_classification.js b/examples/point_cloud_classification.js index 4c68e6348c..55421975fd 100644 --- a/examples/point_cloud_classification.js +++ b/examples/point_cloud_classification.js @@ -1,4 +1,4 @@ -import { Color } from 'three'; +import { Color, Vector2 } from 'three'; import { MapControls } from 'three/examples/jsm/controls/MapControls.js'; import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer.js'; @@ -11,6 +11,9 @@ import StatusBar from './widgets/StatusBar.js'; import { bindColorPicker } from './widgets/bindColorPicker.js'; import { bindSlider } from './widgets/bindSlider.js'; import { bindToggle } from './widgets/bindToggle.js'; +import { Pass } from 'three/examples/jsm/postprocessing/Pass.js'; +import { DotScreenPass } from 'three/examples/jsm/postprocessing/DotScreenPass.js'; +import { BokehPass } from 'three/examples/jsm/postprocessing/BokehPass.js'; Instance.registerCRS( 'EPSG:2154', @@ -22,6 +25,15 @@ const instance = new Instance({ crs: 'EPSG:2154', backgroundColor: null, // To make the canvas transparent and show the actual CSS background }); +// function initPass() { +// class BlurPass extends Pass { + +// } +// instance.engine._renderPipeline.effectComposer.addPass(pass); +// instance.removeEventListener('after-render', initPass); +// } +const pass = new DotScreenPass(new Vector2(0, 0), 0.1, 80); +instance.engine.renderingOptions.customPasses = [pass]; // Enables post-processing effects to improve readability of point cloud. instance.renderingOptions.enableEDL = true; -- GitLab From f97c886f3f6a6c91f6099eed1379d0b22fdb2a6d Mon Sep 17 00:00:00 2001 From: Augustin Trancart Date: Fri, 11 Apr 2025 10:51:47 +0200 Subject: [PATCH 3/3] fixup! wip: custom render passes --- src/renderer/RenderPipeline.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/renderer/RenderPipeline.ts b/src/renderer/RenderPipeline.ts index 6fb0055267..7c1c53c19f 100644 --- a/src/renderer/RenderPipeline.ts +++ b/src/renderer/RenderPipeline.ts @@ -3,6 +3,7 @@ import { Color, DepthTexture, FloatType, NearestFilter, WebGLRenderTarget } from import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js'; import { OutputPass } from 'three/examples/jsm/postprocessing/OutputPass.js'; import { TexturePass } from 'three/examples/jsm/postprocessing/TexturePass.js'; +import type { Pass } from 'three/examples/jsm/postprocessing/Pass.js'; import PointCloudRenderer from './PointCloudRenderer'; import type RenderingOptions from './RenderingOptions'; -- GitLab