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:
@@ -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 );
|
||||
}`
|
||||
+48
-8
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user