Skip to content

feat: HBAO + SSGI + TRAA + MotionBlur #211

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
Binary file added .storybook/public/porsche.glb
Binary file not shown.
2 changes: 1 addition & 1 deletion .storybook/stories/Autofocus.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { EffectComposer, Autofocus } from '../../src'

// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction
const meta = {
title: 'Effect/Autofocus',
title: 'Effects/Autofocus',
component: Autofocus,
decorators: [
(Story) => (
Expand Down
56 changes: 56 additions & 0 deletions .storybook/stories/HBAO.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import * as React from 'react'
import * as THREE from 'three'
import type { Meta, StoryObj } from '@storybook/react'
import { EffectComposer, HBAO as HBAOImpl } from '../../src'
import { Canvas } from '@react-three/fiber'
import { Environment, useGLTF, OrbitControls } from '@react-three/drei'

const meta = {
title: 'Effects/HBAO',
component: HBAOImpl,
parameters: {
layout: 'fullscreen',
},
} satisfies Meta<typeof HBAOImpl>
export default meta

function Model() {
const gltf = useGLTF('/porsche.glb')
return <primitive object={gltf.scene} />
}

type Story = StoryObj<typeof meta>

export const HBAO: Story = {
render: (args) => (
<Canvas gl={{ antialias: false }} camera={{ fov: 35, position: [5, 3, 5] }}>
<OrbitControls />
<Environment preset="city" />
<EffectComposer disableNormalPass multisampling={0}>
<HBAOImpl {...args} />
</EffectComposer>
<Model />
<directionalLight position={[217, 43, 76]} />
</Canvas>
),
args: {
// AO
resolutionScale: 1,
spp: 8,
distance: 2,
distancePower: 1,
power: 2,
bias: 40,
thickness: 0.075,
color: new THREE.Color('black'),
useNormalPass: false,
// Poisson
iterations: 1,
radius: 8,
rings: 5.625,
lumaPhi: 10,
depthPhi: 2,
normalPhi: 3.25,
samples: 16,
},
}
59 changes: 59 additions & 0 deletions .storybook/stories/SSGI.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import * as React from 'react'
import type { Meta, StoryObj } from '@storybook/react'
import { EffectComposer, SSGI as SSGIImpl, TRAA, MotionBlur } from '../../src'
import { Canvas } from '@react-three/fiber'
import { Environment, useGLTF, OrbitControls } from '@react-three/drei'

const meta = {
title: 'Effects/SSGI',
component: SSGIImpl,
parameters: {
layout: 'fullscreen',
},
} satisfies Meta<typeof SSGIImpl>
export default meta

function Model() {
const gltf = useGLTF('/porsche.glb')
return <primitive object={gltf.scene} />
}

type Story = StoryObj<typeof meta>

export const SSGI: Story = {
render: (args) => (
<Canvas gl={{ antialias: false }} camera={{ fov: 35, position: [5, 3, 5] }}>
<OrbitControls />
<Environment preset="city" />
<EffectComposer disableNormalPass multisampling={0}>
<SSGIImpl {...args} />
<TRAA />
<MotionBlur />
</EffectComposer>
<Model />
<directionalLight position={[217, 43, 76]} />
</Canvas>
),
args: {
distance: 10,
thickness: 10,
autoThickness: false,
maxRoughness: 1,
blend: 0.9,
denoiseIterations: 1,
denoiseKernel: 2,
denoiseDiffuse: 10,
denoiseSpecular: 10,
depthPhi: 2,
normalPhi: 50,
roughnessPhi: 1,
envBlur: 0.5,
importanceSampling: true,
directLightMultiplier: 1,
steps: 20,
refineSteps: 5,
spp: 1,
resolutionScale: 1,
missedRays: false,
},
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"maath": "^0.6.0",
"n8ao": "^1.6.6",
"postprocessing": "^6.32.1",
"realism-effects": "^1.1.2",
"screen-space-reflections": "^2.5.0",
"three-stdlib": "^2.23.4"
},
Expand Down
18 changes: 11 additions & 7 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
export * from './Selection'
export * from './EffectComposer'
export * from './util'

export * from './effects/Autofocus'
export * from './effects/Bloom'
export * from './effects/BrightnessContrast'
Expand Down Expand Up @@ -33,6 +29,14 @@ export * from './effects/TiltShift'
export * from './effects/TiltShift2'
export * from './effects/ASCII'

// These are not effect passes
export * from './effects/SSR'
export * from './effects/N8AO'
export * from './passes/HBAO'
export * from './passes/MotionBlur'
export * from './passes/N8AO'
export * from './passes/SSGI'
export * from './passes/SSR'
export * from './passes/TRAA'
export * from './passes/useVelocityBuffer'

export * from './Selection'
export * from './EffectComposer'
export * from './util'
121 changes: 121 additions & 0 deletions src/passes/HBAO.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import { forwardRef, useContext, useEffect, useMemo } from 'react'
import * as THREE from 'three'
import { EffectComposer, EffectPass } from 'postprocessing'
// @ts-ignore
import { VelocityDepthNormalPass, HBAOEffect } from 'realism-effects'
import { EffectComposerContext } from '../EffectComposer'
import { useVelocityBuffer } from './useVelocityBuffer'

export interface HBAOOptions {
// AO options
resolutionScale: number
spp: number
distance: number
distancePower: number
power: number
bias: number
thickness: number
color: THREE.Color
useNormalPass: boolean
velocityDepthNormalPass: VelocityDepthNormalPass | null
normalTexture: THREE.Texture | null
// Poisson blur options
iterations: number
radius: number
rings: number
lumaPhi: number
depthPhi: number
normalPhi: number
samples: number
// normalTexture: THREE.Texture | null
}

export class HBAOPass extends EffectPass {
constructor(composer: EffectComposer, camera: THREE.Camera, scene: THREE.Scene, options?: Partial<HBAOOptions>) {
super(camera, new HBAOEffect(composer, camera, scene, options))
}
}

export interface HBAOProps extends Omit<Partial<HBAOOptions>, 'velocityDepthNormalPass'>, Partial<HBAOPass> {}

export const HBAO = forwardRef<HBAOPass, HBAOProps>(function HBAO(
{
// AO
resolutionScale = 1,
spp = 8,
distance = 2,
distancePower = 1,
power = 2,
bias = 40,
thickness = 0.075,
color = new THREE.Color('black'),
useNormalPass = false,
normalTexture = null,
// Poisson
iterations = 1,
radius = 8,
rings = 5.625,
lumaPhi = 10,
depthPhi = 2,
normalPhi = 3.25,
samples = 16,
...props
},
ref
) {
const velocityDepthNormalPass = useVelocityBuffer()
const { composer, camera, scene } = useContext(EffectComposerContext)
const effect = useMemo(
() =>
new HBAOPass(composer, camera, scene, {
resolutionScale,
spp,
distance,
distancePower,
power,
bias,
thickness,
color,
useNormalPass,
velocityDepthNormalPass,
normalTexture,
iterations,
radius,
rings,
lumaPhi,
depthPhi,
normalPhi,
samples,
}),
[
composer,
camera,
scene,
resolutionScale,
spp,
distance,
distancePower,
power,
bias,
thickness,
color,
useNormalPass,
velocityDepthNormalPass,
normalTexture,
iterations,
radius,
rings,
lumaPhi,
depthPhi,
normalPhi,
samples,
]
)
useEffect(() => {
return () => {
effect.dispose()
}
}, [effect])

return <primitive {...props} ref={ref} object={effect} />
})
27 changes: 27 additions & 0 deletions src/passes/MotionBlur.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { forwardRef, useContext, useEffect, useMemo } from 'react'
import { VelocityBuffer, useVelocityBuffer } from './useVelocityBuffer'
import { EffectPass } from 'postprocessing'
// @ts-ignore
import { MotionBlurEffect } from 'realism-effects'
import { EffectComposerContext } from '../EffectComposer'

export class MotionBlurPass extends EffectPass {
constructor(camera: THREE.Camera, velocityBuffer: VelocityBuffer) {
super(camera, new MotionBlurEffect(velocityBuffer))
}
}

export interface MotionBlurProps extends Partial<MotionBlurPass> {}

export const MotionBlur = forwardRef<MotionBlurPass, MotionBlurProps>(function MotionBlur(props, ref) {
const velocityBuffer = useVelocityBuffer()
const { camera } = useContext(EffectComposerContext)
const effect = useMemo(() => new MotionBlurPass(camera, velocityBuffer), [camera, velocityBuffer])
useEffect(() => {
return () => {
effect.dispose()
}
}, [effect])

return <primitive {...props} ref={ref} object={effect} />
})
File renamed without changes.
Loading