Implemented interpolating during frame accumulation between the dynamic SAO and the static AO. This makes the transition much more smooth and seamless than simply jumping straight to the static AO which begins accumulating from 0

This commit is contained in:
AlexandruPopovici
2022-10-17 14:32:00 +03:00
parent 2a8ad84563
commit 6eced47c44
5 changed files with 85 additions and 9 deletions
@@ -0,0 +1,19 @@
export const speckleApplyAoFrag = `
uniform float opacity;
uniform sampler2D tDiffuse;
uniform sampler2D tDiffuseInterp;
varying vec2 vUv;
#if ACCUMULATE == 1
uniform float frameIndex;
#endif
void main() {
vec3 currentSample = texture2D( tDiffuse, vUv ).rgb;
vec3 interpSample = texture2D( tDiffuseInterp, vUv ).rgb;
#if ACCUMULATE == 1
gl_FragColor.rgb = mix(interpSample, currentSample, frameIndex/float(NUM_FRAMES));
#else
gl_FragColor.rgb = currentSample;
#endif
gl_FragColor.a = 1.;
}`
@@ -0,0 +1,6 @@
export const speckleApplyAoVert = `
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}`
@@ -1,28 +1,43 @@
import {
AddEquation,
Camera,
CustomBlending,
DstAlphaFactor,
DstColorFactor,
NoBlending,
Scene,
ShaderMaterial,
Texture,
UniformsUtils,
ZeroFactor
} 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'
import { speckleApplyAoFrag } from '../materials/shaders/speckle-apply-ao-frag'
import { speckleApplyAoVert } from '../materials/shaders/speckle-apply-ao-vert'
import { Pipeline, RenderType } from './Pipeline'
import {
InputColorTextureUniform,
InputColorInterpolateTextureUniform,
SpeckleProgressivePass
} from './SpecklePass'
export class ApplySAOPass extends Pass implements SpecklePass {
export class ApplySAOPass extends Pass implements SpeckleProgressivePass {
private fsQuad: FullScreenQuad
public materialCopy: ShaderMaterial
private frameIndex = 0
constructor() {
super()
this.materialCopy = new ShaderMaterial({
uniforms: UniformsUtils.clone(CopyShader.uniforms),
vertexShader: CopyShader.vertexShader,
fragmentShader: CopyShader.fragmentShader,
defines: {
ACCUMULATE: 0
},
uniforms: {
tDiffuse: { value: null },
tDiffuseInterp: { value: null },
frameIndex: { value: 0 }
},
vertexShader: speckleApplyAoVert,
fragmentShader: speckleApplyAoFrag,
blending: NoBlending
})
this.materialCopy.transparent = true
@@ -40,7 +55,10 @@ export class ApplySAOPass extends Pass implements SpecklePass {
this.fsQuad = new FullScreenQuad(this.materialCopy)
}
public setTexture(uName: InputColorTextureUniform, texture: Texture) {
public setTexture(
uName: InputColorTextureUniform | InputColorInterpolateTextureUniform,
texture: Texture
) {
this.materialCopy.uniforms[uName].value = texture
this.materialCopy.needsUpdate = true
}
@@ -57,6 +75,28 @@ export class ApplySAOPass extends Pass implements SpecklePass {
params
}
setFrameIndex(index: number) {
this.frameIndex = index
}
setRenderType(type: RenderType) {
if (type === RenderType.NORMAL) {
this.materialCopy.defines['ACCUMULATE'] = 0
} else {
this.materialCopy.defines['ACCUMULATE'] = 1
this.frameIndex = 0
}
this.materialCopy.needsUpdate = true
}
public update(scene: Scene, camera: Camera) {
scene
camera
this.materialCopy.defines['NUM_FRAMES'] = Pipeline.ACCUMULATE_FRAMES
this.materialCopy.uniforms['frameIndex'].value = this.frameIndex
this.materialCopy.needsUpdate = true
}
render(renderer, writeBuffer, readBuffer /*, deltaTime, maskActive*/) {
writeBuffer
readBuffer
@@ -3,7 +3,7 @@ import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js'
import Batcher from '../batching/Batcher'
import SpeckleRenderer from '../SpeckleRenderer'
import { ApplySAOPass } from './ApplySAOPass'
import { ApplySAOPass } from './ApplyAOPass'
import { CopyOutputPass } from './CopyOutputPass'
import { DepthPass } from './DepthPass'
import { NormalsPass } from './NormalsPass'
@@ -257,6 +257,7 @@ export class Pipeline {
this.dynamicAoPass.setTexture('tDepth', this.depthPass.outputTexture)
this.dynamicAoPass.setTexture('tNormal', this.normalsPass.outputTexture)
this.applySaoPass.setTexture('tDiffuse', this.dynamicAoPass.outputTexture)
this.applySaoPass.setTexture('tDiffuseInterp', this.dynamicAoPass.outputTexture)
this.staticAoPass.setTexture('tDepth', this.depthPass.outputTexture)
let restoreVisibility
@@ -288,7 +289,10 @@ export class Pipeline {
this.dynamicAoPass.update(renderer.scene, renderer.camera)
this.normalsPass.update(renderer.scene, renderer.camera)
this.staticAoPass.update(renderer.scene, renderer.camera)
this.applySaoPass.update(renderer.scene, renderer.camera)
this.staticAoPass.setFrameIndex(this.accumulationFrame)
this.applySaoPass.setFrameIndex(this.accumulationFrame)
}
public render(): boolean {
@@ -326,16 +330,20 @@ export class Pipeline {
this.applySaoPass.enabled = true
this.staticAoPass.enabled = true
this.applySaoPass.setTexture('tDiffuse', this.staticAoPass.outputTexture)
this.applySaoPass.setTexture('tDiffuseInterp', this.dynamicAoPass.outputTexture)
this.applySaoPass.setRenderType(this.renderType)
console.warn('Starting stationary')
}
public onStationaryEnd() {
if (this.renderType === RenderType.NORMAL) return
this.accumulationFrame = 0
this.renderType = RenderType.NORMAL
this.staticAoPass.enabled = false
this.applySaoPass.enabled = true
this.dynamicAoPass.enabled = true
this.applySaoPass.setTexture('tDiffuse', this.dynamicAoPass.outputTexture)
this.applySaoPass.setRenderType(this.renderType)
console.warn('Ending stationary')
}
}
@@ -1,8 +1,10 @@
import { Camera, Plane, Scene, Texture } from 'three'
import { RenderType } from './Pipeline'
export type InputColorTextureUniform = 'tDiffuse'
export type InputDepthTextureUniform = 'tDepth'
export type InputNormalsTextureUniform = 'tNormal'
export type InputColorInterpolateTextureUniform = 'tDiffuseInterp'
export interface SpecklePass {
onBeforeRender?: () => void
@@ -19,4 +21,5 @@ export interface SpecklePass {
export interface SpeckleProgressivePass extends SpecklePass {
setFrameIndex(index: number)
setRenderType?(type: RenderType)
}