Skip to content

Commit

Permalink
Formalized the progressive pipeline concept which removed a lot of du…
Browse files Browse the repository at this point in the history
…plicated code
  • Loading branch information
AlexandruPopovici committed Oct 14, 2024
1 parent 58c86f3 commit 19250e8
Show file tree
Hide file tree
Showing 12 changed files with 73 additions and 330 deletions.
2 changes: 1 addition & 1 deletion packages/viewer-sandbox/src/Sandbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ export default class Sandbox {
this.addStreamControls(url)
this.addViewControls()
this.addBatches()
// this.properties = await this.viewer.getObjectProperties()
this.properties = await this.viewer.getObjectProperties()
this.batchesParams.totalBvhSize = this.getBVHSize()
this.refresh()
})
Expand Down
7 changes: 4 additions & 3 deletions packages/viewer/src/modules/SpeckleRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@ import { SpeckleTypeAllRenderables } from './loaders/GeometryConverter.js'
import SpeckleInstancedMesh from './objects/SpeckleInstancedMesh.js'
import { MeshBatch } from './batching/MeshBatch.js'
import { RenderTree } from './tree/RenderTree.js'
import { GPipeline } from './pipeline/G/GPipeline.js'
import { GPipeline } from './pipeline/G/Pipelines/GPipeline.js'
import { DefaultPipeline } from './pipeline/G/Pipelines/DefaultPipeline.js'
import { GProgressivePipeline } from './pipeline/G/Pipelines/GProgressivePipeline.js'

export class RenderingStats {
private renderTimeAcc = 0
Expand Down Expand Up @@ -230,11 +231,11 @@ export default class SpeckleRenderer {
this._speckleCamera = value
this._speckleCamera.on(CameraEvent.Dynamic, () => {
this._needsRender = true
this.pipeline.onStationaryEnd()
this.pipeline instanceof GProgressivePipeline && this.pipeline.onStationaryEnd()
})
this._speckleCamera.on(CameraEvent.Stationary, () => {
this._needsRender = true
this.pipeline.onStationaryBegin()
this.pipeline instanceof GProgressivePipeline && this.pipeline.onStationaryBegin()
})
this._speckleCamera.on(CameraEvent.FrameUpdate, (needsUpdate: boolean) => {
this.needsRender = needsUpdate
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
import { PerspectiveCamera, OrthographicCamera } from 'three'
import SpeckleRenderer from '../../../SpeckleRenderer.js'
import { GBlendPass } from '../GBlendPass.js'
import { GDepthPass, DepthType } from '../GDepthPass.js'
import { GPass, ObjectVisibility, ProgressiveGPass } from '../GPass.js'
import { GPipeline } from '../GPipeline.js'
import { ObjectVisibility } from '../GPass.js'
import { ObjectLayers } from '../../../../IViewer.js'
import { GProgressiveAOPass } from '../GProgressiveAOPass.js'
import { GViewportPass } from '../GViewportPass.js'
import { GProgressivePipeline } from './GProgressivePipeline.js'

export class ArcticViewPipeline extends GPipeline {
protected accumulationFrameIndex: number = 0
protected accumulationFrameCount: number = 32
protected dynamicStage: Array<GPass> = []
protected progressiveStage: Array<GPass> = []

export class ArcticViewPipeline extends GProgressivePipeline {
constructor(speckleRenderer: SpeckleRenderer) {
super(speckleRenderer)

Expand Down Expand Up @@ -55,35 +49,4 @@ export class ArcticViewPipeline extends GPipeline {

this.passList = this.progressiveStage
}

public update(camera: PerspectiveCamera | OrthographicCamera): void {
this.passList.forEach((pass: GPass) => {
pass.enabled && pass.update?.(camera)
if (pass instanceof ProgressiveGPass) {
pass.frameIndex = this.accumulationFrameIndex
}
})
this.accumulationFrameIndex++

if (this.accumulationFrameIndex === this.accumulationFrameCount)
this.onAccumulationComplete()
}

public resize(width: number, height: number) {
this.dynamicStage.forEach((pass: GPass) => pass.setSize?.(width, height))
this.progressiveStage.forEach((pass: GPass) => pass.setSize?.(width, height))
}

public onStationaryBegin() {
this.accumulationFrameIndex = 0
this.passList = this.progressiveStage
}

public onStationaryEnd() {
this.passList = this.dynamicStage
}

public onAccumulationComplete() {
console.warn('Accumulation Complete')
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
import { OrthographicCamera, PerspectiveCamera } from 'three'
import { ObjectLayers, WorldTree } from '../../../../index.js'
import SpeckleRenderer from '../../../SpeckleRenderer.js'
import { GColorPass } from '../GColorPass.js'
import { GPass, ProgressiveGPass } from '../GPass.js'
import { GPipeline } from '../GPipeline.js'
import { GPipeline } from './GPipeline.js'
import { GBasitPass } from '../GBasitPass.js'

export class BasitPipeline extends GPipeline {
protected accumulationFrameIndex: number = 0
protected accumulationFrameCount: number = 16
protected dynamicStage: Array<GPass> = []
protected progressiveStage: Array<GPass> = []

constructor(speckleRenderer: SpeckleRenderer, tree: WorldTree) {
super(speckleRenderer)

Expand All @@ -25,22 +18,4 @@ export class BasitPipeline extends GPipeline {

this.passList.push(basitPass, transparentColorPass)
}

public update(camera: PerspectiveCamera | OrthographicCamera): void {
this.passList.forEach((pass: GPass) => {
pass.enabled && pass.update?.(camera)
if (pass instanceof ProgressiveGPass) {
pass.frameIndex = this.accumulationFrameIndex
}
})
this.accumulationFrameIndex++

if (this.accumulationFrameIndex === this.accumulationFrameCount)
this.onAccumulationComplete()
}

public resize(width: number, height: number) {
this.dynamicStage.forEach((pass: GPass) => pass.setSize?.(width, height))
this.progressiveStage.forEach((pass: GPass) => pass.setSize?.(width, height))
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
import { OrthographicCamera, PerspectiveCamera } from 'three'
import { ObjectLayers } from '../../../../index.js'
import SpeckleRenderer from '../../../SpeckleRenderer.js'
import { GColorPass } from '../GColorPass.js'
import { DepthType, GDepthPass } from '../GDepthPass.js'
import { GPass, ObjectVisibility, ProgressiveGPass } from '../GPass.js'
import { GPipeline } from '../GPipeline.js'
import { ObjectVisibility } from '../GPass.js'
import { GProgressiveAOPass } from '../GProgressiveAOPass.js'
import { GBlendPass } from '../GBlendPass.js'
import { GOutputPass, InputType } from '../GOutputPass.js'
import { GTAAPass } from '../GTAAPass.js'
import { GProgressivePipeline } from './GProgressivePipeline.js'

export class DefaultPipeline extends GPipeline {
protected accumulationFrameIndex: number = 0
protected accumulationFrameCount: number = 16
protected dynamicStage: Array<GPass> = []
protected progressiveStage: Array<GPass> = []

export class DefaultPipeline extends GProgressivePipeline {
constructor(speckleRenderer: SpeckleRenderer) {
super(speckleRenderer)

Expand All @@ -24,11 +18,6 @@ export class DefaultPipeline extends GPipeline {
depthPass.setLayers([ObjectLayers.STREAM_CONTENT_MESH])
depthPass.setVisibility(ObjectVisibility.DEPTH)

// const normalPass = new GNormalsPass()
// normalPass.setLayers([ObjectLayers.STREAM_CONTENT_MESH])
// normalPass.setVisibility(ObjectVisibility.OPAQUE)
// normalPass.setJitter(true)

const opaqueColorPass = new GColorPass()
opaqueColorPass.setLayers([
ObjectLayers.PROPS,
Expand Down Expand Up @@ -114,35 +103,4 @@ export class DefaultPipeline extends GPipeline {

this.passList = this.progressiveStage
}

public update(camera: PerspectiveCamera | OrthographicCamera): void {
this.passList.forEach((pass: GPass) => {
pass.enabled && pass.update?.(camera)
if (pass instanceof ProgressiveGPass) {
pass.frameIndex = this.accumulationFrameIndex
}
})
this.accumulationFrameIndex++

if (this.accumulationFrameIndex === this.accumulationFrameCount)
this.onAccumulationComplete()
}

public resize(width: number, height: number) {
this.dynamicStage.forEach((pass: GPass) => pass.setSize?.(width, height))
this.progressiveStage.forEach((pass: GPass) => pass.setSize?.(width, height))
}

public onStationaryBegin() {
this.accumulationFrameIndex = 0
this.passList = this.progressiveStage
}

public onStationaryEnd() {
this.passList = this.dynamicStage
}

public onAccumulationComplete() {
console.warn('Accumulation Complete')
}
}
43 changes: 3 additions & 40 deletions packages/viewer/src/modules/pipeline/G/Pipelines/EdgesPipeline.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
import { PerspectiveCamera, OrthographicCamera } from 'three'
import SpeckleRenderer from '../../../SpeckleRenderer.js'
import { GBlendPass } from '../GBlendPass.js'
import { GColorPass } from '../GColorPass.js'
import { GDepthPass, DepthType } from '../GDepthPass.js'
import { GEdgePass } from '../GEdgesPass.js'
import { GNormalsPass } from '../GNormalPass.js'
import { GPass, ObjectVisibility, ProgressiveGPass } from '../GPass.js'
import { GPipeline } from '../GPipeline.js'
import { ObjectVisibility } from '../GPass.js'
import { GProgressiveAOPass } from '../GProgressiveAOPass.js'
import { GTAAPass } from '../GTAAPass.js'
import { ObjectLayers } from '../../../../IViewer.js'
import { GProgressivePipeline } from './GProgressivePipeline.js'

export class EdgesPipeline extends GPipeline {
protected accumulationFrameIndex: number = 0
protected accumulationFrameCount: number = 16
protected dynamicStage: Array<GPass> = []
protected progressiveStage: Array<GPass> = []

export class EdgesPipeline extends GProgressivePipeline {
constructor(speckleRenderer: SpeckleRenderer) {
super(speckleRenderer)

Expand Down Expand Up @@ -114,35 +108,4 @@ export class EdgesPipeline extends GPipeline {

this.passList = this.progressiveStage
}

public update(camera: PerspectiveCamera | OrthographicCamera): void {
this.passList.forEach((pass: GPass) => {
pass.enabled && pass.update?.(camera)
if (pass instanceof ProgressiveGPass) {
pass.frameIndex = this.accumulationFrameIndex
}
})
this.accumulationFrameIndex++

if (this.accumulationFrameIndex === this.accumulationFrameCount)
this.onAccumulationComplete()
}

public resize(width: number, height: number) {
this.dynamicStage.forEach((pass: GPass) => pass.setSize?.(width, height))
this.progressiveStage.forEach((pass: GPass) => pass.setSize?.(width, height))
}

public onStationaryBegin() {
this.accumulationFrameIndex = 0
this.passList = this.progressiveStage
}

public onStationaryEnd() {
this.passList = this.dynamicStage
}

public onAccumulationComplete() {
console.warn('Accumulation Complete')
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Matrix4, OrthographicCamera, PerspectiveCamera, Plane, Vector2 } from 'three'
import { GPass, ObjectVisibility } from './GPass.js'
import SpeckleRenderer from '../../SpeckleRenderer.js'
import { BatchUpdateRange } from '../../batching/Batch.js'
import { GPass, ObjectVisibility } from '../GPass.js'
import SpeckleRenderer from '../../../SpeckleRenderer.js'
import { BatchUpdateRange } from '../../../batching/Batch.js'

export abstract class GPipeline {
protected speckleRenderer: SpeckleRenderer
Expand Down Expand Up @@ -106,12 +106,6 @@ export abstract class GPipeline {
this.passList.forEach((pass: GPass) => pass.setSize?.(width, height))
}

public onStationaryBegin() {}

public onStationaryEnd() {}

public onAccumulationComplete() {}

/**
* Generate a number in the Halton Sequence at a given index. This is
* shamelessly stolen from the pseudocode on the Wikipedia page
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { OrthographicCamera, PerspectiveCamera } from 'three'
import { GPass, ProgressiveGPass } from '../GPass.js'
import { GPipeline } from './GPipeline.js'

export abstract class GProgressivePipeline extends GPipeline {
protected accumulationFrameIndex: number = 0
protected accumulationFrameCount: number = 16
protected dynamicStage: Array<GPass> = []
protected progressiveStage: Array<GPass> = []

public update(camera: PerspectiveCamera | OrthographicCamera): void {
this.passList.forEach((pass: GPass) => {
pass.enabled && pass.update?.(camera)
if (pass instanceof ProgressiveGPass) {
pass.frameIndex = this.accumulationFrameIndex
}
})
this.accumulationFrameIndex++

if (this.accumulationFrameIndex === this.accumulationFrameCount)
this.onAccumulationComplete()
}

public resize(width: number, height: number) {
super.resize(width, height)
this.dynamicStage.forEach((pass: GPass) => pass.setSize?.(width, height))
this.progressiveStage.forEach((pass: GPass) => pass.setSize?.(width, height))
}

public onStationaryBegin() {
this.accumulationFrameIndex = 0
this.passList = this.progressiveStage
}

public onStationaryEnd() {
this.passList = this.dynamicStage
}

public onAccumulationComplete() {
console.warn('Accumulation Complete')
}
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
import { PerspectiveCamera, OrthographicCamera, RepeatWrapping, Texture } from 'three'
import { RepeatWrapping, Texture } from 'three'
import SpeckleRenderer from '../../../SpeckleRenderer.js'
import { GDepthPass, DepthType } from '../GDepthPass.js'
import { GEdgePass } from '../GEdgesPass.js'
import { GNormalsPass } from '../GNormalPass.js'
import { GPass, ObjectVisibility, ProgressiveGPass } from '../GPass.js'
import { GPipeline } from '../GPipeline.js'
import { ObjectVisibility } from '../GPass.js'
import { GTAAPass } from '../GTAAPass.js'
import { AssetType, ObjectLayers } from '../../../../IViewer.js'
import { Assets } from '../../../Assets.js'
import paperTex from '../../../../assets/paper.png'
import Logger from '../../../utils/Logger.js'
import { GProgressivePipeline } from './GProgressivePipeline.js'

export class PenViewPipeline extends GPipeline {
protected accumulationFrameIndex: number = 0
protected accumulationFrameCount: number = 16
protected dynamicStage: Array<GPass> = []
protected progressiveStage: Array<GPass> = []

export class PenViewPipeline extends GProgressivePipeline {
constructor(speckleRenderer: SpeckleRenderer) {
super(speckleRenderer)

Expand Down Expand Up @@ -75,35 +70,4 @@ export class PenViewPipeline extends GPipeline {
Logger.error(`Matcap texture failed to load ${reason}`)
})
}

public update(camera: PerspectiveCamera | OrthographicCamera): void {
this.passList.forEach((pass: GPass) => {
pass.enabled && pass.update?.(camera)
if (pass instanceof ProgressiveGPass) {
pass.frameIndex = this.accumulationFrameIndex
}
})
this.accumulationFrameIndex++

if (this.accumulationFrameIndex === this.accumulationFrameCount)
this.onAccumulationComplete()
}

public resize(width: number, height: number) {
this.dynamicStage.forEach((pass: GPass) => pass.setSize?.(width, height))
this.progressiveStage.forEach((pass: GPass) => pass.setSize?.(width, height))
}

public onStationaryBegin() {
this.accumulationFrameIndex = 0
this.passList = this.progressiveStage
}

public onStationaryEnd() {
this.passList = this.dynamicStage
}

public onAccumulationComplete() {
console.warn('Accumulation Complete')
}
}
Loading

0 comments on commit 19250e8

Please sign in to comment.