Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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