Skip to content

Commit d95f0d5

Browse files
Merge branch 'master' into fix/unpin-ssr
2 parents 74475ef + 693f5e0 commit d95f0d5

File tree

11 files changed

+505
-437
lines changed

11 files changed

+505
-437
lines changed

package.json

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,31 +34,27 @@
3434
]
3535
},
3636
"scripts": {
37-
"prebuild": "rimraf dist && yarn typegen",
38-
"build": "rollup -c",
37+
"prebuild": "rimraf dist",
38+
"build": "vite build && tsc --emitDeclarationOnly",
3939
"prepare": "yarn build",
4040
"eslint": "eslint . --fix --ext=js,ts,jsx,tsx",
4141
"eslint:ci": "eslint . --ext=js,ts,jsx,tsx",
4242
"test": "echo no tests yet",
43-
"typecheck": "tsc --noEmit --emitDeclarationOnly false --strict --jsx react",
44-
"typegen": "tsc --emitDeclarationOnly || true",
43+
"typecheck": "tsc --noEmit false --strict --jsx react",
4544
"release": "semantic-release",
4645
"storybook": "storybook dev -p 6006",
4746
"build-storybook": "storybook build"
4847
},
4948
"dependencies": {
5049
"maath": "^0.5.3",
51-
"n8ao": "^1.2.1",
52-
"postprocessing": "^6.30.2",
50+
"n8ao": "^1.4.2",
51+
"postprocessing": "^6.31.0",
5352
"screen-space-reflections": "^2.5.0",
54-
"three-stdlib": "^2.21.10"
53+
"three-stdlib": "^2.23.4"
5554
},
5655
"devDependencies": {
5756
"@react-three/drei": "^9.68.2",
5857
"@react-three/fiber": "^8.13.0",
59-
"@rollup/plugin-commonjs": "^24.1.0",
60-
"@rollup/plugin-node-resolve": "^15.0.2",
61-
"@rollup/plugin-typescript": "^11.1.0",
6258
"@storybook/addon-essentials": "^7.0.10",
6359
"@storybook/addon-interactions": "^7.0.10",
6460
"@storybook/addon-links": "^7.0.10",
@@ -85,8 +81,6 @@
8581
"react": "^18.2.0",
8682
"react-dom": "^18.2.0",
8783
"rimraf": "^5.0.0",
88-
"rollup": "^3.21.0",
89-
"rollup-plugin-filesize": "^10.0.0",
9084
"semantic-release": "^21.0.2",
9185
"storybook": "^7.0.10",
9286
"three": "^0.151.3",

rollup.config.js

Lines changed: 0 additions & 23 deletions
This file was deleted.

src/EffectComposer.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,11 @@ export const EffectComposer = React.memo(
113113
useFrame(
114114
(_, delta) => {
115115
if (enabled) {
116+
const currentAutoClear = gl.autoClear
116117
gl.autoClear = autoClear
118+
if (stencilBuffer && !autoClear) gl.clearStencil()
117119
composer.render(delta)
120+
gl.autoClear = currentAutoClear
118121
}
119122
},
120123
enabled ? renderPriority : 0

src/effects/ASCII.tsx

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
// From: https://github.com/emilwidlund/ASCII
2+
// https://twitter.com/emilwidlund/status/1652386482420609024
3+
4+
import { forwardRef, useMemo } from 'react'
5+
import { CanvasTexture, Color, NearestFilter, RepeatWrapping, Texture, Uniform } from 'three'
6+
import { Effect } from 'postprocessing'
7+
8+
const fragment = `
9+
uniform sampler2D uCharacters;
10+
uniform float uCharactersCount;
11+
uniform float uCellSize;
12+
uniform bool uInvert;
13+
uniform vec3 uColor;
14+
15+
const vec2 SIZE = vec2(16.);
16+
17+
vec3 greyscale(vec3 color, float strength) {
18+
float g = dot(color, vec3(0.299, 0.587, 0.114));
19+
return mix(color, vec3(g), strength);
20+
}
21+
22+
vec3 greyscale(vec3 color) {
23+
return greyscale(color, 1.0);
24+
}
25+
26+
void mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor) {
27+
vec2 cell = resolution / uCellSize;
28+
vec2 grid = 1.0 / cell;
29+
vec2 pixelizedUV = grid * (0.5 + floor(uv / grid));
30+
vec4 pixelized = texture2D(inputBuffer, pixelizedUV);
31+
float greyscaled = greyscale(pixelized.rgb).r;
32+
33+
if (uInvert) {
34+
greyscaled = 1.0 - greyscaled;
35+
}
36+
37+
float characterIndex = floor((uCharactersCount - 1.0) * greyscaled);
38+
vec2 characterPosition = vec2(mod(characterIndex, SIZE.x), floor(characterIndex / SIZE.y));
39+
vec2 offset = vec2(characterPosition.x, -characterPosition.y) / SIZE;
40+
vec2 charUV = mod(uv * (cell / SIZE), 1.0 / SIZE) - vec2(0., 1.0 / SIZE) + offset;
41+
vec4 asciiCharacter = texture2D(uCharacters, charUV);
42+
43+
asciiCharacter.rgb = uColor * asciiCharacter.r;
44+
asciiCharacter.a = pixelized.a;
45+
outputColor = asciiCharacter;
46+
}
47+
`
48+
49+
interface IASCIIEffectProps {
50+
characters?: string
51+
fontSize?: number
52+
cellSize?: number
53+
color?: string
54+
invert?: boolean
55+
}
56+
57+
class ASCIIEffect extends Effect {
58+
constructor({
59+
characters = ` .:,'-^=*+?!|0#X%WM@`,
60+
fontSize = 54,
61+
cellSize = 16,
62+
color = '#ffffff',
63+
invert = false,
64+
}: IASCIIEffectProps = {}) {
65+
const uniforms = new Map<string, Uniform>([
66+
['uCharacters', new Uniform(new Texture())],
67+
['uCellSize', new Uniform(cellSize)],
68+
['uCharactersCount', new Uniform(characters.length)],
69+
['uColor', new Uniform(new Color(color))],
70+
['uInvert', new Uniform(invert)],
71+
])
72+
73+
super('ASCIIEffect', fragment, { uniforms })
74+
75+
const charactersTextureUniform = this.uniforms.get('uCharacters')
76+
77+
if (charactersTextureUniform) {
78+
charactersTextureUniform.value = this.createCharactersTexture(characters, fontSize)
79+
}
80+
}
81+
82+
/** Draws the characters on a Canvas and returns a texture */
83+
public createCharactersTexture(characters: string, fontSize: number): THREE.Texture {
84+
const canvas = document.createElement('canvas')
85+
const SIZE = 1024
86+
const MAX_PER_ROW = 16
87+
const CELL = SIZE / MAX_PER_ROW
88+
89+
canvas.width = canvas.height = SIZE
90+
const texture = new CanvasTexture(canvas, undefined, RepeatWrapping, RepeatWrapping, NearestFilter, NearestFilter)
91+
const context = canvas.getContext('2d')
92+
93+
if (!context) {
94+
throw new Error('Context not available')
95+
}
96+
97+
context.clearRect(0, 0, SIZE, SIZE)
98+
context.font = `${fontSize}px arial`
99+
context.textAlign = 'center'
100+
context.textBaseline = 'middle'
101+
context.fillStyle = '#fff'
102+
103+
for (let i = 0; i < characters.length; i++) {
104+
const char = characters[i]
105+
const x = i % MAX_PER_ROW
106+
const y = Math.floor(i / MAX_PER_ROW)
107+
context.fillText(char, x * CELL + CELL / 2, y * CELL + CELL / 2)
108+
}
109+
110+
texture.needsUpdate = true
111+
return texture
112+
}
113+
}
114+
115+
export const ASCII = forwardRef<ASCIIEffect, IASCIIEffectProps>(
116+
({ characters = ` .:,'-^=*+?!|0#X%WM@`, fontSize = 54, cellSize = 16, color = '#ffffff', invert = false }, fref) => {
117+
const effect = useMemo(
118+
() => new ASCIIEffect({ characters, fontSize, cellSize, color, invert }),
119+
[characters, fontSize, cellSize, color, invert]
120+
)
121+
return <primitive ref={fref} object={effect} />
122+
}
123+
)

src/effects/FXAA.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { FXAAEffect } from 'postprocessing'
2+
import { wrapEffect } from '../util'
3+
4+
export const FXAA = wrapEffect(FXAAEffect)

src/effects/Glitch.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { Vector2 } from 'three'
12
import { GlitchEffect, GlitchMode } from 'postprocessing'
23
import { Ref, forwardRef, useMemo, useLayoutEffect } from 'react'
34
import { ReactThreeFiber, useThree } from '@react-three/fiber'
@@ -21,9 +22,10 @@ export const Glitch = forwardRef<GlitchEffect, GlitchProps>(function Glitch(
2122
const delay = useVector2(props, 'delay')
2223
const duration = useVector2(props, 'duration')
2324
const strength = useVector2(props, 'strength')
25+
const chromaticAberrationOffset = useVector2(props, 'chromaticAberrationOffset')
2426
const effect = useMemo(
25-
() => new GlitchEffect({ ...props, delay, duration, strength }),
26-
[delay, duration, props, strength]
27+
() => new GlitchEffect({ ...props, delay, duration, strength, chromaticAberrationOffset }),
28+
[delay, duration, props, strength, chromaticAberrationOffset]
2729
)
2830
useLayoutEffect(() => {
2931
effect.mode = active ? props.mode || GlitchMode.SPORADIC : GlitchMode.DISABLED

src/effects/N8AO.tsx

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,52 @@
44
import { Ref, forwardRef, useLayoutEffect, useMemo } from 'react'
55
/* @ts-ignore */
66
import { N8AOPostPass } from 'n8ao'
7-
import { useThree } from '@react-three/fiber'
7+
import { useThree, ReactThreeFiber, applyProps } from '@react-three/fiber'
88

99
type N8AOProps = {
1010
aoRadius?: number
1111
distanceFalloff?: number
1212
intensity?: number
13+
quality?: 'performance' | 'low' | 'medium' | 'high' | 'ultra'
14+
aoSamples?: number
15+
denoiseSamples?: number
16+
denoiseRadius?: number
17+
color?: ReactThreeFiber.Color
18+
screenSpaceRadius?: boolean
1319
}
1420

15-
export const N8AO = forwardRef<N8AOPostPass, N8AOProps>((props, ref: Ref<N8AOPostPass>) => {
16-
const { camera, scene } = useThree()
17-
const effect = useMemo(() => new N8AOPostPass(scene, camera), [])
18-
useLayoutEffect(() => {
19-
Object.assign(effect.configuration, props)
20-
}, [props])
21-
return <primitive ref={ref} object={effect} />
22-
})
21+
export const N8AO = forwardRef<N8AOPostPass, N8AOProps>(
22+
(
23+
{
24+
screenSpaceRadius,
25+
quality,
26+
aoRadius = 5,
27+
aoSamples = 16,
28+
denoiseSamples = 4,
29+
denoiseRadius = 12,
30+
distanceFalloff = 1,
31+
intensity = 1,
32+
color,
33+
},
34+
ref: Ref<N8AOPostPass>
35+
) => {
36+
const { camera, scene } = useThree()
37+
const effect = useMemo(() => new N8AOPostPass(scene, camera), [])
38+
useLayoutEffect(() => {
39+
applyProps(effect.configuration, {
40+
color,
41+
aoRadius,
42+
distanceFalloff,
43+
intensity,
44+
aoSamples,
45+
denoiseSamples,
46+
denoiseRadius,
47+
screenSpaceRadius,
48+
})
49+
}, [screenSpaceRadius, color, aoRadius, distanceFalloff, intensity, aoSamples, denoiseSamples, denoiseRadius])
50+
useLayoutEffect(() => {
51+
if (quality) effect.setQualityMode(quality.charAt(0).toUpperCase() + quality.slice(1))
52+
}, [quality])
53+
return <primitive ref={ref} object={effect} />
54+
}
55+
)

src/effects/Outline.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ export const Outline = forwardRef(function Outline(
6161
hiddenEdgeColor,
6262
kernelSize,
6363
patternTexture,
64-
props,
6564
pulseSpeed,
6665
scene,
6766
visibleEdgeColor,

src/index.tsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
1+
export * from './Selection'
2+
export * from './EffectComposer'
3+
export * from './util'
4+
15
export * from './effects/Autofocus'
26
export * from './effects/Bloom'
37
export * from './effects/BrightnessContrast'
48
export * from './effects/ChromaticAberration'
59
export * from './effects/ColorAverage'
610
export * from './effects/ColorDepth'
711
export * from './effects/Depth'
8-
export { DepthOfField } from './effects/DepthOfField'
12+
export * from './effects/DepthOfField'
913
export * from './effects/DotScreen'
1014
export * from './effects/Glitch'
1115
export * from './effects/GodRays'
@@ -18,19 +22,17 @@ export * from './effects/ScanlineEffect'
1822
export * from './effects/SelectiveBloom'
1923
export * from './effects/Sepia'
2024
export * from './effects/SSAO'
21-
export * from './effects/N8AO'
2225
export * from './effects/SMAA'
26+
export * from './effects/FXAA'
2327
export * from './effects/Texture'
2428
export * from './effects/ToneMapping'
2529
export * from './effects/Vignette'
2630
export * from './effects/ShockWave'
2731
export * from './effects/LUT'
2832
export * from './effects/TiltShift'
2933
export * from './effects/TiltShift2'
34+
export * from './effects/ASCII'
3035

31-
// This is not an effect pass
36+
// These are not effect passes
3237
export * from './effects/SSR'
33-
34-
export * from './Selection'
35-
export * from './EffectComposer'
36-
export * from './util'
38+
export * from './effects/N8AO'

vite.config.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import * as path from 'node:path'
2+
import { defineConfig } from 'vite'
3+
4+
const inline: string[] = ['n8ao']
5+
6+
export default defineConfig({
7+
build: {
8+
minify: false,
9+
target: 'es2018',
10+
sourcemap: true,
11+
lib: {
12+
formats: ['es', 'cjs'],
13+
entry: 'src/index.tsx',
14+
fileName: '[name]',
15+
},
16+
rollupOptions: {
17+
external: (id: string) => !id.startsWith('.') && !path.isAbsolute(id) && !inline.includes(id),
18+
},
19+
},
20+
plugins: [
21+
{
22+
name: 'n8ao-fix',
23+
generateBundle(_, bundle) {
24+
for (const id in bundle) {
25+
const asset = bundle[id]
26+
if ('code' in asset) {
27+
asset.code = asset.code.replace(/three\/(addons|examples)[^'"`]+/g, 'three-stdlib')
28+
}
29+
}
30+
},
31+
},
32+
],
33+
})

0 commit comments

Comments
 (0)