A lot of changes. Pipeline rework is more or less complete. Added individual output for some pipeline passes that we might want to inspect inside the sandbox.
This commit is contained in:
@@ -30,26 +30,20 @@ export default class Sandbox {
|
||||
tonemapping: 4 //'ACESFilmicToneMapping'
|
||||
}
|
||||
|
||||
public static postParams = {
|
||||
saoEnabled: true,
|
||||
saoParams: {
|
||||
saoBias: 0.15,
|
||||
saoIntensity: 1.25,
|
||||
saoScale: 434,
|
||||
saoKernelRadius: 15,
|
||||
saoMinResolution: 0,
|
||||
saoBlur: true,
|
||||
saoBlurRadius: 4,
|
||||
saoBlurStdDev: 4,
|
||||
saoBlurDepthCutoff: 0.0007
|
||||
},
|
||||
saoScaleOffset: 0,
|
||||
saoNormalsRendering: 2,
|
||||
minDistance: 0.0,
|
||||
maxDistance: 0.008,
|
||||
ssaoKernelRadius: 0.5,
|
||||
progressiveAO: 0,
|
||||
progressive: true
|
||||
public static pipelineParams = {
|
||||
pipelineOutput: 8,
|
||||
dynamicAoEnabled: true,
|
||||
dynamicAoParams: {
|
||||
intensity: 1.25,
|
||||
scale: 0,
|
||||
kernelRadius: 10,
|
||||
bias: 0.15,
|
||||
normalsType: 2,
|
||||
blurEnabled: true,
|
||||
blurRadius: 4,
|
||||
blurStdDev: 4,
|
||||
blurDepthCutoff: 0.0007
|
||||
}
|
||||
}
|
||||
|
||||
public static lightParams: SunLightConfiguration = {
|
||||
@@ -343,33 +337,88 @@ export default class Sandbox {
|
||||
this.viewer.getRenderer().renderer.toneMapping = Sandbox.sceneParams.tonemapping
|
||||
this.viewer.requestRender()
|
||||
})
|
||||
postFolder
|
||||
.addInput(Sandbox.postParams, 'saoEnabled', { label: 'SAO-ENABLED' })
|
||||
.on('change', () => {
|
||||
this.viewer.getRenderer().pipelineOptions = Sandbox.postParams
|
||||
this.viewer.requestRender()
|
||||
})
|
||||
postFolder
|
||||
.addInput(Sandbox.postParams.saoParams, 'saoBias', {
|
||||
min: -1,
|
||||
max: 1
|
||||
|
||||
const pipelineFolder = this.tabs.pages[1].addFolder({
|
||||
title: 'Pipeline',
|
||||
expanded: true
|
||||
})
|
||||
pipelineFolder
|
||||
.addInput(Sandbox.pipelineParams, 'pipelineOutput', {
|
||||
options: {
|
||||
DEPTH_RGBA: 0,
|
||||
DEPTH: 1,
|
||||
COLOR: 2,
|
||||
GEOMETRY_NORMALS: 3,
|
||||
RECONSTRUCTED_NORMALS: 4,
|
||||
DYNAMIC_AO: 5,
|
||||
DYNAMIC_AO_BLURED: 6,
|
||||
PROGRESSIVE_AO: 7,
|
||||
FINAL: 8
|
||||
}
|
||||
})
|
||||
.on('change', () => {
|
||||
this.viewer.getRenderer().pipelineOptions = Sandbox.postParams
|
||||
this.viewer.requestRender()
|
||||
})
|
||||
postFolder
|
||||
.addInput(Sandbox.postParams.saoParams, 'saoIntensity', {
|
||||
min: 0,
|
||||
max: 5
|
||||
})
|
||||
.on('change', () => {
|
||||
this.viewer.getRenderer().pipelineOptions = Sandbox.postParams
|
||||
this.viewer.getRenderer().pipelineOptions = Sandbox.pipelineParams
|
||||
this.viewer.requestRender()
|
||||
})
|
||||
// postFolder
|
||||
// .addInput(Sandbox.postParams, 'saoEnabled', { label: 'SAO-ENABLED' })
|
||||
// .on('change', () => {
|
||||
// this.viewer.getRenderer().pipelineOptions = Sandbox.postParams
|
||||
// this.viewer.requestRender()
|
||||
// })
|
||||
// postFolder
|
||||
// .addInput(Sandbox.postParams.saoParams, 'saoBias', {
|
||||
// min: -1,
|
||||
// max: 1
|
||||
// })
|
||||
// .on('change', () => {
|
||||
// this.viewer.getRenderer().pipelineOptions = Sandbox.postParams
|
||||
// this.viewer.requestRender()
|
||||
// })
|
||||
// postFolder
|
||||
// .addInput(Sandbox.postParams.saoParams, 'saoIntensity', {
|
||||
// min: 0,
|
||||
// max: 5
|
||||
// })
|
||||
// .on('change', () => {
|
||||
// this.viewer.getRenderer().pipelineOptions = Sandbox.postParams
|
||||
// this.viewer.requestRender()
|
||||
// })
|
||||
|
||||
// // postFolder
|
||||
// // .addInput(Sandbox.postParams.saoParams, 'saoScale', {
|
||||
// // min: 0,
|
||||
// // max: 100
|
||||
// // })
|
||||
// // .on('change', () => {
|
||||
// // this.viewer.getRenderer().pipelineOptions = Sandbox.postParams
|
||||
// // this.viewer.requestRender()
|
||||
// // })
|
||||
// postFolder
|
||||
// .addInput(Sandbox.postParams, 'saoScaleOffset', {
|
||||
// min: -100,
|
||||
// max: 100
|
||||
// })
|
||||
// .on('change', () => {
|
||||
// this.viewer.getRenderer().pipelineOptions = Sandbox.postParams
|
||||
// this.viewer.requestRender()
|
||||
// })
|
||||
|
||||
// postFolder
|
||||
// .addInput(Sandbox.postParams.saoParams, 'saoScale', {
|
||||
// .addInput(Sandbox.postParams, 'saoNormalsRendering', {
|
||||
// options: {
|
||||
// DEFAULT: 0,
|
||||
// ADVANCED: 1,
|
||||
// ACCURATE: 2
|
||||
// }
|
||||
// })
|
||||
// .on('change', () => {
|
||||
// this.viewer.getRenderer().pipelineOptions = Sandbox.postParams
|
||||
// this.viewer.requestRender()
|
||||
// })
|
||||
|
||||
// postFolder
|
||||
// .addInput(Sandbox.postParams.saoParams, 'saoKernelRadius', {
|
||||
// min: 0,
|
||||
// max: 100
|
||||
// })
|
||||
@@ -377,97 +426,65 @@ export default class Sandbox {
|
||||
// this.viewer.getRenderer().pipelineOptions = Sandbox.postParams
|
||||
// this.viewer.requestRender()
|
||||
// })
|
||||
postFolder
|
||||
.addInput(Sandbox.postParams, 'saoScaleOffset', {
|
||||
min: -100,
|
||||
max: 100
|
||||
})
|
||||
.on('change', () => {
|
||||
this.viewer.getRenderer().pipelineOptions = Sandbox.postParams
|
||||
this.viewer.requestRender()
|
||||
})
|
||||
|
||||
postFolder
|
||||
.addInput(Sandbox.postParams, 'saoNormalsRendering', {
|
||||
options: {
|
||||
DEFAULT: 0,
|
||||
ADVANCED: 1,
|
||||
ACCURATE: 2
|
||||
}
|
||||
})
|
||||
.on('change', () => {
|
||||
this.viewer.getRenderer().pipelineOptions = Sandbox.postParams
|
||||
this.viewer.requestRender()
|
||||
})
|
||||
|
||||
postFolder
|
||||
.addInput(Sandbox.postParams.saoParams, 'saoKernelRadius', {
|
||||
min: 0,
|
||||
max: 100
|
||||
})
|
||||
.on('change', () => {
|
||||
this.viewer.getRenderer().pipelineOptions = Sandbox.postParams
|
||||
this.viewer.requestRender()
|
||||
})
|
||||
// // postFolder
|
||||
// // .addInput(Sandbox.postParams.saoParams, 'saoMinResolution', {
|
||||
// // min: 0,
|
||||
// // max: 1
|
||||
// // })
|
||||
// // .on('change', () => {
|
||||
// // this.viewer.getRenderer().pipelineOptions = Sandbox.postParams
|
||||
// // this.viewer.requestRender()
|
||||
// // })
|
||||
|
||||
// postFolder
|
||||
// .addInput(Sandbox.postParams.saoParams, 'saoMinResolution', {
|
||||
// min: 0,
|
||||
// max: 1
|
||||
// })
|
||||
// .addInput(Sandbox.postParams.saoParams, 'saoBlur', {})
|
||||
// .on('change', () => {
|
||||
// this.viewer.getRenderer().pipelineOptions = Sandbox.postParams
|
||||
// this.viewer.requestRender()
|
||||
// })
|
||||
|
||||
postFolder
|
||||
.addInput(Sandbox.postParams.saoParams, 'saoBlur', {})
|
||||
.on('change', () => {
|
||||
this.viewer.getRenderer().pipelineOptions = Sandbox.postParams
|
||||
this.viewer.requestRender()
|
||||
})
|
||||
// postFolder
|
||||
// .addInput(Sandbox.postParams.saoParams, 'saoBlurRadius', { min: 0, max: 10 })
|
||||
// .on('change', () => {
|
||||
// this.viewer.getRenderer().pipelineOptions = Sandbox.postParams
|
||||
// this.viewer.requestRender()
|
||||
// })
|
||||
|
||||
postFolder
|
||||
.addInput(Sandbox.postParams.saoParams, 'saoBlurRadius', { min: 0, max: 10 })
|
||||
.on('change', () => {
|
||||
this.viewer.getRenderer().pipelineOptions = Sandbox.postParams
|
||||
this.viewer.requestRender()
|
||||
})
|
||||
// postFolder
|
||||
// .addInput(Sandbox.postParams, 'minDistance', { min: 0, max: 100, step: 0.000001 })
|
||||
// .on('change', () => {
|
||||
// this.viewer.getRenderer().pipelineOptions = Sandbox.postParams
|
||||
// this.viewer.requestRender()
|
||||
// })
|
||||
|
||||
postFolder
|
||||
.addInput(Sandbox.postParams, 'minDistance', { min: 0, max: 100, step: 0.000001 })
|
||||
.on('change', () => {
|
||||
this.viewer.getRenderer().pipelineOptions = Sandbox.postParams
|
||||
this.viewer.requestRender()
|
||||
})
|
||||
|
||||
postFolder
|
||||
.addInput(Sandbox.postParams, 'maxDistance', { min: 0, max: 100, step: 0.000001 })
|
||||
.on('change', () => {
|
||||
this.viewer.getRenderer().pipelineOptions = Sandbox.postParams
|
||||
this.viewer.requestRender()
|
||||
})
|
||||
postFolder
|
||||
.addInput(Sandbox.postParams, 'ssaoKernelRadius', { min: 0, max: 100 })
|
||||
.on('change', () => {
|
||||
this.viewer.getRenderer().pipelineOptions = Sandbox.postParams
|
||||
this.viewer.requestRender()
|
||||
})
|
||||
postFolder.addInput(Sandbox.postParams, 'progressive', {}).on('change', () => {
|
||||
this.viewer.getRenderer().pipelineOptions = Sandbox.postParams
|
||||
this.viewer.requestRender()
|
||||
})
|
||||
postFolder
|
||||
.addInput(Sandbox.postParams, 'progressiveAO', {
|
||||
options: {
|
||||
SAO: 0,
|
||||
SSAO: 1
|
||||
}
|
||||
})
|
||||
.on('change', () => {
|
||||
this.viewer.getRenderer().pipelineOptions = Sandbox.postParams
|
||||
this.viewer.requestRender()
|
||||
})
|
||||
// postFolder
|
||||
// .addInput(Sandbox.postParams, 'maxDistance', { min: 0, max: 100, step: 0.000001 })
|
||||
// .on('change', () => {
|
||||
// this.viewer.getRenderer().pipelineOptions = Sandbox.postParams
|
||||
// this.viewer.requestRender()
|
||||
// })
|
||||
// postFolder
|
||||
// .addInput(Sandbox.postParams, 'ssaoKernelRadius', { min: 0, max: 100 })
|
||||
// .on('change', () => {
|
||||
// this.viewer.getRenderer().pipelineOptions = Sandbox.postParams
|
||||
// this.viewer.requestRender()
|
||||
// })
|
||||
// postFolder.addInput(Sandbox.postParams, 'progressive', {}).on('change', () => {
|
||||
// this.viewer.getRenderer().pipelineOptions = Sandbox.postParams
|
||||
// this.viewer.requestRender()
|
||||
// })
|
||||
// postFolder
|
||||
// .addInput(Sandbox.postParams, 'progressiveAO', {
|
||||
// options: {
|
||||
// SAO: 0,
|
||||
// SSAO: 1
|
||||
// }
|
||||
// })
|
||||
// .on('change', () => {
|
||||
// this.viewer.getRenderer().pipelineOptions = Sandbox.postParams
|
||||
// this.viewer.requestRender()
|
||||
// })
|
||||
|
||||
// postFolder
|
||||
// .addInput(Sandbox.postParams.saoParams, 'saoBlurStdDev', {
|
||||
|
||||
@@ -50,7 +50,7 @@ import { DefaultPipelineOptions, Pipeline, PipelineOptions } from './pipeline/Pi
|
||||
export default class SpeckleRenderer {
|
||||
private readonly SHOW_HELPERS = false
|
||||
private _renderer: WebGLRenderer
|
||||
public scene: Scene
|
||||
public _scene: Scene
|
||||
private rootGroup: Group
|
||||
private batcher: Batcher
|
||||
private intersections: Intersections
|
||||
@@ -62,19 +62,12 @@ export default class SpeckleRenderer {
|
||||
private filterBatchRecording: string[]
|
||||
private pipeline: Pipeline
|
||||
|
||||
private lastAzimuth: number
|
||||
private lastPolar: number
|
||||
private lastDistance: number
|
||||
private lastTarget: Vector3 = new Vector3()
|
||||
private lasMaxCameraMotion: number
|
||||
private readonly CAMERA_MOTION_EPSILON: number = 0.0001
|
||||
|
||||
public get renderer(): WebGLRenderer {
|
||||
return this._renderer
|
||||
}
|
||||
|
||||
public set indirectIBL(texture: Texture) {
|
||||
this.scene.environment = texture
|
||||
this._scene.environment = texture
|
||||
}
|
||||
|
||||
public set indirectIBLIntensity(value: number) {
|
||||
@@ -92,11 +85,11 @@ export default class SpeckleRenderer {
|
||||
|
||||
/** TEMPORARY for backwards compatibility */
|
||||
public get allObjects() {
|
||||
return this.scene.getObjectByName('ContentGroup')
|
||||
return this._scene.getObjectByName('ContentGroup')
|
||||
}
|
||||
|
||||
public subtree(subtreeId: string) {
|
||||
return this.scene.getObjectByName(subtreeId)
|
||||
return this._scene.getObjectByName(subtreeId)
|
||||
}
|
||||
|
||||
public get sceneBox() {
|
||||
@@ -115,15 +108,23 @@ export default class SpeckleRenderer {
|
||||
return this.sun
|
||||
}
|
||||
|
||||
public get camera() {
|
||||
return this.viewer.cameraHandler.activeCam.camera
|
||||
}
|
||||
|
||||
public get scene() {
|
||||
return this._scene
|
||||
}
|
||||
|
||||
public set pipelineOptions(value: PipelineOptions) {
|
||||
this.pipeline.pipelineOptions = value
|
||||
}
|
||||
|
||||
public constructor(viewer: Viewer /** TEMPORARY */) {
|
||||
this.scene = new Scene()
|
||||
this._scene = new Scene()
|
||||
this.rootGroup = new Group()
|
||||
this.rootGroup.name = 'ContentGroup'
|
||||
this.scene.add(this.rootGroup)
|
||||
this._scene.add(this.rootGroup)
|
||||
|
||||
this.batcher = new Batcher()
|
||||
this.intersections = new Intersections()
|
||||
@@ -151,7 +152,7 @@ export default class SpeckleRenderer {
|
||||
container.appendChild(this._renderer.domElement)
|
||||
|
||||
this.pipeline = new Pipeline(this._renderer, this.batcher)
|
||||
this.pipeline.configure(this.scene, this.viewer.cameraHandler.activeCam.camera)
|
||||
this.pipeline.configure(this._scene, this.viewer.cameraHandler.activeCam.camera)
|
||||
this.pipeline.pipelineOptions = DefaultPipelineOptions
|
||||
|
||||
this.input = new Input(this._renderer.domElement, InputOptionsDefault)
|
||||
@@ -163,7 +164,7 @@ export default class SpeckleRenderer {
|
||||
if (this.SHOW_HELPERS) {
|
||||
const helpers = new Group()
|
||||
helpers.name = 'Helpers'
|
||||
this.scene.add(helpers)
|
||||
this._scene.add(helpers)
|
||||
|
||||
const sceneBoxHelper = new Box3Helper(this.sceneBox, new Color(0x0000ff))
|
||||
sceneBoxHelper.name = 'SceneBoxHelper'
|
||||
@@ -287,7 +288,8 @@ export default class SpeckleRenderer {
|
||||
this.viewer.cameraHandler.activeCam.camera.far = d
|
||||
this.viewer.cameraHandler.activeCam.camera.updateProjectionMatrix()
|
||||
this.viewer.cameraHandler.camera.updateProjectionMatrix()
|
||||
this.pipeline.pipelineOptions = { saoParams: { saoScale: d } }
|
||||
|
||||
this.pipeline.update(this)
|
||||
|
||||
// const currentAzimuth = this.viewer.cameraHandler.controls.azimuthAngle
|
||||
// const currentPolar = this.viewer.cameraHandler.controls.polarAngle
|
||||
@@ -321,8 +323,9 @@ export default class SpeckleRenderer {
|
||||
}
|
||||
|
||||
public render(camera: Camera): boolean {
|
||||
camera
|
||||
this.batcher.render(this.renderer)
|
||||
const needsRender = this.pipeline.render(this.scene, camera)
|
||||
const needsRender = this.pipeline.render()
|
||||
return needsRender
|
||||
// this.renderer.render(this.scene, camera)
|
||||
}
|
||||
@@ -431,7 +434,7 @@ export default class SpeckleRenderer {
|
||||
private addDirectLights() {
|
||||
this.sun = new DirectionalLight(0xffffff, 5)
|
||||
this.sun.name = 'sun'
|
||||
this.scene.add(this.sun)
|
||||
this._scene.add(this.sun)
|
||||
|
||||
this.sun.castShadow = true
|
||||
|
||||
@@ -450,7 +453,7 @@ export default class SpeckleRenderer {
|
||||
this.sun.shadow.radius = 2
|
||||
|
||||
this.sunTarget = new Object3D()
|
||||
this.scene.add(this.sunTarget)
|
||||
this._scene.add(this.sunTarget)
|
||||
this.sunTarget.position.copy(this.sceneCenter)
|
||||
this.sun.target = this.sunTarget
|
||||
}
|
||||
@@ -529,12 +532,14 @@ export default class SpeckleRenderer {
|
||||
|
||||
public updateHelpers() {
|
||||
if (this.SHOW_HELPERS) {
|
||||
;(this.scene.getObjectByName('CamHelper') as CameraHelper).update()
|
||||
;(this._scene.getObjectByName('CamHelper') as CameraHelper).update()
|
||||
// Thank you prettier, this looks so much better
|
||||
;(this.scene.getObjectByName('SceneBoxHelper') as Box3Helper).box.copy(
|
||||
;(this._scene.getObjectByName('SceneBoxHelper') as Box3Helper).box.copy(
|
||||
this.sceneBox
|
||||
)
|
||||
;(this.scene.getObjectByName('DirLightHelper') as DirectionalLightHelper).update()
|
||||
;(
|
||||
this._scene.getObjectByName('DirLightHelper') as DirectionalLightHelper
|
||||
).update()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -575,7 +580,7 @@ export default class SpeckleRenderer {
|
||||
|
||||
private onObjectClick(e) {
|
||||
const results: Array<Intersection> = this.intersections.intersect(
|
||||
this.scene,
|
||||
this._scene,
|
||||
this.viewer.cameraHandler.activeCam.camera,
|
||||
e,
|
||||
true,
|
||||
@@ -614,7 +619,7 @@ export default class SpeckleRenderer {
|
||||
|
||||
private onObjectDoubleClick(e) {
|
||||
const results: Array<Intersection> = this.intersections.intersect(
|
||||
this.scene,
|
||||
this._scene,
|
||||
this.viewer.cameraHandler.activeCam.camera,
|
||||
e,
|
||||
true,
|
||||
@@ -899,7 +904,7 @@ export default class SpeckleRenderer {
|
||||
/** DEBUG */
|
||||
public onObjectClickDebug(e) {
|
||||
const results: Array<Intersection> = this.intersections.intersect(
|
||||
this.scene,
|
||||
this._scene,
|
||||
this.viewer.cameraHandler.activeCam.camera,
|
||||
e,
|
||||
true,
|
||||
|
||||
@@ -135,7 +135,9 @@ export class Viewer extends EventEmitter implements IViewer {
|
||||
}
|
||||
|
||||
public resize() {
|
||||
this.speckleRenderer.resize(this.container.offsetWidth, this.container.offsetHeight)
|
||||
const width = this.container.offsetWidth
|
||||
const height = this.container.offsetHeight
|
||||
this.speckleRenderer.resize(width, height)
|
||||
this.needsRender = true
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
export const speckleCopyOutputFrag = `
|
||||
uniform float opacity;
|
||||
uniform sampler2D tDiffuse;
|
||||
varying vec2 vUv;
|
||||
|
||||
const float UnpackDownscale = 255. / 256.;
|
||||
const vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );
|
||||
const vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );
|
||||
|
||||
float unpackRGBAToDepth( const in vec4 v ) {
|
||||
return dot( v, UnpackFactors );
|
||||
}
|
||||
|
||||
vec3 unpackRGBToNormal( const in vec3 rgb ) {
|
||||
return 2.0 * rgb.xyz - 1.0;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 inSample = texture2D( tDiffuse, vUv );
|
||||
vec3 outSample = inSample.rgb;
|
||||
#if OUTPUT_TYPE == 1
|
||||
outSample.rgb = vec3(unpackRGBAToDepth(inSample));
|
||||
#endif
|
||||
#if OUTPUT_TYPE == 3
|
||||
outSample.rgb = unpackRGBToNormal(inSample.rgb);
|
||||
#endif
|
||||
|
||||
gl_FragColor.rgb = outSample;
|
||||
gl_FragColor.a = 1.;
|
||||
}`
|
||||
@@ -0,0 +1,6 @@
|
||||
export const speckleCopyOutputVert = `
|
||||
varying vec2 vUv;
|
||||
void main() {
|
||||
vUv = uv;
|
||||
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
|
||||
}`
|
||||
@@ -209,6 +209,21 @@ export const speckleSaoFrag = /* glsl */ `
|
||||
}
|
||||
float centerViewZ = getViewZ( centerDepth );
|
||||
vec3 viewPosition = getViewPosition( vUv, centerDepth, centerViewZ );
|
||||
|
||||
#ifdef OUTPUT_RECONSTRUCTED_NORMALS
|
||||
vec3 normal;
|
||||
#if IMPROVED_NORMAL_RECONSTRUCTION == 1
|
||||
normal = viewNormalImproved(vUv, viewPosition);
|
||||
#elif ACCURATE_NORMAL_RECONSTRUCTION == 1
|
||||
normal = viewNormalAccurate(vUv, viewPosition, centerDepth);
|
||||
#else
|
||||
normal = normalize( cross( dFdx( viewPosition ), dFdy( viewPosition ) ) );
|
||||
#endif
|
||||
gl_FragColor.rgb = packNormalToRGB(viewNormalImproved(vUv, viewPosition));
|
||||
gl_FragColor.a = 1.;
|
||||
return;
|
||||
#endif
|
||||
|
||||
float ambientOcclusion = getAmbientOcclusion( viewPosition, centerDepth );
|
||||
gl_FragColor = getDefaultColor( vUv );
|
||||
gl_FragColor.xyz *= 1. - ambientOcclusion;
|
||||
|
||||
@@ -11,8 +11,9 @@ import {
|
||||
} from 'three'
|
||||
import { FullScreenQuad, Pass } from 'three/examples/jsm/postprocessing/Pass'
|
||||
import { CopyShader } from 'three/examples/jsm/shaders/CopyShader.js'
|
||||
import { InputColorTextureUniform, SpecklePass } from './SpecklePass'
|
||||
|
||||
export class ApplySAOPass extends Pass {
|
||||
export class ApplySAOPass extends Pass implements SpecklePass {
|
||||
private fsQuad: FullScreenQuad
|
||||
public materialCopy: ShaderMaterial
|
||||
|
||||
@@ -35,26 +36,34 @@ export class ApplySAOPass extends Pass {
|
||||
this.materialCopy.blendDstAlpha = ZeroFactor
|
||||
this.materialCopy.blendEquationAlpha = AddEquation
|
||||
|
||||
// this.materialCopy.blending = CustomBlending
|
||||
// this.materialCopy.blendSrc = OneFactor
|
||||
// this.materialCopy.blendDst = OneFactor
|
||||
// this.materialCopy.blendEquation = ReverseSubtractEquation
|
||||
// this.materialCopy.blendSrcAlpha = OneFactor
|
||||
// this.materialCopy.blendDstAlpha = OneFactor
|
||||
// this.materialCopy.blendEquationAlpha = AddEquation
|
||||
this.materialCopy.needsUpdate = true
|
||||
this.fsQuad = new FullScreenQuad(this.materialCopy)
|
||||
}
|
||||
|
||||
public setAoTexture(texture: Texture) {
|
||||
this.materialCopy.uniforms['tDiffuse'].value = texture
|
||||
public setTexture(uName: InputColorTextureUniform, texture: Texture) {
|
||||
this.materialCopy.uniforms[uName].value = texture
|
||||
this.materialCopy.needsUpdate = true
|
||||
}
|
||||
|
||||
get displayName(): string {
|
||||
return 'APPLYSAO'
|
||||
}
|
||||
|
||||
get outputTexture(): Texture {
|
||||
return null
|
||||
}
|
||||
|
||||
setParams(params: unknown) {
|
||||
params
|
||||
}
|
||||
|
||||
render(renderer, writeBuffer, readBuffer /*, deltaTime, maskActive*/) {
|
||||
writeBuffer
|
||||
readBuffer
|
||||
renderer.setRenderTarget(null)
|
||||
const rendereAutoClear = renderer.autoClear
|
||||
renderer.autoClear = false
|
||||
this.fsQuad.render(renderer)
|
||||
renderer.autoClear = rendereAutoClear
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
import { NoBlending, ShaderMaterial, Texture, UniformsUtils } from 'three'
|
||||
import { FullScreenQuad, Pass } from 'three/examples/jsm/postprocessing/Pass'
|
||||
import { CopyShader } from 'three/examples/jsm/shaders/CopyShader.js'
|
||||
import { speckleCopyOutputFrag } from '../materials/shaders/speckle-copy-output-frag'
|
||||
import { speckleCopyOutputVert } from '../materials/shaders/speckle-copy-output-vert'
|
||||
import { PipelineOutputType } from './Pipeline'
|
||||
import { InputColorTextureUniform, SpecklePass } from './SpecklePass'
|
||||
|
||||
export class CopyOutputPass extends Pass implements SpecklePass {
|
||||
private fsQuad: FullScreenQuad
|
||||
public materialCopy: ShaderMaterial
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
this.materialCopy = new ShaderMaterial({
|
||||
defines: {
|
||||
INPUT_TYPE: 0
|
||||
},
|
||||
uniforms: UniformsUtils.clone(CopyShader.uniforms),
|
||||
vertexShader: speckleCopyOutputVert,
|
||||
fragmentShader: speckleCopyOutputFrag,
|
||||
blending: NoBlending
|
||||
})
|
||||
|
||||
this.materialCopy.needsUpdate = true
|
||||
this.fsQuad = new FullScreenQuad(this.materialCopy)
|
||||
}
|
||||
|
||||
public setOutputType(type: PipelineOutputType) {
|
||||
this.materialCopy.defines['OUTPUT_TYPE'] = type
|
||||
this.materialCopy.needsUpdate = true
|
||||
}
|
||||
|
||||
public setTexture(uName: InputColorTextureUniform, texture: Texture) {
|
||||
this.materialCopy.uniforms[uName].value = texture
|
||||
this.materialCopy.needsUpdate = true
|
||||
}
|
||||
|
||||
get displayName(): string {
|
||||
return 'COPY-OUTPUT'
|
||||
}
|
||||
|
||||
get outputTexture(): Texture {
|
||||
return null
|
||||
}
|
||||
|
||||
render(renderer, writeBuffer, readBuffer /*, deltaTime, maskActive*/) {
|
||||
writeBuffer
|
||||
readBuffer
|
||||
renderer.setRenderTarget(null)
|
||||
const rendereAutoClear = renderer.autoClear
|
||||
renderer.autoClear = false
|
||||
this.fsQuad.render(renderer)
|
||||
renderer.autoClear = rendereAutoClear
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
Color,
|
||||
DoubleSide,
|
||||
NoBlending,
|
||||
Plane,
|
||||
RGBADepthPacking,
|
||||
Scene,
|
||||
Texture,
|
||||
@@ -10,7 +11,7 @@ import {
|
||||
} from 'three'
|
||||
import { Pass } from 'three/examples/jsm/postprocessing/Pass'
|
||||
import SpeckleDepthMaterial from '../materials/SpeckleDepthMaterial'
|
||||
import { SpecklePass } from './Pipeline'
|
||||
import { SpecklePass } from './SpecklePass'
|
||||
|
||||
export class DepthPass extends Pass implements SpecklePass {
|
||||
private renderTarget: WebGLRenderTarget
|
||||
@@ -20,6 +21,9 @@ export class DepthPass extends Pass implements SpecklePass {
|
||||
|
||||
private colorBuffer: Color = new Color()
|
||||
|
||||
public onBeforeRender: () => void = null
|
||||
public onAfterRender: () => void = null
|
||||
|
||||
get displayName(): string {
|
||||
return 'DEPTH'
|
||||
}
|
||||
@@ -49,7 +53,11 @@ export class DepthPass extends Pass implements SpecklePass {
|
||||
this.depthMaterial.side = DoubleSide
|
||||
}
|
||||
|
||||
public update(camera: Camera, scene: Scene) {
|
||||
public setClippingPlanes(planes: Plane[]) {
|
||||
this.depthMaterial.clippingPlanes = planes
|
||||
}
|
||||
|
||||
public update(scene: Scene, camera: Camera) {
|
||||
this.camera = camera
|
||||
this.scene = scene
|
||||
}
|
||||
@@ -58,6 +66,7 @@ export class DepthPass extends Pass implements SpecklePass {
|
||||
writeBuffer
|
||||
readBuffer
|
||||
|
||||
this.onBeforeRender()
|
||||
renderer.getClearColor(this.colorBuffer)
|
||||
const originalClearAlpha = renderer.getClearAlpha()
|
||||
const originalAutoClear = renderer.autoClear
|
||||
@@ -83,6 +92,7 @@ export class DepthPass extends Pass implements SpecklePass {
|
||||
renderer.autoClear = originalAutoClear
|
||||
renderer.setClearColor(this.colorBuffer)
|
||||
renderer.setClearAlpha(originalClearAlpha)
|
||||
this.onAfterRender()
|
||||
}
|
||||
|
||||
public setSize(width: number, height: number) {
|
||||
|
||||
+26
-32
@@ -17,7 +17,7 @@ import { speckleSaoVert } from '../materials/shaders/speckle-sao-vert'
|
||||
import { SAOShader } from 'three/examples/jsm/shaders/SAOShader.js'
|
||||
import { DepthLimitedBlurShader } from 'three/examples/jsm/shaders/DepthLimitedBlurShader.js'
|
||||
import { BlurShaderUtils } from 'three/examples/jsm/shaders/DepthLimitedBlurShader.js'
|
||||
import { SpecklePass } from './Pipeline'
|
||||
import { InputDepthTextureUniform, SpecklePass } from './SpecklePass'
|
||||
|
||||
export enum NormalsType {
|
||||
DEFAULT = 0,
|
||||
@@ -49,12 +49,8 @@ export const DefaultSpeckleDynamicSAOPassParams = {
|
||||
blurDepthCutoff: 0.0007
|
||||
}
|
||||
|
||||
/**
|
||||
* SAO implementation inspired from bhouston previous SAO work
|
||||
*/
|
||||
|
||||
export class SpeckleDynamicSAOPass extends Pass implements SpecklePass {
|
||||
private params: SpeckleDynamicSAOPassParams
|
||||
export class DynamicSAOPass extends Pass implements SpecklePass {
|
||||
private params: SpeckleDynamicSAOPassParams = DefaultSpeckleDynamicSAOPassParams
|
||||
private colorBuffer: Color = new Color()
|
||||
private saoMaterial: ShaderMaterial = null
|
||||
private vBlurMaterial: ShaderMaterial = null
|
||||
@@ -66,32 +62,22 @@ export class SpeckleDynamicSAOPass extends Pass implements SpecklePass {
|
||||
private prevStdDev: number
|
||||
private prevNumSamples: number
|
||||
|
||||
get displayName(): string {
|
||||
public get displayName(): string {
|
||||
return 'SAO'
|
||||
}
|
||||
|
||||
get outputTexture(): Texture {
|
||||
public get outputTexture(): Texture {
|
||||
return this.saoRenderTarget.texture
|
||||
}
|
||||
|
||||
public setDepthTexture(texture: Texture) {
|
||||
this.saoMaterial.uniforms['tDepth'].value = texture
|
||||
this.vBlurMaterial.uniforms['tDepth'].value = texture
|
||||
this.hBlurMaterial.uniforms['tDepth'].value = texture
|
||||
this.saoMaterial.needsUpdate = true
|
||||
this.vBlurMaterial.needsUpdate = true
|
||||
this.hBlurMaterial.needsUpdate = true
|
||||
public set outputReconstructedNormals(value: boolean) {
|
||||
if (value) this.saoMaterial.defines['OUTPUT_RECONSTRUCTED_NORMALS'] = ''
|
||||
else delete this.saoMaterial.defines['OUTPUT_RECONSTRUCTED_NORMALS']
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
|
||||
// this.normalRenderTarget.depthBuffer = true
|
||||
// this.normalRenderTarget.stencilBuffer = true
|
||||
|
||||
// this.normalMaterial = new SpeckleNormalMaterial({}, ['USE_RTE'])
|
||||
// this.normalMaterial.blending = NoBlending
|
||||
// this.normalMaterial.side = DoubleSide
|
||||
this.saoRenderTarget = new WebGLRenderTarget(256, 256)
|
||||
this.blurIntermediateRenderTarget = new WebGLRenderTarget(256, 256)
|
||||
this.saoMaterial = new ShaderMaterial({
|
||||
@@ -145,7 +131,21 @@ export class SpeckleDynamicSAOPass extends Pass implements SpecklePass {
|
||||
this.fsQuad = new FullScreenQuad(this.saoMaterial)
|
||||
}
|
||||
|
||||
public setParams(params: unknown) {
|
||||
Object.assign(this.params, params)
|
||||
}
|
||||
|
||||
public setTexture(uName: InputDepthTextureUniform, texture: Texture) {
|
||||
this.saoMaterial.uniforms['tDepth'].value = texture
|
||||
this.vBlurMaterial.uniforms['tDepth'].value = texture
|
||||
this.hBlurMaterial.uniforms['tDepth'].value = texture
|
||||
this.saoMaterial.needsUpdate = true
|
||||
this.vBlurMaterial.needsUpdate = true
|
||||
this.hBlurMaterial.needsUpdate = true
|
||||
}
|
||||
|
||||
public update(scene: Scene, camera: Camera) {
|
||||
this.params.scale = (camera as PerspectiveCamera | OrthographicCamera).far
|
||||
/** SAO DEFINES */
|
||||
this.saoMaterial.defines['PERSPECTIVE_CAMERA'] = (camera as PerspectiveCamera)
|
||||
.isPerspectiveCamera
|
||||
@@ -235,15 +235,9 @@ export class SpeckleDynamicSAOPass extends Pass implements SpecklePass {
|
||||
this.hBlurMaterial.needsUpdate = true
|
||||
}
|
||||
|
||||
public render(renderer, writeBuffer, readBuffer) {
|
||||
writeBuffer
|
||||
readBuffer
|
||||
|
||||
// const restoreVisibility = this.batcher.saveVisiblity()
|
||||
// const opaque = this.batcher.getOpaque()
|
||||
// this.batcher.applyVisibility(opaque)
|
||||
// this.batcher.applyVisibility(restoreVisibility)
|
||||
|
||||
public render(renderer) {
|
||||
const outputNormals =
|
||||
this.saoMaterial.defines['OUTPUT_RECONSTRUCTED_NORMALS'] !== undefined
|
||||
// Rendering SAO texture
|
||||
renderer.getClearColor(this.colorBuffer)
|
||||
const originalClearAlpha = renderer.getClearAlpha()
|
||||
@@ -259,7 +253,7 @@ export class SpeckleDynamicSAOPass extends Pass implements SpecklePass {
|
||||
this.fsQuad.material = this.saoMaterial
|
||||
this.fsQuad.render(renderer)
|
||||
|
||||
if (this.params.blurEnabled) {
|
||||
if (this.params.blurEnabled && !outputNormals) {
|
||||
renderer.setRenderTarget(this.blurIntermediateRenderTarget)
|
||||
renderer.setClearColor(0xffffff)
|
||||
renderer.setClearAlpha(1.0)
|
||||
@@ -0,0 +1,95 @@
|
||||
import {
|
||||
Camera,
|
||||
Color,
|
||||
DoubleSide,
|
||||
NoBlending,
|
||||
Plane,
|
||||
Scene,
|
||||
Texture,
|
||||
WebGLRenderTarget
|
||||
} from 'three'
|
||||
import { Pass } from 'three/examples/jsm/postprocessing/Pass'
|
||||
import SpeckleNormalMaterial from '../materials/SpeckleNormalMaterial'
|
||||
import { SpecklePass } from './SpecklePass'
|
||||
|
||||
export class NormalsPass extends Pass implements SpecklePass {
|
||||
private renderTarget: WebGLRenderTarget
|
||||
private normalsMaterial: SpeckleNormalMaterial = null
|
||||
private scene: Scene
|
||||
private camera: Camera
|
||||
|
||||
private colorBuffer: Color = new Color()
|
||||
|
||||
public onBeforeRender: () => void = null
|
||||
public onAfterRender: () => void = null
|
||||
|
||||
get displayName(): string {
|
||||
return 'GEOMETRY-NORMALS'
|
||||
}
|
||||
|
||||
get outputTexture(): Texture {
|
||||
return this.renderTarget.texture
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
|
||||
this.renderTarget = new WebGLRenderTarget(256, 256)
|
||||
/** On Chromium, on MacOS the 16 bit depth render buffer appears broken.
|
||||
* We're not really using a stencil buffer at all, we're just forcing
|
||||
* three.js to use a 24 bit depth render buffer
|
||||
*/
|
||||
this.renderTarget.depthBuffer = true
|
||||
this.renderTarget.stencilBuffer = true
|
||||
|
||||
this.normalsMaterial = new SpeckleNormalMaterial({}, ['USE_RTE'])
|
||||
this.normalsMaterial.blending = NoBlending
|
||||
this.normalsMaterial.side = DoubleSide
|
||||
}
|
||||
|
||||
public setClippingPlanes(planes: Plane[]) {
|
||||
this.normalsMaterial.clippingPlanes = planes
|
||||
}
|
||||
|
||||
public update(scene: Scene, camera: Camera) {
|
||||
this.camera = camera
|
||||
this.scene = scene
|
||||
}
|
||||
|
||||
public render(renderer, writeBuffer, readBuffer) {
|
||||
writeBuffer
|
||||
readBuffer
|
||||
|
||||
this.onBeforeRender()
|
||||
renderer.getClearColor(this.colorBuffer)
|
||||
const originalClearAlpha = renderer.getClearAlpha()
|
||||
const originalAutoClear = renderer.autoClear
|
||||
|
||||
renderer.setRenderTarget(this.renderTarget)
|
||||
renderer.autoClear = false
|
||||
|
||||
renderer.setClearColor(0x000000)
|
||||
renderer.setClearAlpha(1.0)
|
||||
renderer.clear()
|
||||
|
||||
const shadowmapEnabled = renderer.shadowMap.enabled
|
||||
const shadowmapNeedsUpdate = renderer.shadowMap.needsUpdate
|
||||
this.scene.overrideMaterial = this.normalsMaterial
|
||||
renderer.shadowMap.enabled = false
|
||||
renderer.shadowMap.needsUpdate = false
|
||||
renderer.render(this.scene, this.camera)
|
||||
renderer.shadowMap.enabled = shadowmapEnabled
|
||||
renderer.shadowMap.needsUpdate = shadowmapNeedsUpdate
|
||||
this.scene.overrideMaterial = null
|
||||
|
||||
// restore original state
|
||||
renderer.autoClear = originalAutoClear
|
||||
renderer.setClearColor(this.colorBuffer)
|
||||
renderer.setClearAlpha(originalClearAlpha)
|
||||
this.onAfterRender()
|
||||
}
|
||||
|
||||
public setSize(width: number, height: number) {
|
||||
this.renderTarget.setSize(width, height)
|
||||
}
|
||||
}
|
||||
@@ -1,31 +1,40 @@
|
||||
import { Camera, Plane, Scene, Texture, Vector2, WebGLRenderer } from 'three'
|
||||
import { Camera, Plane, Scene, Vector2, WebGLRenderer } from 'three'
|
||||
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js'
|
||||
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js'
|
||||
import Batcher from '../batching/Batcher'
|
||||
import SpeckleRenderer from '../SpeckleRenderer'
|
||||
import { ApplySAOPass } from './ApplySAOPass'
|
||||
import { CopyOutputPass } from './CopyOutputPass'
|
||||
import { DepthPass } from './DepthPass'
|
||||
import { NormalsPass } from './NormalsPass'
|
||||
import {
|
||||
DefaultSpeckleDynamicSAOPassParams,
|
||||
NormalsType,
|
||||
SpeckleDynamicSAOPass,
|
||||
DynamicSAOPass,
|
||||
SpeckleDynamicSAOPassParams
|
||||
} from './SpeckleDynamicSAOPass'
|
||||
import { SpeckleStaticAOGeneratePass } from './SpeckleStaticAOGeneratePass'
|
||||
} from './DynamicSAOPass'
|
||||
// import { SpecklePass } from './SpecklePass'
|
||||
// import { SpeckleStaticAOGeneratePass } from './SpeckleStaticAOGeneratePass'
|
||||
|
||||
enum RenderType {
|
||||
NORMAL,
|
||||
ACCUMULATION
|
||||
}
|
||||
export interface SpecklePass {
|
||||
get displayName(): string
|
||||
get outputTexture(): Texture
|
||||
export enum PipelineOutputType {
|
||||
DEPTH_RGBA = 0,
|
||||
DEPTH = 1,
|
||||
COLOR = 2,
|
||||
GEOMETRY_NORMALS = 3,
|
||||
RECONSTRUCTED_NORMALS = 4,
|
||||
DYNAMIC_AO = 5,
|
||||
DYNAMIC_AO_BLURED = 6,
|
||||
PROGRESSIVE_AO = 7,
|
||||
FINAL = 8
|
||||
}
|
||||
|
||||
export interface PipelineOptions {
|
||||
pipelineOutput: PipelineOutputType
|
||||
dynamicAoEnabled: boolean
|
||||
dynamicAoParams: SpeckleDynamicSAOPassParams
|
||||
}
|
||||
|
||||
export const DefaultPipelineOptions: PipelineOptions = {
|
||||
pipelineOutput: PipelineOutputType.FINAL,
|
||||
dynamicAoEnabled: true,
|
||||
dynamicAoParams: DefaultSpeckleDynamicSAOPassParams
|
||||
// saoScaleOffset: 0,
|
||||
@@ -43,23 +52,79 @@ export class Pipeline {
|
||||
private _pipelineOptions: PipelineOptions = Object.assign({}, DefaultPipelineOptions)
|
||||
private composer: EffectComposer = null
|
||||
|
||||
private depthPass: DepthPass = null
|
||||
private normalsPass: NormalsPass = null
|
||||
private renderPass: RenderPass = null
|
||||
private dynamicAoPass: SpeckleDynamicSAOPass = null
|
||||
private dynamicAoPass: DynamicSAOPass = null
|
||||
private applySaoPass: ApplySAOPass = null
|
||||
private staticAOGenerationPass: SpeckleStaticAOGeneratePass = null
|
||||
private copyOutputPass: CopyOutputPass = null
|
||||
|
||||
private drawingSize: Vector2 = new Vector2()
|
||||
private _renderType: RenderType = RenderType.NORMAL
|
||||
private accumulationFrame = 0
|
||||
private readonly NUM_ACCUMULATION_FRAMES = 16
|
||||
private enableProgressive = true
|
||||
|
||||
public set pipelineOptions(options: Partial<PipelineOptions>) {
|
||||
Object.assign(this._pipelineOptions, options)
|
||||
this.pipelineOutput = options.pipelineOutput
|
||||
this.dynamicAoPass.setParams(options.dynamicAoParams)
|
||||
}
|
||||
|
||||
private set renderType(value: RenderType) {
|
||||
this._renderType = value
|
||||
public set pipelineOutput(outputType: PipelineOutputType) {
|
||||
switch (outputType) {
|
||||
case PipelineOutputType.DEPTH_RGBA:
|
||||
this.dynamicAoPass.enabled = false
|
||||
this.renderPass.enabled = false
|
||||
this.applySaoPass.enabled = false
|
||||
this.normalsPass.enabled = false
|
||||
this.depthPass.enabled = true
|
||||
this.copyOutputPass.enabled = true
|
||||
this.copyOutputPass.setTexture('tDiffuse', this.depthPass.outputTexture)
|
||||
this.copyOutputPass.setOutputType(PipelineOutputType.DEPTH_RGBA)
|
||||
break
|
||||
|
||||
case PipelineOutputType.DEPTH:
|
||||
this.dynamicAoPass.enabled = false
|
||||
this.renderPass.enabled = false
|
||||
this.applySaoPass.enabled = false
|
||||
this.depthPass.enabled = true
|
||||
this.normalsPass.enabled = false
|
||||
this.copyOutputPass.enabled = true
|
||||
this.copyOutputPass.setTexture('tDiffuse', this.depthPass.outputTexture)
|
||||
this.copyOutputPass.setOutputType(PipelineOutputType.DEPTH)
|
||||
break
|
||||
|
||||
case PipelineOutputType.COLOR:
|
||||
this.depthPass.enabled = false
|
||||
this.dynamicAoPass.enabled = false
|
||||
this.applySaoPass.enabled = false
|
||||
this.copyOutputPass.enabled = false
|
||||
this.normalsPass.enabled = false
|
||||
this.renderPass.enabled = true
|
||||
break
|
||||
|
||||
case PipelineOutputType.GEOMETRY_NORMALS:
|
||||
this.depthPass.enabled = false
|
||||
this.dynamicAoPass.enabled = false
|
||||
this.applySaoPass.enabled = false
|
||||
this.renderPass.enabled = false
|
||||
this.normalsPass.enabled = true
|
||||
this.copyOutputPass.enabled = true
|
||||
this.copyOutputPass.setTexture('tDiffuse', this.normalsPass.outputTexture)
|
||||
this.copyOutputPass.setOutputType(PipelineOutputType.GEOMETRY_NORMALS)
|
||||
break
|
||||
|
||||
case PipelineOutputType.RECONSTRUCTED_NORMALS:
|
||||
this.depthPass.enabled = true
|
||||
this.dynamicAoPass.enabled = true
|
||||
this.applySaoPass.enabled = false
|
||||
this.renderPass.enabled = false
|
||||
this.normalsPass.enabled = false
|
||||
this.copyOutputPass.enabled = true
|
||||
this.copyOutputPass.setTexture('tDiffuse', this.dynamicAoPass.outputTexture)
|
||||
this.copyOutputPass.setOutputType(PipelineOutputType.GEOMETRY_NORMALS)
|
||||
this.dynamicAoPass.outputReconstructedNormals = true
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public constructor(renderer: WebGLRenderer, batcher: Batcher) {
|
||||
@@ -71,59 +136,64 @@ export class Pipeline {
|
||||
}
|
||||
|
||||
public configure(scene: Scene, camera: Camera) {
|
||||
this.dynamicAoPass = new SpeckleDynamicSAOPass(
|
||||
scene,
|
||||
camera,
|
||||
this._batcher,
|
||||
false,
|
||||
NormalsType.IMPROVED
|
||||
)
|
||||
this.staticAOGenerationPass = new SpeckleStaticAOGeneratePass(this._batcher)
|
||||
this.staticAOGenerationPass.depthTexture =
|
||||
this.dynamicAoPass.depthRenderTarget.texture
|
||||
this.composer.addPass(this.dynamicAoPass)
|
||||
this.depthPass = new DepthPass()
|
||||
this.normalsPass = new NormalsPass()
|
||||
this.normalsPass.enabled = false
|
||||
this.dynamicAoPass = new DynamicSAOPass()
|
||||
this.renderPass = new RenderPass(scene, camera)
|
||||
this.renderPass.renderToScreen = true
|
||||
// this.renderPass.enabled = false
|
||||
this.composer.addPass(this.renderPass)
|
||||
this.composer.addPass(this.staticAOGenerationPass)
|
||||
this.applySaoPass = new ApplySAOPass()
|
||||
this.applySaoPass.setAoTexture(this.dynamicAoPass.saoRenderTarget.texture)
|
||||
this.applySaoPass.renderToScreen = true
|
||||
this.copyOutputPass = new CopyOutputPass()
|
||||
this.copyOutputPass.renderToScreen = true
|
||||
this.copyOutputPass.enabled = false
|
||||
this.composer.addPass(this.depthPass)
|
||||
this.composer.addPass(this.normalsPass)
|
||||
this.composer.addPass(this.dynamicAoPass)
|
||||
this.composer.addPass(this.renderPass)
|
||||
this.composer.addPass(this.applySaoPass)
|
||||
this.composer.addPass(this.copyOutputPass)
|
||||
|
||||
this.dynamicAoPass.setTexture('tDepth', this.depthPass.outputTexture)
|
||||
this.applySaoPass.setTexture('tDiffuse', this.dynamicAoPass.outputTexture)
|
||||
|
||||
let restoreVisibility
|
||||
this.depthPass.onBeforeRender = () => {
|
||||
restoreVisibility = this._batcher.saveVisiblity()
|
||||
const opaque = this._batcher.getOpaque()
|
||||
this._batcher.applyVisibility(opaque)
|
||||
}
|
||||
this.depthPass.onAfterRender = () => {
|
||||
this._batcher.applyVisibility(restoreVisibility)
|
||||
}
|
||||
|
||||
this.normalsPass.onBeforeRender = () => {
|
||||
restoreVisibility = this._batcher.saveVisiblity()
|
||||
const opaque = this._batcher.getOpaque()
|
||||
this._batcher.applyVisibility(opaque)
|
||||
}
|
||||
this.normalsPass.onAfterRender = () => {
|
||||
this._batcher.applyVisibility(restoreVisibility)
|
||||
}
|
||||
}
|
||||
|
||||
public updateClippingPlanes(planes: Plane[]) {
|
||||
this.dynamicAoPass.depthMaterial.clippingPlanes = planes
|
||||
this.dynamicAoPass.normalMaterial.clippingPlanes = planes
|
||||
this.depthPass.setClippingPlanes(planes)
|
||||
}
|
||||
|
||||
public render(scene: Scene, camera: Camera): boolean {
|
||||
public update(renderer: SpeckleRenderer) {
|
||||
this.depthPass.update(renderer.scene, renderer.camera)
|
||||
this.dynamicAoPass.update(renderer.scene, renderer.camera)
|
||||
this.normalsPass.update(renderer.scene, renderer.camera)
|
||||
}
|
||||
|
||||
public render(): boolean {
|
||||
this._renderer.getDrawingBufferSize(this.drawingSize)
|
||||
if (this.drawingSize.length() === 0) return
|
||||
|
||||
if (this._renderType === RenderType.NORMAL) {
|
||||
this._renderer.clear(true)
|
||||
this.applySaoPass.setAoTexture(this.dynamicAoPass.saoRenderTarget.texture)
|
||||
this.renderPass.scene = scene
|
||||
this.renderPass.camera = camera
|
||||
this.dynamicAoPass.scene = scene
|
||||
this.dynamicAoPass.camera = camera
|
||||
this.composer.render()
|
||||
return true
|
||||
} else if (this.enableProgressive) {
|
||||
this._renderer.clear(true)
|
||||
this.applySaoPass.setAoTexture(this.staticAOGenerationPass.outputTexture.texture)
|
||||
this.renderPass.scene = scene
|
||||
this.renderPass.camera = camera
|
||||
this.dynamicAoPass.scene = scene
|
||||
this.dynamicAoPass.camera = camera
|
||||
this.staticAOGenerationPass.update(camera, this.accumulationFrame)
|
||||
this.composer.render()
|
||||
this.accumulationFrame++
|
||||
console.warn('rendering stationary frame => ', this.accumulationFrame)
|
||||
return this.accumulationFrame < this.NUM_ACCUMULATION_FRAMES ? true : false
|
||||
}
|
||||
this._renderer.clear(true)
|
||||
this.composer.render()
|
||||
return true
|
||||
}
|
||||
|
||||
public resize(width: number, height: number) {
|
||||
@@ -131,15 +201,15 @@ export class Pipeline {
|
||||
}
|
||||
|
||||
public onStationaryBegin() {
|
||||
this.renderType = RenderType.ACCUMULATION
|
||||
this.staticAOGenerationPass.enabled = true
|
||||
this.accumulationFrame = 0
|
||||
// this.renderType = RenderType.ACCUMULATION
|
||||
// this.staticAOGenerationPass.enabled = true
|
||||
// this.accumulationFrame = 0
|
||||
console.warn('Starting stationary')
|
||||
}
|
||||
|
||||
public onStationaryEnd() {
|
||||
this.renderType = RenderType.NORMAL
|
||||
this.staticAOGenerationPass.enabled = false
|
||||
// this.renderType = RenderType.NORMAL
|
||||
// this.staticAOGenerationPass.enabled = false
|
||||
console.warn('Ending stationary')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { Camera, Plane, Scene, Texture } from 'three'
|
||||
|
||||
export type InputColorTextureUniform = 'tDiffuse'
|
||||
export type InputDepthTextureUniform = 'tDepth'
|
||||
|
||||
export interface SpecklePass {
|
||||
onBeforeRender?: () => void
|
||||
onAferRender?: () => void
|
||||
|
||||
get displayName(): string
|
||||
get outputTexture(): Texture
|
||||
|
||||
update?(scene: Scene, camera: Camera)
|
||||
setTexture?(uName: string, texture: Texture)
|
||||
setParams?(params: unknown)
|
||||
setClippingPlanes?(planes: Plane[])
|
||||
}
|
||||
Reference in New Issue
Block a user