Skip to content

Commit b07d5b4

Browse files
committed
feat: add Example effect
1 parent 56e3687 commit b07d5b4

File tree

3 files changed

+125
-0
lines changed

3 files changed

+125
-0
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import React, { memo } from 'react'
2+
import * as THREE from 'three'
3+
import type { Meta, StoryObj } from '@storybook/react'
4+
import { Box, useTexture } from '@react-three/drei'
5+
6+
import { Setup } from '../Setup'
7+
import { EffectComposer, Example } from '../../src'
8+
import { BlendFunction } from 'postprocessing'
9+
10+
// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction
11+
const meta = {
12+
title: 'Effect/Example',
13+
component: Example,
14+
decorators: [(Story) => <Setup>{Story()}</Setup>],
15+
tags: ['autodocs'],
16+
argTypes: {
17+
blendFunction: {
18+
control: 'select',
19+
options: Object.keys(BlendFunction),
20+
mapping: Object.keys(BlendFunction).reduce((acc, k) => {
21+
acc[k] = BlendFunction[k]
22+
return acc
23+
}, {}),
24+
},
25+
opacity: { control: { type: 'range', min: 0, max: 1, step: 0.001 } },
26+
color: { control: { type: 'color' } },
27+
},
28+
} satisfies Meta<typeof Example>
29+
30+
export default meta
31+
type Story = StoryObj<typeof meta>
32+
33+
// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
34+
export const Primary: Story = {
35+
render: ({ color, ...args }) => (
36+
<>
37+
<Box />
38+
39+
<EffectComposer>
40+
<Example color={color && new THREE.Color(color)} {...args} />
41+
</EffectComposer>
42+
</>
43+
),
44+
args: {
45+
blendFunction: BlendFunction.ADD,
46+
color: 'red' as unknown as THREE.Color,
47+
},
48+
}

src/effects/Example.tsx

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import * as THREE from 'three'
2+
import { useRef } from 'react'
3+
import { useFrame, useThree } from '@react-three/fiber'
4+
import { BlendFunction, Effect } from 'postprocessing'
5+
6+
import { wrapEffect } from '../util'
7+
8+
//
9+
// Effect
10+
//
11+
12+
const ExampleShader = {
13+
fragment: `
14+
uniform vec3 color;
15+
uniform float time;
16+
void mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor) {
17+
outputColor = vec4(color, 0.5 + (cos(time) / 2.0 + 0.5));
18+
}
19+
`,
20+
}
21+
22+
type ExampleEffectOptions = {
23+
/** The color for this effect */
24+
color: THREE.Color
25+
/** The blend function of this effect */
26+
blendFunction?: BlendFunction
27+
}
28+
29+
export class ExampleEffect extends Effect {
30+
constructor({ color, blendFunction }: ExampleEffectOptions) {
31+
super('LensFlareEffect', ExampleShader.fragment, {
32+
blendFunction,
33+
uniforms: new Map<string, THREE.Uniform>([
34+
['color', new THREE.Uniform(color)],
35+
['time', new THREE.Uniform(0)],
36+
]),
37+
})
38+
}
39+
40+
update(_renderer: any, _inputBuffer: any, deltaTime: number) {
41+
const time = this.uniforms.get('time')
42+
if (time) {
43+
time.value += deltaTime
44+
}
45+
}
46+
}
47+
48+
//
49+
// Component
50+
//
51+
52+
const ExampleWrapped = wrapEffect(ExampleEffect)
53+
54+
type ExampleProps = React.ComponentPropsWithoutRef<typeof ExampleWrapped> & {
55+
/** mouse */
56+
mouse?: boolean
57+
}
58+
59+
export const Example = ({ mouse = false, ...props }: ExampleProps) => {
60+
const pointer = useThree(({ pointer }) => pointer)
61+
62+
const ref = useRef<ExampleEffect>(null)
63+
64+
useFrame(() => {
65+
if (!mouse) return
66+
if (!ref?.current) return
67+
68+
const uColor = ref.current.uniforms.get('color')
69+
if (!uColor) return
70+
71+
uColor.value.r = pointer.x / 2.0 + 0.5
72+
uColor.value.g = pointer.y / 2.0 + 0.5
73+
})
74+
75+
return <ExampleWrapped ref={ref} {...props} />
76+
}

src/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export * from './effects/ColorDepth'
1212
export * from './effects/Depth'
1313
export * from './effects/DepthOfField'
1414
export * from './effects/DotScreen'
15+
export * from './effects/Example'
1516
export * from './effects/Glitch'
1617
export * from './effects/GodRays'
1718
export * from './effects/Grid'

0 commit comments

Comments
 (0)