Restructuring how the pipeline and it's passes work so we can extend/configure them more easily. Added the concept of SpecklePass

This commit is contained in:
AlexandruPopovici
2022-10-12 18:59:07 +03:00
parent 20ddbea6f8
commit 75a2a6ca93
4 changed files with 346 additions and 321 deletions
@@ -0,0 +1,91 @@
import {
Camera,
Color,
DoubleSide,
NoBlending,
RGBADepthPacking,
Scene,
Texture,
WebGLRenderTarget
} from 'three'
import { Pass } from 'three/examples/jsm/postprocessing/Pass'
import SpeckleDepthMaterial from '../materials/SpeckleDepthMaterial'
import { SpecklePass } from './Pipeline'
export class DepthPass extends Pass implements SpecklePass {
private renderTarget: WebGLRenderTarget
private depthMaterial: SpeckleDepthMaterial = null
private scene: Scene
private camera: Camera
private colorBuffer: Color = new Color()
get displayName(): string {
return 'DEPTH'
}
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.depthMaterial = new SpeckleDepthMaterial(
{
depthPacking: RGBADepthPacking
},
['USE_RTE', 'ALPHATEST_REJECTION']
)
this.depthMaterial.blending = NoBlending
this.depthMaterial.side = DoubleSide
}
public update(camera: Camera, scene: Scene) {
this.camera = camera
this.scene = scene
}
public render(renderer, writeBuffer, readBuffer) {
writeBuffer
readBuffer
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.depthMaterial
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)
}
public setSize(width: number, height: number) {
this.renderTarget.setSize(width, height)
}
}
@@ -1,111 +1,61 @@
import { Camera, Plane, Scene, Vector2, WebGLRenderer } from 'three'
import { Camera, Plane, Scene, Texture, Vector2, WebGLRenderer } from 'three'
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js'
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js'
import { SAOPassParams } from 'three/examples/jsm/postprocessing/SAOPass.js'
import Batcher from '../batching/Batcher'
import { ApplySAOPass } from './ApplySAOPass'
import { NormalsType, SpeckleDynamicSAOPass } from './SpeckleDynamicSAOPass'
import {
DefaultSpeckleDynamicSAOPassParams,
NormalsType,
SpeckleDynamicSAOPass,
SpeckleDynamicSAOPassParams
} from './SpeckleDynamicSAOPass'
import { SpeckleStaticAOGeneratePass } from './SpeckleStaticAOGeneratePass'
enum RenderType {
NORMAL,
ACCUMULATION
}
export interface SpecklePass {
get displayName(): string
get outputTexture(): Texture
}
export interface PipelineOptions {
saoEnabled?: boolean
saoParams?: Partial<SAOPassParams>
saoScaleOffset?: number
saoNormalsRendering?: NormalsType
minDistance?: number
maxDistance?: number
ssaoKernelRadius?: number
progressiveAO?: number
progressive?: boolean
dynamicAoEnabled: boolean
dynamicAoParams: SpeckleDynamicSAOPassParams
}
export const DefaultPipelineOptions: PipelineOptions = {
saoEnabled: true,
saoParams: {
saoBias: 0.15,
saoIntensity: 1.25,
saoScale: 434,
saoKernelRadius: 10,
saoMinResolution: 0,
saoBlur: true,
saoBlurRadius: 4,
saoBlurStdDev: 4,
saoBlurDepthCutoff: 0.0007
},
saoScaleOffset: 0,
saoNormalsRendering: NormalsType.ACCURATE,
minDistance: 0,
maxDistance: 0.008,
ssaoKernelRadius: 0.5,
progressiveAO: 0,
progressive: true
dynamicAoEnabled: true,
dynamicAoParams: DefaultSpeckleDynamicSAOPassParams
// saoScaleOffset: 0,
// saoNormalsRendering: NormalsType.ACCURATE,
// minDistance: 0,
// maxDistance: 0.008,
// ssaoKernelRadius: 0.5,
// progressiveAO: 0,
// progressive: true
}
export class Pipeline {
private _renderer: WebGLRenderer = null
private _batcher: Batcher = null
private _pipelineOptions: PipelineOptions = {}
private _pipelineOptions: PipelineOptions = Object.assign({}, DefaultPipelineOptions)
private composer: EffectComposer = null
private renderPass: RenderPass = null
private saoPass: SpeckleDynamicSAOPass = null
private dynamicAoPass: SpeckleDynamicSAOPass = null
private applySaoPass: ApplySAOPass = null
private staticAOGenerationPass: SpeckleStaticAOGeneratePass = 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: PipelineOptions) {
public set pipelineOptions(options: Partial<PipelineOptions>) {
Object.assign(this._pipelineOptions, options)
if (this.saoPass) {
this.applySaoPass.enabled = this._pipelineOptions.saoEnabled
Object.assign(this.saoPass.params, this._pipelineOptions.saoParams)
this.saoPass.params.saoScale += this._pipelineOptions.saoScaleOffset
this.saoPass.normalsRendering = this._pipelineOptions.saoNormalsRendering
if (
this.staticAOGenerationPass.minDistance !== this._pipelineOptions.minDistance ||
this.staticAOGenerationPass.maxDistance !== this._pipelineOptions.maxDistance
)
this.accumulationFrame = 0
if (
this._pipelineOptions.ssaoKernelRadius !== undefined &&
this.staticAOGenerationPass.ssaoKernelRadius !==
this._pipelineOptions.ssaoKernelRadius
) {
this.accumulationFrame = 0
this.staticAOGenerationPass.ssaoKernelRadius =
this._pipelineOptions.ssaoKernelRadius
}
if (
this._pipelineOptions.progressiveAO !== undefined &&
this.staticAOGenerationPass.progressiveAO !==
this._pipelineOptions.progressiveAO
) {
this.accumulationFrame = 0
this.staticAOGenerationPass.progressiveAO = this._pipelineOptions.progressiveAO
this.staticAOGenerationPass.aoMaterial.defines['AO_ESTIMATOR'] =
this._pipelineOptions.progressiveAO
this.staticAOGenerationPass.aoMaterial.needsUpdate = true
}
this.staticAOGenerationPass.minDistance = this._pipelineOptions.minDistance
this.staticAOGenerationPass.maxDistance = this._pipelineOptions.maxDistance
if (
this._pipelineOptions.saoParams.saoKernelRadius !== undefined &&
this.staticAOGenerationPass.kernelRadius !==
this._pipelineOptions.saoParams.saoKernelRadius
) {
this.accumulationFrame = 0
this.staticAOGenerationPass.kernelRadius =
this._pipelineOptions.saoParams.saoKernelRadius
}
this.enableProgressive = this._pipelineOptions.progressive
}
}
private set renderType(value: RenderType) {
@@ -121,7 +71,7 @@ export class Pipeline {
}
public configure(scene: Scene, camera: Camera) {
this.saoPass = new SpeckleDynamicSAOPass(
this.dynamicAoPass = new SpeckleDynamicSAOPass(
scene,
camera,
this._batcher,
@@ -129,22 +79,23 @@ export class Pipeline {
NormalsType.IMPROVED
)
this.staticAOGenerationPass = new SpeckleStaticAOGeneratePass(this._batcher)
this.staticAOGenerationPass.depthTexture = this.saoPass.depthRenderTarget.texture
this.composer.addPass(this.saoPass)
this.staticAOGenerationPass.depthTexture =
this.dynamicAoPass.depthRenderTarget.texture
this.composer.addPass(this.dynamicAoPass)
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.saoPass.saoRenderTarget.texture)
this.applySaoPass.setAoTexture(this.dynamicAoPass.saoRenderTarget.texture)
this.applySaoPass.renderToScreen = true
this.composer.addPass(this.applySaoPass)
}
public updateClippingPlanes(planes: Plane[]) {
this.saoPass.depthMaterial.clippingPlanes = planes
this.saoPass.normalMaterial.clippingPlanes = planes
this.dynamicAoPass.depthMaterial.clippingPlanes = planes
this.dynamicAoPass.normalMaterial.clippingPlanes = planes
}
public render(scene: Scene, camera: Camera): boolean {
@@ -153,11 +104,11 @@ export class Pipeline {
if (this._renderType === RenderType.NORMAL) {
this._renderer.clear(true)
this.applySaoPass.setAoTexture(this.saoPass.saoRenderTarget.texture)
this.applySaoPass.setAoTexture(this.dynamicAoPass.saoRenderTarget.texture)
this.renderPass.scene = scene
this.renderPass.camera = camera
this.saoPass.scene = scene
this.saoPass.camera = camera
this.dynamicAoPass.scene = scene
this.dynamicAoPass.camera = camera
this.composer.render()
return true
} else if (this.enableProgressive) {
@@ -165,8 +116,8 @@ export class Pipeline {
this.applySaoPass.setAoTexture(this.staticAOGenerationPass.outputTexture.texture)
this.renderPass.scene = scene
this.renderPass.camera = camera
this.saoPass.scene = scene
this.saoPass.camera = camera
this.dynamicAoPass.scene = scene
this.dynamicAoPass.camera = camera
this.staticAOGenerationPass.update(camera, this.accumulationFrame)
this.composer.render()
this.accumulationFrame++
@@ -1,25 +1,23 @@
import {
AdditiveBlending,
Camera,
DoubleSide,
Color,
NoBlending,
OrthographicCamera,
PerspectiveCamera,
RGBADepthPacking,
Scene,
ShaderMaterial,
Texture,
UniformsUtils,
Vector2
Vector2,
WebGLRenderTarget
} from 'three'
import { FullScreenQuad } from 'three/examples/jsm/postprocessing/Pass'
import { SAOPass } from 'three/examples/jsm/postprocessing/SAOPass.js'
import { BlurShaderUtils } from 'three/examples/jsm/shaders/DepthLimitedBlurShader.js'
import { FullScreenQuad, Pass } from 'three/examples/jsm/postprocessing/Pass'
import { speckleSaoFrag } from '../materials/shaders/speckle-sao-frag'
import { speckleSaoVert } from '../materials/shaders/speckle-sao-vert'
import { SAOShader } from 'three/examples/jsm/shaders/SAOShader.js'
import Batcher from '../batching/Batcher'
import SpeckleDepthMaterial from '../materials/SpeckleDepthMaterial'
import SpeckleNormalMaterial from '../materials/SpeckleNormalMaterial'
import { DepthLimitedBlurShader } from 'three/examples/jsm/shaders/DepthLimitedBlurShader.js'
import { BlurShaderUtils } from 'three/examples/jsm/shaders/DepthLimitedBlurShader.js'
import { SpecklePass } from './Pipeline'
export enum NormalsType {
DEFAULT = 0,
@@ -27,62 +25,75 @@ export enum NormalsType {
ACCURATE = 2
}
export interface SpeckleDynamicSAOPassParams {
intensity: number
scale: number
kernelRadius: number
bias: number
normalsType: NormalsType
blurEnabled: boolean
blurRadius: number
blurStdDev: number
blurDepthCutoff: number
}
export const DefaultSpeckleDynamicSAOPassParams = {
intensity: 1.25,
scale: 0,
kernelRadius: 10,
bias: 0.15,
normalsType: NormalsType.ACCURATE,
blurEnabled: true,
blurRadius: 4,
blurStdDev: 4,
blurDepthCutoff: 0.0007
}
/**
* SAO implementation inspired from bhouston previous SAO work
*/
export class SpeckleDynamicSAOPass extends SAOPass {
private _oldClearColor
private prevStdDev
private prevNumSamples
private batcher: Batcher = null
private normalsType: NormalsType = NormalsType.IMPROVED
export class SpeckleDynamicSAOPass extends Pass implements SpecklePass {
private params: SpeckleDynamicSAOPassParams
private colorBuffer: Color = new Color()
private saoMaterial: ShaderMaterial = null
private vBlurMaterial: ShaderMaterial = null
private hBlurMaterial: ShaderMaterial = null
private saoRenderTarget: WebGLRenderTarget = null
private blurIntermediateRenderTarget: WebGLRenderTarget = null
private fsQuad: FullScreenQuad = null
public set normalsRendering(type: NormalsType) {
this.normalsType = type
this.saoMaterial.defines['NORMAL_TEXTURE'] =
this.normalsType === NormalsType.DEFAULT ? 1 : 0
this.saoMaterial.defines['IMPROVED_NORMAL_RECONSTRUCTION'] =
this.normalsType === NormalsType.IMPROVED ? 1 : 0
this.saoMaterial.defines['ACCURATE_NORMAL_RECONSTRUCTION'] =
this.normalsType === NormalsType.ACCURATE ? 1 : 0
this.saoMaterial.needsUpdate = true
private prevStdDev: number
private prevNumSamples: number
get displayName(): string {
return 'SAO'
}
constructor(
scene: Scene,
camera: Camera,
batcher: Batcher,
useDepthTexture = false,
normalsType: NormalsType,
resolution = new Vector2(256, 256)
) {
super(scene, camera, useDepthTexture, true, resolution)
get outputTexture(): Texture {
return this.saoRenderTarget.texture
}
this.batcher = batcher
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
}
/** 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.depthRenderTarget.depthBuffer = true
this.depthRenderTarget.stencilBuffer = true
this.normalRenderTarget.depthBuffer = true
this.normalRenderTarget.stencilBuffer = true
constructor() {
super()
this.depthMaterial = new SpeckleDepthMaterial(
{
depthPacking: RGBADepthPacking
},
['USE_RTE', 'ALPHATEST_REJECTION']
)
this.depthMaterial.blending = NoBlending
this.depthMaterial.side = DoubleSide
this.normalMaterial = new SpeckleNormalMaterial({}, ['USE_RTE'])
this.normalMaterial.blending = NoBlending
this.normalMaterial.side = DoubleSide
// 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({
defines: {
NUM_SAMPLES: 7,
@@ -96,211 +107,184 @@ export class SpeckleDynamicSAOPass extends SAOPass {
vertexShader: speckleSaoVert,
uniforms: UniformsUtils.clone(SAOShader.uniforms)
})
this.normalsRendering = normalsType
this.saoMaterial.extensions.derivatives = true
this.saoMaterial.defines['DEPTH_PACKING'] = this.supportsDepthTextureExtension
? 0
: 1
this.saoMaterial.defines['PERSPECTIVE_CAMERA'] = (this.camera as PerspectiveCamera)
this.saoMaterial.defines['DEPTH_PACKING'] = 1
this.saoMaterial.uniforms['tDepth'].value = null
this.saoMaterial.uniforms['tNormal'].value = null
this.saoMaterial.uniforms['size'].value.set(256, 256)
this.saoMaterial.uniforms['minResolution'].value = 0
this.saoMaterial.blending = NoBlending
this.vBlurMaterial = new ShaderMaterial({
uniforms: UniformsUtils.clone(DepthLimitedBlurShader.uniforms),
defines: Object.assign({}, DepthLimitedBlurShader.defines),
vertexShader: DepthLimitedBlurShader.vertexShader,
fragmentShader: DepthLimitedBlurShader.fragmentShader
})
this.vBlurMaterial.defines['DEPTH_PACKING'] = 1
this.vBlurMaterial.uniforms['tDiffuse'].value = this.saoRenderTarget.texture
this.vBlurMaterial.uniforms['tDepth'].value = null
this.vBlurMaterial.uniforms['size'].value.set(256, 256)
this.vBlurMaterial.blending = NoBlending
this.hBlurMaterial = new ShaderMaterial({
uniforms: UniformsUtils.clone(DepthLimitedBlurShader.uniforms),
defines: Object.assign({}, DepthLimitedBlurShader.defines),
vertexShader: DepthLimitedBlurShader.vertexShader,
fragmentShader: DepthLimitedBlurShader.fragmentShader
})
this.hBlurMaterial.defines['DEPTH_PACKING'] = 1
this.hBlurMaterial.uniforms['tDiffuse'].value =
this.blurIntermediateRenderTarget.texture
this.hBlurMaterial.uniforms['tDepth'].value = null
this.hBlurMaterial.uniforms['size'].value.set(256, 256)
this.hBlurMaterial.blending = NoBlending
this.fsQuad = new FullScreenQuad(this.saoMaterial)
}
public update(scene: Scene, camera: Camera) {
/** SAO DEFINES */
this.saoMaterial.defines['PERSPECTIVE_CAMERA'] = (camera as PerspectiveCamera)
.isPerspectiveCamera
? 1
: 0
this.saoMaterial.uniforms['tDepth'].value = this.supportsDepthTextureExtension
? this.beautyRenderTarget.depthTexture
: this.depthRenderTarget.texture
this.saoMaterial.uniforms['tNormal'].value = this.normalRenderTarget.texture
this.saoMaterial.uniforms['size'].value.set(this.resolution.x, this.resolution.y)
this.saoMaterial.defines['NORMAL_TEXTURE'] =
this.params.normalsType === NormalsType.DEFAULT ? 1 : 0
this.saoMaterial.defines['IMPROVED_NORMAL_RECONSTRUCTION'] =
this.params.normalsType === NormalsType.IMPROVED ? 1 : 0
this.saoMaterial.defines['ACCURATE_NORMAL_RECONSTRUCTION'] =
this.params.normalsType === NormalsType.ACCURATE ? 1 : 0
/** SAO UNIFORMS */
this.saoMaterial.uniforms['cameraNear'].value = (
camera as PerspectiveCamera | OrthographicCamera
).near
this.saoMaterial.uniforms['cameraFar'].value = (
camera as PerspectiveCamera | OrthographicCamera
).far
this.saoMaterial.uniforms['cameraInverseProjectionMatrix'].value.copy(
this.camera.projectionMatrixInverse
camera.projectionMatrixInverse
)
this.saoMaterial.uniforms['cameraProjectionMatrix'].value =
this.camera.projectionMatrix
this.saoMaterial.blending = NoBlending
this.saoMaterial.uniforms['cameraProjectionMatrix'].value = camera.projectionMatrix
/** SAO UNIFORM PARAMS */
this.saoMaterial.uniforms['intensity'].value = this.params.intensity
this.saoMaterial.uniforms['scale'].value = this.params.scale
this.saoMaterial.uniforms['kernelRadius'].value = this.params.kernelRadius
this.saoMaterial.uniforms['bias'].value = this.params.bias
this.saoMaterial.needsUpdate = true
/** BLUR DEFINES */
this.vBlurMaterial.defines['PERSPECTIVE_CAMERA'] = (camera as PerspectiveCamera)
.isPerspectiveCamera
? 1
: 0
this.hBlurMaterial.defines['PERSPECTIVE_CAMERA'] = (camera as PerspectiveCamera)
.isPerspectiveCamera
? 1
: 0
/** BLUR UNIFORMS */
this.vBlurMaterial.uniforms['cameraNear'].value = (
camera as PerspectiveCamera | OrthographicCamera
).near
this.vBlurMaterial.uniforms['cameraFar'].value = (
camera as PerspectiveCamera | OrthographicCamera
).far
this.hBlurMaterial.uniforms['cameraNear'].value = (
camera as PerspectiveCamera | OrthographicCamera
).near
this.hBlurMaterial.uniforms['cameraFar'].value = (
camera as PerspectiveCamera | OrthographicCamera
).far
/** BLUR UNIFORM PARAMS */
const depthCutoff =
this.params.blurDepthCutoff *
((camera as PerspectiveCamera | OrthographicCamera).far -
(camera as PerspectiveCamera | OrthographicCamera).near)
this.vBlurMaterial.uniforms['depthCutoff'].value = depthCutoff
this.hBlurMaterial.uniforms['depthCutoff'].value = depthCutoff
this.params.blurRadius = Math.floor(this.params.blurRadius)
if (
this.prevStdDev !== this.params.blurStdDev ||
this.prevNumSamples !== this.params.blurRadius
) {
BlurShaderUtils.configure(
this.vBlurMaterial,
this.params.blurRadius,
this.params.blurStdDev,
new Vector2(0, 1)
)
BlurShaderUtils.configure(
this.hBlurMaterial,
this.params.blurRadius,
this.params.blurStdDev,
new Vector2(1, 0)
)
this.prevStdDev = this.params.blurStdDev
this.prevNumSamples = this.params.blurRadius
}
this.vBlurMaterial.needsUpdate = true
this.hBlurMaterial.needsUpdate = true
}
public render(renderer, writeBuffer, readBuffer) {
writeBuffer
readBuffer
if (this.params.output === 1) {
return
}
renderer.getClearColor(this._oldClearColor)
this.oldClearAlpha = renderer.getClearAlpha()
renderer.autoClear = false
renderer.setRenderTarget(this.depthRenderTarget)
renderer.clear()
this.saoMaterial.blending = AdditiveBlending
this.saoMaterial.uniforms['bias'].value = this.params.saoBias
this.saoMaterial.uniforms['intensity'].value = this.params.saoIntensity
this.saoMaterial.uniforms['scale'].value = this.params.saoScale
this.saoMaterial.uniforms['kernelRadius'].value = this.params.saoKernelRadius
this.saoMaterial.uniforms['minResolution'].value = this.params.saoMinResolution
this.saoMaterial.uniforms['cameraNear'].value = (
this.camera as PerspectiveCamera | OrthographicCamera
).near
this.saoMaterial.uniforms['cameraFar'].value = (
this.camera as PerspectiveCamera | OrthographicCamera
).far
this.saoMaterial.uniforms['cameraInverseProjectionMatrix'].value.copy(
this.camera.projectionMatrixInverse
)
this.saoMaterial.uniforms['cameraProjectionMatrix'].value =
this.camera.projectionMatrix
// this.saoMaterial.uniforms['randomSeed'].value = Math.random()
const depthCutoff =
this.params.saoBlurDepthCutoff *
((this.camera as PerspectiveCamera | OrthographicCamera).far -
(this.camera as PerspectiveCamera | OrthographicCamera).near)
this.vBlurMaterial.uniforms['depthCutoff'].value = depthCutoff
this.hBlurMaterial.uniforms['depthCutoff'].value = depthCutoff
this.vBlurMaterial.uniforms['cameraNear'].value = (
this.camera as PerspectiveCamera | OrthographicCamera
).near
this.vBlurMaterial.uniforms['cameraFar'].value = (
this.camera as PerspectiveCamera | OrthographicCamera
).far
this.hBlurMaterial.uniforms['cameraNear'].value = (
this.camera as PerspectiveCamera | OrthographicCamera
).near
this.hBlurMaterial.uniforms['cameraFar'].value = (
this.camera as PerspectiveCamera | OrthographicCamera
).far
this.params.saoBlurRadius = Math.floor(this.params.saoBlurRadius)
if (
this.prevStdDev !== this.params.saoBlurStdDev ||
this.prevNumSamples !== this.params.saoBlurRadius
) {
BlurShaderUtils.configure(
this.vBlurMaterial,
this.params.saoBlurRadius,
this.params.saoBlurStdDev,
new Vector2(0, 1)
)
BlurShaderUtils.configure(
this.hBlurMaterial,
this.params.saoBlurRadius,
this.params.saoBlurStdDev,
new Vector2(1, 0)
)
this.prevStdDev = this.params.saoBlurStdDev
this.prevNumSamples = this.params.saoBlurRadius
}
const restoreVisibility = this.batcher.saveVisiblity()
const opaque = this.batcher.getOpaque()
this.batcher.applyVisibility(opaque)
// Re-render scene if depth texture extension is not supported
if (!this.supportsDepthTextureExtension) {
// Clear rule : far clipping plane in both RGBA and Basic encoding
this.renderOverride(
renderer,
this.depthMaterial,
this.depthRenderTarget,
0x000000,
1.0
)
}
if (this.normalsType === NormalsType.DEFAULT) {
if (this.supportsNormalTexture) {
// Clear rule : default normal is facing the camera
this.renderOverride(
renderer,
this.normalMaterial,
this.normalRenderTarget,
0x7777ff,
1.0
)
}
}
this.batcher.applyVisibility(restoreVisibility)
// const restoreVisibility = this.batcher.saveVisiblity()
// const opaque = this.batcher.getOpaque()
// this.batcher.applyVisibility(opaque)
// this.batcher.applyVisibility(restoreVisibility)
// Rendering SAO texture
this.renderPass(renderer, this.saoMaterial, this.saoRenderTarget, 0x000000, 1.0)
// Blurring SAO texture
if (this.params.saoBlur) {
this.renderPass(
renderer,
this.vBlurMaterial,
this.blurIntermediateRenderTarget,
0xffffff,
1.0
)
this.renderPass(renderer, this.hBlurMaterial, this.saoRenderTarget, 0xffffff, 1.0)
}
}
public renderPass(
renderer,
passMaterial,
renderTarget,
clearColor = undefined,
clearAlpha = undefined
) {
// save original state
renderer.getClearColor(this.originalClearColor)
renderer.getClearColor(this.colorBuffer)
const originalClearAlpha = renderer.getClearAlpha()
const originalAutoClear = renderer.autoClear
renderer.setRenderTarget(renderTarget)
renderer.setRenderTarget(this.saoRenderTarget)
// setup pass state
renderer.autoClear = false
if (clearColor !== undefined && clearColor !== null) {
renderer.setClearColor(clearColor)
renderer.setClearAlpha(clearAlpha || 0.0)
renderer.setClearColor(0xffffff)
renderer.setClearAlpha(1.0)
renderer.clear()
this.fsQuad.material = this.saoMaterial
this.fsQuad.render(renderer)
if (this.params.blurEnabled) {
renderer.setRenderTarget(this.blurIntermediateRenderTarget)
renderer.setClearColor(0xffffff)
renderer.setClearAlpha(1.0)
renderer.clear()
this.fsQuad.material = this.vBlurMaterial
this.fsQuad.render(renderer)
renderer.setRenderTarget(this.saoRenderTarget)
this.fsQuad.material = this.hBlurMaterial
this.fsQuad.render(renderer)
}
;(this.fsQuad as FullScreenQuad).material = passMaterial
;(this.fsQuad as FullScreenQuad).render(renderer)
// restore original state
renderer.autoClear = originalAutoClear
renderer.setClearColor(this.originalClearColor)
renderer.setClearColor(this.colorBuffer)
renderer.setClearAlpha(originalClearAlpha)
}
public renderOverride(
renderer,
overrideMaterial,
renderTarget,
clearColor,
clearAlpha
) {
renderer.getClearColor(this.originalClearColor)
const originalClearAlpha = renderer.getClearAlpha()
const originalAutoClear = renderer.autoClear
public setSize(width: number, height: number) {
this.saoRenderTarget.setSize(width, height)
this.blurIntermediateRenderTarget.setSize(width, height)
renderer.setRenderTarget(renderTarget)
renderer.autoClear = false
clearColor = overrideMaterial.clearColor || clearColor
clearAlpha = overrideMaterial.clearAlpha || clearAlpha
if (clearColor !== undefined && clearColor !== null) {
renderer.setClearColor(clearColor)
renderer.setClearAlpha(clearAlpha || 0.0)
renderer.clear()
}
const shadowmapEnabled = renderer.shadowMap.enabled
const shadowmapNeedsUpdate = renderer.shadowMap.needsUpdate
this.scene.overrideMaterial = overrideMaterial
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.originalClearColor)
renderer.setClearAlpha(originalClearAlpha)
this.saoMaterial.uniforms['size'].value.set(width, height)
this.vBlurMaterial.uniforms['size'].value.set(width, height)
this.hBlurMaterial.uniforms['size'].value.set(width, height)
this.saoMaterial.needsUpdate = true
}
}
@@ -174,7 +174,6 @@ export class SpeckleStaticAOGeneratePass extends Pass {
public render(renderer, writeBuffer, readBuffer) {
writeBuffer
readBuffer
// save original state
const originalClearColor = new Color()
renderer.getClearColor(originalClearColor)