@react-three/postprocessing 2.18.0 → 3.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (271) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +81 -81
  3. package/dist/index.d.ts +1 -38
  4. package/dist/index.js +554 -88
  5. package/dist/index.js.map +1 -1
  6. package/package.json +69 -96
  7. package/src/EffectComposer.test.tsx +126 -0
  8. package/src/EffectComposer.tsx +202 -0
  9. package/src/Selection.tsx +46 -0
  10. package/src/effects/ASCII.tsx +135 -0
  11. package/src/effects/Autofocus.tsx +153 -0
  12. package/src/effects/Bloom.tsx +6 -0
  13. package/src/effects/BrightnessContrast.tsx +4 -0
  14. package/src/effects/ChromaticAberration.tsx +5 -0
  15. package/src/effects/ColorAverage.tsx +15 -0
  16. package/src/effects/ColorDepth.tsx +4 -0
  17. package/src/effects/Depth.tsx +4 -0
  18. package/src/effects/DepthOfField.tsx +89 -0
  19. package/src/effects/DotScreen.tsx +4 -0
  20. package/src/effects/FXAA.tsx +4 -0
  21. package/src/effects/Glitch.tsx +40 -0
  22. package/src/effects/GodRays.tsx +16 -0
  23. package/src/effects/Grid.tsx +21 -0
  24. package/src/effects/HueSaturation.tsx +4 -0
  25. package/src/effects/LUT.tsx +26 -0
  26. package/src/effects/LensFlare.tsx +611 -0
  27. package/src/effects/N8AO.tsx +81 -0
  28. package/src/effects/Noise.tsx +4 -0
  29. package/src/effects/Outline.tsx +117 -0
  30. package/src/effects/Pixelation.tsx +15 -0
  31. package/{dist/effects/Ramp.js → src/effects/Ramp.tsx} +150 -156
  32. package/src/effects/SMAA.tsx +4 -0
  33. package/src/effects/SSAO.tsx +41 -0
  34. package/src/effects/ScanlineEffect.tsx +7 -0
  35. package/src/effects/SelectiveBloom.tsx +126 -0
  36. package/src/effects/Sepia.tsx +4 -0
  37. package/src/effects/ShockWave.tsx +4 -0
  38. package/src/effects/Texture.tsx +23 -0
  39. package/src/effects/TiltShift.tsx +4 -0
  40. package/{dist/effects/TiltShift2.js → src/effects/TiltShift2.tsx} +90 -98
  41. package/src/effects/ToneMapping.tsx +6 -0
  42. package/src/effects/Vignette.tsx +4 -0
  43. package/{dist/effects/Water.js → src/effects/Water.tsx} +35 -38
  44. package/src/index.ts +40 -0
  45. package/src/util.tsx +55 -0
  46. package/dist/EffectComposer.cjs +0 -137
  47. package/dist/EffectComposer.cjs.map +0 -1
  48. package/dist/EffectComposer.d.ts +0 -27
  49. package/dist/EffectComposer.js +0 -137
  50. package/dist/EffectComposer.js.map +0 -1
  51. package/dist/EffectComposer.test.d.ts +0 -4
  52. package/dist/Selection.cjs +0 -36
  53. package/dist/Selection.cjs.map +0 -1
  54. package/dist/Selection.d.ts +0 -16
  55. package/dist/Selection.js +0 -36
  56. package/dist/Selection.js.map +0 -1
  57. package/dist/compat.cjs +0 -77
  58. package/dist/compat.cjs.map +0 -1
  59. package/dist/compat.js +0 -60
  60. package/dist/compat.js.map +0 -1
  61. package/dist/effects/ASCII.cjs +0 -113
  62. package/dist/effects/ASCII.cjs.map +0 -1
  63. package/dist/effects/ASCII.d.ts +0 -17
  64. package/dist/effects/ASCII.js +0 -113
  65. package/dist/effects/ASCII.js.map +0 -1
  66. package/dist/effects/Autofocus.cjs +0 -126
  67. package/dist/effects/Autofocus.cjs.map +0 -1
  68. package/dist/effects/Autofocus.d.ts +0 -22
  69. package/dist/effects/Autofocus.js +0 -109
  70. package/dist/effects/Autofocus.js.map +0 -1
  71. package/dist/effects/Bloom.cjs +0 -9
  72. package/dist/effects/Bloom.cjs.map +0 -1
  73. package/dist/effects/Bloom.d.ts +0 -6
  74. package/dist/effects/Bloom.js +0 -9
  75. package/dist/effects/Bloom.js.map +0 -1
  76. package/dist/effects/BrightnessContrast.cjs +0 -7
  77. package/dist/effects/BrightnessContrast.cjs.map +0 -1
  78. package/dist/effects/BrightnessContrast.d.ts +0 -10
  79. package/dist/effects/BrightnessContrast.js +0 -7
  80. package/dist/effects/BrightnessContrast.js.map +0 -1
  81. package/dist/effects/ChromaticAberration.cjs +0 -7
  82. package/dist/effects/ChromaticAberration.cjs.map +0 -1
  83. package/dist/effects/ChromaticAberration.d.ts +0 -13
  84. package/dist/effects/ChromaticAberration.js +0 -7
  85. package/dist/effects/ChromaticAberration.js.map +0 -1
  86. package/dist/effects/ColorAverage.cjs +0 -11
  87. package/dist/effects/ColorAverage.cjs.map +0 -1
  88. package/dist/effects/ColorAverage.d.ts +0 -8
  89. package/dist/effects/ColorAverage.js +0 -11
  90. package/dist/effects/ColorAverage.js.map +0 -1
  91. package/dist/effects/ColorDepth.cjs +0 -7
  92. package/dist/effects/ColorDepth.cjs.map +0 -1
  93. package/dist/effects/ColorDepth.d.ts +0 -9
  94. package/dist/effects/ColorDepth.js +0 -7
  95. package/dist/effects/ColorDepth.js.map +0 -1
  96. package/dist/effects/Depth.cjs +0 -7
  97. package/dist/effects/Depth.cjs.map +0 -1
  98. package/dist/effects/Depth.d.ts +0 -9
  99. package/dist/effects/Depth.js +0 -7
  100. package/dist/effects/Depth.js.map +0 -1
  101. package/dist/effects/DepthOfField.cjs +0 -74
  102. package/dist/effects/DepthOfField.cjs.map +0 -1
  103. package/dist/effects/DepthOfField.d.ts +0 -25
  104. package/dist/effects/DepthOfField.js +0 -74
  105. package/dist/effects/DepthOfField.js.map +0 -1
  106. package/dist/effects/DotScreen.cjs +0 -7
  107. package/dist/effects/DotScreen.cjs.map +0 -1
  108. package/dist/effects/DotScreen.d.ts +0 -10
  109. package/dist/effects/DotScreen.js +0 -7
  110. package/dist/effects/DotScreen.js.map +0 -1
  111. package/dist/effects/FXAA.cjs +0 -7
  112. package/dist/effects/FXAA.cjs.map +0 -1
  113. package/dist/effects/FXAA.d.ts +0 -8
  114. package/dist/effects/FXAA.js +0 -7
  115. package/dist/effects/FXAA.js.map +0 -1
  116. package/dist/effects/Glitch.cjs +0 -31
  117. package/dist/effects/Glitch.cjs.map +0 -1
  118. package/dist/effects/Glitch.d.ts +0 -30
  119. package/dist/effects/Glitch.js +0 -31
  120. package/dist/effects/Glitch.js.map +0 -1
  121. package/dist/effects/GodRays.cjs +0 -15
  122. package/dist/effects/GodRays.cjs.map +0 -1
  123. package/dist/effects/GodRays.d.ts +0 -21
  124. package/dist/effects/GodRays.js +0 -15
  125. package/dist/effects/GodRays.js.map +0 -1
  126. package/dist/effects/Grid.cjs +0 -18
  127. package/dist/effects/Grid.cjs.map +0 -1
  128. package/dist/effects/Grid.d.ts +0 -12
  129. package/dist/effects/Grid.js +0 -18
  130. package/dist/effects/Grid.js.map +0 -1
  131. package/dist/effects/HueSaturation.cjs +0 -7
  132. package/dist/effects/HueSaturation.cjs.map +0 -1
  133. package/dist/effects/HueSaturation.d.ts +0 -10
  134. package/dist/effects/HueSaturation.js +0 -7
  135. package/dist/effects/HueSaturation.js.map +0 -1
  136. package/dist/effects/LUT.cjs +0 -20
  137. package/dist/effects/LUT.cjs.map +0 -1
  138. package/dist/effects/LUT.d.ts +0 -9
  139. package/dist/effects/LUT.js +0 -20
  140. package/dist/effects/LUT.js.map +0 -1
  141. package/dist/effects/LensFlare.cjs +0 -189
  142. package/dist/effects/LensFlare.cjs.map +0 -1
  143. package/dist/effects/LensFlare.d.ts +0 -52
  144. package/dist/effects/LensFlare.js +0 -172
  145. package/dist/effects/LensFlare.js.map +0 -1
  146. package/dist/effects/N8AO/BlueNoise.cjs +0 -4
  147. package/dist/effects/N8AO/BlueNoise.cjs.map +0 -1
  148. package/dist/effects/N8AO/BlueNoise.js +0 -5
  149. package/dist/effects/N8AO/BlueNoise.js.map +0 -1
  150. package/dist/effects/N8AO/DepthDownSample.cjs +0 -183
  151. package/dist/effects/N8AO/DepthDownSample.cjs.map +0 -1
  152. package/dist/effects/N8AO/DepthDownSample.js +0 -166
  153. package/dist/effects/N8AO/DepthDownSample.js.map +0 -1
  154. package/dist/effects/N8AO/EffectCompositer.cjs +0 -278
  155. package/dist/effects/N8AO/EffectCompositer.cjs.map +0 -1
  156. package/dist/effects/N8AO/EffectCompositer.js +0 -261
  157. package/dist/effects/N8AO/EffectCompositer.js.map +0 -1
  158. package/dist/effects/N8AO/EffectShader.cjs +0 -236
  159. package/dist/effects/N8AO/EffectShader.cjs.map +0 -1
  160. package/dist/effects/N8AO/EffectShader.js +0 -219
  161. package/dist/effects/N8AO/EffectShader.js.map +0 -1
  162. package/dist/effects/N8AO/FullScreenTriangle.cjs +0 -59
  163. package/dist/effects/N8AO/FullScreenTriangle.cjs.map +0 -1
  164. package/dist/effects/N8AO/FullScreenTriangle.js +0 -42
  165. package/dist/effects/N8AO/FullScreenTriangle.js.map +0 -1
  166. package/dist/effects/N8AO/N8AOPostPass.cjs +0 -502
  167. package/dist/effects/N8AO/N8AOPostPass.cjs.map +0 -1
  168. package/dist/effects/N8AO/N8AOPostPass.js +0 -485
  169. package/dist/effects/N8AO/N8AOPostPass.js.map +0 -1
  170. package/dist/effects/N8AO/PoissionBlur.cjs +0 -186
  171. package/dist/effects/N8AO/PoissionBlur.cjs.map +0 -1
  172. package/dist/effects/N8AO/PoissionBlur.js +0 -169
  173. package/dist/effects/N8AO/PoissionBlur.js.map +0 -1
  174. package/dist/effects/N8AO/index.cjs +0 -60
  175. package/dist/effects/N8AO/index.cjs.map +0 -1
  176. package/dist/effects/N8AO/index.d.ts +0 -18
  177. package/dist/effects/N8AO/index.js +0 -60
  178. package/dist/effects/N8AO/index.js.map +0 -1
  179. package/dist/effects/Noise.cjs +0 -7
  180. package/dist/effects/Noise.cjs.map +0 -1
  181. package/dist/effects/Noise.d.ts +0 -9
  182. package/dist/effects/Noise.js +0 -7
  183. package/dist/effects/Noise.js.map +0 -1
  184. package/dist/effects/Outline.cjs +0 -100
  185. package/dist/effects/Outline.cjs.map +0 -1
  186. package/dist/effects/Outline.d.ts +0 -30
  187. package/dist/effects/Outline.js +0 -100
  188. package/dist/effects/Outline.js.map +0 -1
  189. package/dist/effects/Pixelation.cjs +0 -11
  190. package/dist/effects/Pixelation.cjs.map +0 -1
  191. package/dist/effects/Pixelation.d.ts +0 -6
  192. package/dist/effects/Pixelation.js +0 -11
  193. package/dist/effects/Pixelation.js.map +0 -1
  194. package/dist/effects/Ramp.cjs +0 -156
  195. package/dist/effects/Ramp.cjs.map +0 -1
  196. package/dist/effects/Ramp.d.ts +0 -88
  197. package/dist/effects/Ramp.js.map +0 -1
  198. package/dist/effects/SMAA.cjs +0 -7
  199. package/dist/effects/SMAA.cjs.map +0 -1
  200. package/dist/effects/SMAA.d.ts +0 -10
  201. package/dist/effects/SMAA.js +0 -7
  202. package/dist/effects/SMAA.js.map +0 -1
  203. package/dist/effects/SSAO.cjs +0 -37
  204. package/dist/effects/SSAO.cjs.map +0 -1
  205. package/dist/effects/SSAO.d.ts +0 -30
  206. package/dist/effects/SSAO.js +0 -37
  207. package/dist/effects/SSAO.js.map +0 -1
  208. package/dist/effects/SSR/index.cjs +0 -33
  209. package/dist/effects/SSR/index.cjs.map +0 -1
  210. package/dist/effects/SSR/index.d.ts +0 -55
  211. package/dist/effects/SSR/index.js +0 -33
  212. package/dist/effects/SSR/index.js.map +0 -1
  213. package/dist/effects/SSR/screen-space-reflections.cjs +0 -1699
  214. package/dist/effects/SSR/screen-space-reflections.cjs.map +0 -1
  215. package/dist/effects/SSR/screen-space-reflections.js +0 -1699
  216. package/dist/effects/SSR/screen-space-reflections.js.map +0 -1
  217. package/dist/effects/ScanlineEffect.cjs +0 -7
  218. package/dist/effects/ScanlineEffect.cjs.map +0 -1
  219. package/dist/effects/ScanlineEffect.d.ts +0 -9
  220. package/dist/effects/ScanlineEffect.js +0 -7
  221. package/dist/effects/ScanlineEffect.js.map +0 -1
  222. package/dist/effects/SelectiveBloom.cjs +0 -94
  223. package/dist/effects/SelectiveBloom.cjs.map +0 -1
  224. package/dist/effects/SelectiveBloom.d.ts +0 -20
  225. package/dist/effects/SelectiveBloom.js +0 -94
  226. package/dist/effects/SelectiveBloom.js.map +0 -1
  227. package/dist/effects/Sepia.cjs +0 -7
  228. package/dist/effects/Sepia.cjs.map +0 -1
  229. package/dist/effects/Sepia.d.ts +0 -9
  230. package/dist/effects/Sepia.js +0 -7
  231. package/dist/effects/Sepia.js.map +0 -1
  232. package/dist/effects/ShockWave.cjs +0 -7
  233. package/dist/effects/ShockWave.cjs.map +0 -1
  234. package/dist/effects/ShockWave.d.ts +0 -6
  235. package/dist/effects/ShockWave.js +0 -7
  236. package/dist/effects/ShockWave.js.map +0 -1
  237. package/dist/effects/Texture.cjs +0 -21
  238. package/dist/effects/Texture.cjs.map +0 -1
  239. package/dist/effects/Texture.d.ts +0 -11
  240. package/dist/effects/Texture.js +0 -21
  241. package/dist/effects/Texture.js.map +0 -1
  242. package/dist/effects/TiltShift.cjs +0 -7
  243. package/dist/effects/TiltShift.cjs.map +0 -1
  244. package/dist/effects/TiltShift.d.ts +0 -17
  245. package/dist/effects/TiltShift.js +0 -7
  246. package/dist/effects/TiltShift.js.map +0 -1
  247. package/dist/effects/TiltShift2.cjs +0 -98
  248. package/dist/effects/TiltShift2.cjs.map +0 -1
  249. package/dist/effects/TiltShift2.d.ts +0 -30
  250. package/dist/effects/TiltShift2.js.map +0 -1
  251. package/dist/effects/ToneMapping.cjs +0 -7
  252. package/dist/effects/ToneMapping.cjs.map +0 -1
  253. package/dist/effects/ToneMapping.d.ts +0 -19
  254. package/dist/effects/ToneMapping.js +0 -7
  255. package/dist/effects/ToneMapping.js.map +0 -1
  256. package/dist/effects/Vignette.cjs +0 -7
  257. package/dist/effects/Vignette.cjs.map +0 -1
  258. package/dist/effects/Vignette.d.ts +0 -12
  259. package/dist/effects/Vignette.js +0 -7
  260. package/dist/effects/Vignette.js.map +0 -1
  261. package/dist/effects/Water.cjs +0 -38
  262. package/dist/effects/Water.cjs.map +0 -1
  263. package/dist/effects/Water.d.ts +0 -15
  264. package/dist/effects/Water.js.map +0 -1
  265. package/dist/index.cjs +0 -89
  266. package/dist/index.cjs.map +0 -1
  267. package/dist/util.cjs +0 -69
  268. package/dist/util.cjs.map +0 -1
  269. package/dist/util.d.ts +0 -13
  270. package/dist/util.js +0 -52
  271. package/dist/util.js.map +0 -1
@@ -0,0 +1,135 @@
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
+ font?: string
51
+ characters?: string
52
+ fontSize?: number
53
+ cellSize?: number
54
+ color?: string
55
+ invert?: boolean
56
+ }
57
+
58
+ class ASCIIEffect extends Effect {
59
+ constructor({
60
+ font = 'arial',
61
+ characters = ` .:,'-^=*+?!|0#X%WM@`,
62
+ fontSize = 54,
63
+ cellSize = 16,
64
+ color = '#ffffff',
65
+ invert = false,
66
+ }: IASCIIEffectProps = {}) {
67
+ const uniforms = new Map<string, Uniform>([
68
+ ['uCharacters', new Uniform(new Texture())],
69
+ ['uCellSize', new Uniform(cellSize)],
70
+ ['uCharactersCount', new Uniform(characters.length)],
71
+ ['uColor', new Uniform(new Color(color))],
72
+ ['uInvert', new Uniform(invert)],
73
+ ])
74
+
75
+ super('ASCIIEffect', fragment, { uniforms })
76
+
77
+ const charactersTextureUniform = this.uniforms.get('uCharacters')
78
+
79
+ if (charactersTextureUniform) {
80
+ charactersTextureUniform.value = this.createCharactersTexture(characters, font, fontSize)
81
+ }
82
+ }
83
+
84
+ /** Draws the characters on a Canvas and returns a texture */
85
+ public createCharactersTexture(characters: string, font: string, fontSize: number): THREE.Texture {
86
+ const canvas = document.createElement('canvas')
87
+ const SIZE = 1024
88
+ const MAX_PER_ROW = 16
89
+ const CELL = SIZE / MAX_PER_ROW
90
+
91
+ canvas.width = canvas.height = SIZE
92
+ const texture = new CanvasTexture(canvas, undefined, RepeatWrapping, RepeatWrapping, NearestFilter, NearestFilter)
93
+ const context = canvas.getContext('2d')
94
+
95
+ if (!context) {
96
+ throw new Error('Context not available')
97
+ }
98
+
99
+ context.clearRect(0, 0, SIZE, SIZE)
100
+ context.font = `${fontSize}px ${font}`
101
+ context.textAlign = 'center'
102
+ context.textBaseline = 'middle'
103
+ context.fillStyle = '#fff'
104
+
105
+ for (let i = 0; i < characters.length; i++) {
106
+ const char = characters[i]
107
+ const x = i % MAX_PER_ROW
108
+ const y = Math.floor(i / MAX_PER_ROW)
109
+ context.fillText(char, x * CELL + CELL / 2, y * CELL + CELL / 2)
110
+ }
111
+
112
+ texture.needsUpdate = true
113
+ return texture
114
+ }
115
+ }
116
+
117
+ export const ASCII = /* @__PURE__ */ forwardRef<ASCIIEffect, IASCIIEffectProps>(
118
+ (
119
+ {
120
+ font = 'arial',
121
+ characters = ` .:,'-^=*+?!|0#X%WM@`,
122
+ fontSize = 54,
123
+ cellSize = 16,
124
+ color = '#ffffff',
125
+ invert = false,
126
+ },
127
+ fref
128
+ ) => {
129
+ const effect = useMemo(
130
+ () => new ASCIIEffect({ characters, font, fontSize, cellSize, color, invert }),
131
+ [characters, fontSize, cellSize, color, invert, font]
132
+ )
133
+ return <primitive ref={fref} object={effect} />
134
+ }
135
+ )
@@ -0,0 +1,153 @@
1
+ import * as THREE from 'three'
2
+ import React, {
3
+ useRef,
4
+ useContext,
5
+ useState,
6
+ useEffect,
7
+ useCallback,
8
+ forwardRef,
9
+ useImperativeHandle,
10
+ RefObject,
11
+ useMemo,
12
+ } from 'react'
13
+ import { useThree, useFrame, createPortal, type Vector3 } from '@react-three/fiber'
14
+ import { CopyPass, DepthPickingPass, DepthOfFieldEffect } from 'postprocessing'
15
+ import { easing } from 'maath'
16
+
17
+ import { DepthOfField } from './DepthOfField.tsx'
18
+ import { EffectComposerContext } from '../EffectComposer.tsx'
19
+
20
+ export type AutofocusProps = React.ComponentProps<typeof DepthOfField> & {
21
+ target?: Vector3
22
+ /** should the target follow the pointer */
23
+ mouse?: boolean
24
+ /** size of the debug green point */
25
+ debug?: number
26
+ /** manual update */
27
+ manual?: boolean
28
+ /** approximate time to reach the target */
29
+ smoothTime?: number
30
+ }
31
+
32
+ export type AutofocusApi = {
33
+ dofRef: RefObject<DepthOfFieldEffect | null>
34
+ hitpoint: THREE.Vector3
35
+ update: (delta: number, updateTarget: boolean) => void
36
+ }
37
+
38
+ export const Autofocus = /* @__PURE__ */ forwardRef<AutofocusApi, AutofocusProps>(
39
+ (
40
+ { target = undefined, mouse: followMouse = false, debug = undefined, manual = false, smoothTime = 0.25, ...props },
41
+ fref
42
+ ) => {
43
+ const dofRef = useRef<DepthOfFieldEffect>(null)
44
+ const hitpointRef = useRef<THREE.Mesh>(null)
45
+ const targetRef = useRef<THREE.Mesh>(null)
46
+
47
+ const scene = useThree(({ scene }) => scene)
48
+ const pointer = useThree(({ pointer }) => pointer)
49
+ const { composer, camera } = useContext(EffectComposerContext)
50
+
51
+ // see: https://codesandbox.io/s/depthpickingpass-x130hg
52
+ const [depthPickingPass] = useState(() => new DepthPickingPass())
53
+ const [copyPass] = useState(() => new CopyPass())
54
+ useEffect(() => {
55
+ composer.addPass(depthPickingPass)
56
+ composer.addPass(copyPass)
57
+ return () => {
58
+ composer.removePass(depthPickingPass)
59
+ composer.removePass(copyPass)
60
+ }
61
+ }, [composer, depthPickingPass, copyPass])
62
+
63
+ useEffect(() => {
64
+ return () => {
65
+ depthPickingPass.dispose()
66
+ copyPass.dispose()
67
+ }
68
+ }, [depthPickingPass, copyPass])
69
+
70
+ const [hitpoint] = useState(() => new THREE.Vector3(0, 0, 0))
71
+
72
+ const [ndc] = useState(() => new THREE.Vector3(0, 0, 0))
73
+ const getHit = useCallback(
74
+ async (x: number, y: number) => {
75
+ ndc.x = x
76
+ ndc.y = y
77
+ ndc.z = await depthPickingPass.readDepth(ndc)
78
+ ndc.z = ndc.z * 2.0 - 1.0
79
+ const hit = 1 - ndc.z > 0.0000001 // it is missed if ndc.z is close to 1
80
+ return hit ? ndc.unproject(camera) : false
81
+ },
82
+ [ndc, depthPickingPass, camera]
83
+ )
84
+
85
+ const update = useCallback(
86
+ async (delta: number, updateTarget = true) => {
87
+ // Update hitpoint
88
+ if (target) {
89
+ hitpoint.set(...(target as [number, number, number]))
90
+ } else {
91
+ const { x, y } = followMouse ? pointer : { x: 0, y: 0 }
92
+ const hit = await getHit(x, y)
93
+ if (hit) hitpoint.copy(hit)
94
+ }
95
+
96
+ // Update target
97
+ if (updateTarget && dofRef.current?.target) {
98
+ if (smoothTime > 0 && delta > 0) {
99
+ easing.damp3(dofRef.current.target, hitpoint, smoothTime, delta)
100
+ } else {
101
+ dofRef.current.target.copy(hitpoint)
102
+ }
103
+ }
104
+ },
105
+ [target, hitpoint, followMouse, getHit, smoothTime, pointer]
106
+ )
107
+
108
+ useFrame(async (_, delta) => {
109
+ if (!manual) {
110
+ update(delta)
111
+ }
112
+ if (hitpointRef.current) {
113
+ hitpointRef.current.position.copy(hitpoint)
114
+ }
115
+ if (targetRef.current && dofRef.current?.target) {
116
+ targetRef.current.position.copy(dofRef.current.target)
117
+ }
118
+ })
119
+
120
+ // Ref API
121
+ const api = useMemo<AutofocusApi>(
122
+ () => ({
123
+ dofRef,
124
+ hitpoint,
125
+ update,
126
+ }),
127
+ [hitpoint, update]
128
+ )
129
+ useImperativeHandle(fref, () => api, [api])
130
+
131
+ return (
132
+ <>
133
+ {debug
134
+ ? createPortal(
135
+ <>
136
+ <mesh ref={hitpointRef}>
137
+ <sphereGeometry args={[debug, 16, 16]} />
138
+ <meshBasicMaterial color="#00ff00" opacity={1} transparent depthWrite={false} />
139
+ </mesh>
140
+ <mesh ref={targetRef}>
141
+ <sphereGeometry args={[debug / 2, 16, 16]} />
142
+ <meshBasicMaterial color="#00ff00" opacity={0.5} transparent depthWrite={false} />
143
+ </mesh>
144
+ </>,
145
+ scene
146
+ )
147
+ : null}
148
+
149
+ <DepthOfField ref={dofRef} {...props} target={hitpoint} />
150
+ </>
151
+ )
152
+ }
153
+ )
@@ -0,0 +1,6 @@
1
+ import { BloomEffect, BlendFunction } from 'postprocessing'
2
+ import { wrapEffect } from '../util.tsx'
3
+
4
+ export const Bloom = /* @__PURE__ */ wrapEffect(BloomEffect, {
5
+ blendFunction: BlendFunction.ADD,
6
+ })
@@ -0,0 +1,4 @@
1
+ import { BrightnessContrastEffect } from 'postprocessing'
2
+ import { wrapEffect } from '../util.tsx'
3
+
4
+ export const BrightnessContrast = /* @__PURE__ */ wrapEffect(BrightnessContrastEffect)
@@ -0,0 +1,5 @@
1
+ import { ChromaticAberrationEffect } from 'postprocessing'
2
+ import { type EffectProps, wrapEffect } from '../util.tsx'
3
+
4
+ export type ChromaticAberrationProps = EffectProps<typeof ChromaticAberrationEffect>
5
+ export const ChromaticAberration = /* @__PURE__ */ wrapEffect(ChromaticAberrationEffect)
@@ -0,0 +1,15 @@
1
+ import { ColorAverageEffect, BlendFunction } from 'postprocessing'
2
+ import React, { Ref, forwardRef, useMemo } from 'react'
3
+
4
+ export type ColorAverageProps = Partial<{
5
+ blendFunction: BlendFunction
6
+ }>
7
+
8
+ export const ColorAverage = /* @__PURE__ */ forwardRef<ColorAverageEffect, ColorAverageProps>(function ColorAverage(
9
+ { blendFunction = BlendFunction.NORMAL }: ColorAverageProps,
10
+ ref: Ref<ColorAverageEffect>
11
+ ) {
12
+ /** Because ColorAverage blendFunction is not an object but a number, we have to define a custom prop "blendFunction" */
13
+ const effect = useMemo(() => new ColorAverageEffect(blendFunction), [blendFunction])
14
+ return <primitive ref={ref} object={effect} dispose={null} />
15
+ })
@@ -0,0 +1,4 @@
1
+ import { ColorDepthEffect } from 'postprocessing'
2
+ import { wrapEffect } from '../util.tsx'
3
+
4
+ export const ColorDepth = /* @__PURE__ */ wrapEffect(ColorDepthEffect)
@@ -0,0 +1,4 @@
1
+ import { DepthEffect } from 'postprocessing'
2
+ import { wrapEffect } from '../util.tsx'
3
+
4
+ export const Depth = /* @__PURE__ */ wrapEffect(DepthEffect)
@@ -0,0 +1,89 @@
1
+ import { DepthOfFieldEffect, MaskFunction } from 'postprocessing'
2
+ import { Ref, forwardRef, useMemo, useEffect, useContext } from 'react'
3
+ import { ReactThreeFiber } from '@react-three/fiber'
4
+ import { type DepthPackingStrategies, type Texture, Vector3 } from 'three'
5
+ import { EffectComposerContext } from '../EffectComposer.tsx'
6
+
7
+ type DOFProps = ConstructorParameters<typeof DepthOfFieldEffect>[1] &
8
+ Partial<{
9
+ target: ReactThreeFiber.Vector3
10
+ depthTexture: {
11
+ texture: Texture
12
+ // TODO: narrow to DepthPackingStrategies
13
+ packing: number
14
+ }
15
+ // TODO: not used
16
+ blur: number
17
+ }>
18
+
19
+ export const DepthOfField = /* @__PURE__ */ forwardRef(function DepthOfField(
20
+ {
21
+ blendFunction,
22
+ worldFocusDistance,
23
+ worldFocusRange,
24
+ focusDistance,
25
+ focusRange,
26
+ focalLength,
27
+ bokehScale,
28
+ resolutionScale,
29
+ resolutionX,
30
+ resolutionY,
31
+ width,
32
+ height,
33
+ target,
34
+ depthTexture,
35
+ ...props
36
+ }: DOFProps,
37
+ ref: Ref<DepthOfFieldEffect>
38
+ ) {
39
+ const { camera } = useContext(EffectComposerContext)
40
+ const autoFocus = target != null
41
+ const effect = useMemo(() => {
42
+ const effect = new DepthOfFieldEffect(camera, {
43
+ blendFunction,
44
+ worldFocusDistance,
45
+ worldFocusRange,
46
+ focusDistance,
47
+ focusRange,
48
+ focalLength,
49
+ bokehScale,
50
+ resolutionScale,
51
+ resolutionX,
52
+ resolutionY,
53
+ width,
54
+ height,
55
+ })
56
+ // Creating a target enables autofocus, R3F will set via props
57
+ if (autoFocus) effect.target = new Vector3()
58
+ // Depth texture for depth picking with optional packing strategy
59
+ if (depthTexture) effect.setDepthTexture(depthTexture.texture, depthTexture.packing as DepthPackingStrategies)
60
+ // Temporary fix that restores DOF 6.21.3 behavior, everything since then lets shapes leak through the blur
61
+ const maskPass = (effect as any).maskPass
62
+ maskPass.maskFunction = MaskFunction.MULTIPLY_RGB_SET_ALPHA
63
+ return effect
64
+ }, [
65
+ camera,
66
+ blendFunction,
67
+ worldFocusDistance,
68
+ worldFocusRange,
69
+ focusDistance,
70
+ focusRange,
71
+ focalLength,
72
+ bokehScale,
73
+ resolutionScale,
74
+ resolutionX,
75
+ resolutionY,
76
+ width,
77
+ height,
78
+ autoFocus,
79
+ depthTexture,
80
+ ])
81
+
82
+ useEffect(() => {
83
+ return () => {
84
+ effect.dispose()
85
+ }
86
+ }, [effect])
87
+
88
+ return <primitive {...props} ref={ref} object={effect} target={target} />
89
+ })
@@ -0,0 +1,4 @@
1
+ import { DotScreenEffect } from 'postprocessing'
2
+ import { wrapEffect } from '../util.tsx'
3
+
4
+ export const DotScreen = /* @__PURE__ */ wrapEffect(DotScreenEffect)
@@ -0,0 +1,4 @@
1
+ import { FXAAEffect } from 'postprocessing'
2
+ import { wrapEffect } from '../util.tsx'
3
+
4
+ export const FXAA = /* @__PURE__ */ wrapEffect(FXAAEffect)
@@ -0,0 +1,40 @@
1
+ import { Vector2 } from 'three'
2
+ import { GlitchEffect, GlitchMode } from 'postprocessing'
3
+ import { Ref, forwardRef, useMemo, useLayoutEffect, useEffect } from 'react'
4
+ import { ReactThreeFiber, useThree } from '@react-three/fiber'
5
+ import { useVector2 } from '../util.tsx'
6
+
7
+ export type GlitchProps = ConstructorParameters<typeof GlitchEffect>[0] &
8
+ Partial<{
9
+ mode: GlitchMode
10
+ active: boolean
11
+ delay: ReactThreeFiber.Vector2
12
+ duration: ReactThreeFiber.Vector2
13
+ chromaticAberrationOffset: ReactThreeFiber.Vector2
14
+ strength: ReactThreeFiber.Vector2
15
+ }>
16
+
17
+ export const Glitch = /* @__PURE__ */ forwardRef<GlitchEffect, GlitchProps>(function Glitch(
18
+ { active = true, ...props }: GlitchProps,
19
+ ref: Ref<GlitchEffect>
20
+ ) {
21
+ const invalidate = useThree((state) => state.invalidate)
22
+ const delay = useVector2(props, 'delay')
23
+ const duration = useVector2(props, 'duration')
24
+ const strength = useVector2(props, 'strength')
25
+ const chromaticAberrationOffset = useVector2(props, 'chromaticAberrationOffset')
26
+ const effect = useMemo(
27
+ () => new GlitchEffect({ ...props, delay, duration, strength, chromaticAberrationOffset }),
28
+ [delay, duration, props, strength, chromaticAberrationOffset]
29
+ )
30
+ useLayoutEffect(() => {
31
+ effect.mode = active ? props.mode || GlitchMode.SPORADIC : GlitchMode.DISABLED
32
+ invalidate()
33
+ }, [active, effect, invalidate, props.mode])
34
+ useEffect(() => {
35
+ return () => {
36
+ effect.dispose?.()
37
+ }
38
+ }, [effect])
39
+ return <primitive ref={ref} object={effect} dispose={null} />
40
+ })
@@ -0,0 +1,16 @@
1
+ import { GodRaysEffect } from 'postprocessing'
2
+ import React, { Ref, forwardRef, useMemo, useContext, useLayoutEffect } from 'react'
3
+ import { Mesh, Points } from 'three'
4
+ import { EffectComposerContext } from '../EffectComposer'
5
+ import { resolveRef } from '../util.tsx'
6
+
7
+ type GodRaysProps = ConstructorParameters<typeof GodRaysEffect>[2] & {
8
+ sun: Mesh | Points | React.RefObject<Mesh | Points>
9
+ }
10
+
11
+ export const GodRays = /* @__PURE__ */ forwardRef(function GodRays(props: GodRaysProps, ref: Ref<GodRaysEffect>) {
12
+ const { camera } = useContext(EffectComposerContext)
13
+ const effect = useMemo(() => new GodRaysEffect(camera, resolveRef(props.sun), props), [camera, props])
14
+ useLayoutEffect(() => void (effect.lightSource = resolveRef(props.sun)), [effect, props.sun])
15
+ return <primitive ref={ref} object={effect} dispose={null} />
16
+ })
@@ -0,0 +1,21 @@
1
+ import React, { Ref, forwardRef, useMemo, useLayoutEffect } from 'react'
2
+ import { GridEffect } from 'postprocessing'
3
+ import { useThree } from '@react-three/fiber'
4
+
5
+ type GridProps = ConstructorParameters<typeof GridEffect>[0] &
6
+ Partial<{
7
+ size: {
8
+ width: number
9
+ height: number
10
+ }
11
+ }>
12
+
13
+ export const Grid = /* @__PURE__ */ forwardRef(function Grid({ size, ...props }: GridProps, ref: Ref<GridEffect>) {
14
+ const invalidate = useThree((state) => state.invalidate)
15
+ const effect = useMemo(() => new GridEffect(props), [props])
16
+ useLayoutEffect(() => {
17
+ if (size) effect.setSize(size.width, size.height)
18
+ invalidate()
19
+ }, [effect, size, invalidate])
20
+ return <primitive ref={ref} object={effect} dispose={null} />
21
+ })
@@ -0,0 +1,4 @@
1
+ import { HueSaturationEffect } from 'postprocessing'
2
+ import { wrapEffect } from '../util.tsx'
3
+
4
+ export const HueSaturation = /* @__PURE__ */ wrapEffect(HueSaturationEffect)
@@ -0,0 +1,26 @@
1
+ import { useThree } from '@react-three/fiber'
2
+ import { LUT3DEffect, BlendFunction } from 'postprocessing'
3
+ import React, { forwardRef, Ref, useLayoutEffect, useMemo } from 'react'
4
+ import type { Texture } from 'three'
5
+
6
+ export type LUTProps = {
7
+ lut: Texture
8
+ blendFunction?: BlendFunction
9
+ tetrahedralInterpolation?: boolean
10
+ }
11
+
12
+ export const LUT = /* @__PURE__ */ forwardRef(function LUT(
13
+ { lut, tetrahedralInterpolation, ...props }: LUTProps,
14
+ ref: Ref<LUT3DEffect>
15
+ ) {
16
+ const effect = useMemo(() => new LUT3DEffect(lut, props), [lut, props])
17
+ const invalidate = useThree((state) => state.invalidate)
18
+
19
+ useLayoutEffect(() => {
20
+ if (tetrahedralInterpolation) effect.tetrahedralInterpolation = tetrahedralInterpolation
21
+ if (lut) effect.lut = lut
22
+ invalidate()
23
+ }, [effect, invalidate, lut, tetrahedralInterpolation])
24
+
25
+ return <primitive ref={ref} object={effect} dispose={null} />
26
+ })