Skip to content

Commit bacf519

Browse files
authored
Merge pull request #25 from roku-ft/main
add useSimpleBlur hook
2 parents 3446d48 + 68f3064 commit bacf519

File tree

7 files changed

+247
-0
lines changed

7 files changed

+247
-0
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import * as React from "react";
2+
import * as THREE from "three";
3+
import { useFrame, extend, useThree, useLoader} from "@react-three/fiber";
4+
import { FxTextureMaterial } from "../../utils/fxTextureMaterial";
5+
import { FxMaterial, FxMaterialProps } from "../../utils/fxMaterial";
6+
import GUI from "lil-gui";
7+
import { useGUI } from "../../utils/useGUI";
8+
import { CONSTANT } from "../constant";
9+
import { useSimpleBlur,useTransitionBg} from "../../packages/use-shader-fx/src";
10+
import {
11+
SimpleBlurParams,
12+
SIMPLEBLUR_PARAMS,
13+
} from "../../packages/use-shader-fx/src/hooks/useSimpleBlur";
14+
15+
16+
extend({ FxMaterial, FxTextureMaterial });
17+
18+
const CONFIG: SimpleBlurParams = structuredClone(SIMPLEBLUR_PARAMS);
19+
const setGUI = (gui: GUI) => {
20+
gui.add(CONFIG, "blurSize", 0, 10, 0.01);
21+
gui.add(CONFIG, "blurPower", 0, 10, 1);
22+
};
23+
const setConfig = () => {
24+
return {
25+
texture: CONFIG.texture,
26+
blurSize: CONFIG.blurSize,
27+
blurPower: CONFIG.blurPower,
28+
} as SimpleBlurParams;
29+
};
30+
31+
export const UseSimpleBlur = (args: SimpleBlurParams) => {
32+
const updateGUI = useGUI(setGUI);
33+
const [bg] = useLoader(THREE.TextureLoader, ["thumbnail.jpg"]);
34+
const fxRef = React.useRef<FxMaterialProps>();
35+
const size = useThree((state) => state.size);
36+
const dpr = useThree((state) => state.viewport.dpr);
37+
const [updateTransitionBg] = useTransitionBg({ size, dpr });
38+
const [updateSimpleBlur] = useSimpleBlur({ size, dpr });
39+
40+
useFrame((props) => {
41+
const bgTexture = updateTransitionBg(props, {
42+
imageResolution: CONSTANT.imageResolution,
43+
texture0: bg,
44+
});
45+
const fx = updateSimpleBlur(props, {
46+
...setConfig(),
47+
texture: bgTexture
48+
});
49+
fxRef.current!.u_fx = fx;
50+
updateGUI();
51+
});
52+
53+
return (
54+
<mesh>
55+
<planeGeometry args={[2, 2]} />
56+
<fxMaterial key={FxMaterial.key} ref={fxRef} />
57+
</mesh>
58+
);
59+
};
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import * as React from "react";
2+
import type { StoryObj } from "@storybook/react";
3+
import { setArgTypes } from "../utils/setArgTypes";
4+
import { Setup } from "../utils/Setup";
5+
import type { Meta } from "@storybook/react";
6+
import { UseSimpleBlur } from "./UseSimpleBlur";
7+
import {
8+
SIMPLEBLUR_PARAMS,
9+
SimpleBlurParams,
10+
} from "../../packages/use-shader-fx/src/hooks/useSimpleBlur";
11+
12+
const meta = {
13+
title: "useSimpleBlur",
14+
component: UseSimpleBlur,
15+
tags: ["autodocs"],
16+
decorators: [(storyFn: any) => <Setup>{storyFn()}</Setup>],
17+
} satisfies Meta<typeof UseSimpleBlur>;
18+
export default meta;
19+
type Story = StoryObj<typeof meta>;
20+
21+
export const Default: Story = {
22+
args: SIMPLEBLUR_PARAMS,
23+
argTypes: setArgTypes<SimpleBlurParams>(SIMPLEBLUR_PARAMS),
24+
};
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import { useCallback, useMemo } from "react";
2+
import * as THREE from "three";
3+
import { RootState, Size } from "@react-three/fiber";
4+
import { useMesh } from "./useMesh";
5+
import {
6+
useCamera,
7+
useSingleFBO,
8+
useDoubleFBO,
9+
setUniform,
10+
useParams,
11+
} from "@hmng8/use-shader-fx";
12+
import type { HooksReturn } from "@hmng8/use-shader-fx/types/hooks";
13+
14+
export type SimpleBlurParams = {
15+
/** Make this texture blur , Default:new THREE.Texture() */
16+
texture: THREE.Texture;
17+
/** blurSize, default:3 */
18+
blurSize: number,
19+
/** blurPower, affects performance default:5 */
20+
blurPower: number,
21+
};
22+
23+
export type SimpleBlurObject = {
24+
scene: THREE.Scene;
25+
material: THREE.Material;
26+
camera: THREE.Camera;
27+
renderTarget: THREE.WebGLRenderTarget
28+
};
29+
30+
export const SIMPLEBLUR_PARAMS: SimpleBlurParams = {
31+
texture: new THREE.Texture,
32+
blurSize: 3,
33+
blurPower: 5,
34+
};
35+
36+
export const useSimpleBlur = ({
37+
size,
38+
dpr,
39+
}: {
40+
size: Size;
41+
dpr: number;
42+
}): HooksReturn<SimpleBlurParams, SimpleBlurObject> => {
43+
const scene = useMemo(() => new THREE.Scene(), []);
44+
const material = useMesh(scene);
45+
const camera = useCamera(size);
46+
47+
const fboProps = useMemo(
48+
() => ({
49+
scene,
50+
camera,
51+
size,
52+
dpr,
53+
}),
54+
[scene, camera, size, dpr]
55+
);
56+
const [renderTarget, updateRenderTarget] = useSingleFBO(fboProps);
57+
const [tempTexture, updateTempTexture] = useDoubleFBO(fboProps);
58+
const [params, setParams] = useParams<SimpleBlurParams>(SIMPLEBLUR_PARAMS);
59+
60+
const updateFx = useCallback(
61+
(props: RootState, updateParams?: SimpleBlurParams) => {
62+
const {gl} = props;
63+
64+
updateParams && setParams(updateParams);
65+
66+
setUniform(material, "uTexture", params.texture)
67+
setUniform(material, "uResolution", [params.texture.source.data.width,params.texture.source.data.height]);
68+
setUniform(material, "uBlurSize", params.blurSize)
69+
70+
let _tempTexture: THREE.Texture = updateTempTexture(gl);
71+
72+
const iterations = params.blurPower;
73+
for(let i = 0; i < iterations; i++) {
74+
setUniform(material,"uTexture",_tempTexture);
75+
_tempTexture = updateTempTexture(gl);
76+
}
77+
78+
const outPutTexture = updateRenderTarget(gl);
79+
80+
return outPutTexture;
81+
},
82+
[updateRenderTarget, updateTempTexture, material, setParams, params]
83+
);
84+
85+
return [
86+
updateFx,
87+
setParams,
88+
{
89+
scene: scene,
90+
material: material,
91+
camera: camera,
92+
renderTarget: renderTarget
93+
},
94+
];
95+
};
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
precision mediump float;
2+
3+
varying vec2 vUv;
4+
uniform sampler2D uTexture;
5+
uniform vec2 uResolution;
6+
uniform float uBlurSize;
7+
8+
void main() {
9+
vec2 uv = vUv;
10+
vec2 perDivSize = uBlurSize / uResolution;
11+
12+
// calc average color value from adjacent point
13+
vec4 outColor = vec4(
14+
texture2D(uTexture, uv + perDivSize * vec2(-1.0, -1.0)) +
15+
texture2D(uTexture, uv + perDivSize * vec2(0.0, -1.0)) +
16+
texture2D(uTexture, uv + perDivSize * vec2(1.0, -1.0)) +
17+
texture2D(uTexture, uv + perDivSize * vec2(-1.0, 0.0)) +
18+
texture2D(uTexture, uv + perDivSize * vec2(0.0, 0.0)) +
19+
texture2D(uTexture, uv + perDivSize * vec2(1.0, 0.0)) +
20+
texture2D(uTexture, uv + perDivSize * vec2(-1.0, 1.0)) +
21+
texture2D(uTexture, uv + perDivSize * vec2(0.0, 1.0)) +
22+
texture2D(uTexture, uv + perDivSize * vec2(1.0, 1.0))
23+
) / 9.0;
24+
25+
gl_FragColor = outColor;
26+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
precision mediump float;
2+
3+
varying vec2 vUv;
4+
5+
void main() {
6+
vUv = uv;
7+
gl_Position = vec4(position, 1.0);
8+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { useMemo } from "react";
2+
import * as THREE from "three";
3+
import vertexShader from "./shader/main.vert";
4+
import fragmentShader from "./shader/main.frag";
5+
6+
import { useAddMesh } from "@hmng8/use-shader-fx";
7+
8+
export class SampleMaterial extends THREE.ShaderMaterial {
9+
uniforms!: {
10+
uTexture: { value: THREE.Texture };
11+
uResolution: { value: THREE.Vector2 };
12+
uBlurSize: { value: number };
13+
};
14+
}
15+
16+
export const useMesh = (scene: THREE.Scene) => {
17+
const geometry = useMemo(() => new THREE.PlaneGeometry(2, 2), []);
18+
const material = useMemo(
19+
() =>
20+
new THREE.ShaderMaterial({
21+
uniforms: {
22+
uTexture: { value: new THREE.Texture() },
23+
uResolution: { value: new THREE.Vector2(0,0) },
24+
uBlurSize: { value: 1, }
25+
},
26+
vertexShader: vertexShader,
27+
fragmentShader: fragmentShader,
28+
}),
29+
[]
30+
);
31+
useAddMesh(scene, geometry, material);
32+
return material as SampleMaterial;
33+
};

packages/use-shader-fx/src/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export { useFluid, FLUID_PARAMS } from "./hooks/useFluid";
99
export { useRipple, RIPPLE_PARAMS } from "./hooks/useRipple";
1010
export { useTransitionBg, TRANSITIONBG_PARAMS } from "./hooks/useTransitionBg";
1111
export { useNoise, NOISE_PARAMS } from "./hooks/useNoise";
12+
export { useSimpleBlur, SIMPLEBLUR_PARAMS } from './hooks/useSimpleBlur'
1213

1314
// utils
1415
export { setUniform } from "./utils/setUniforms";
@@ -19,3 +20,4 @@ export { useParams } from "./utils/useParams";
1920
export { usePointer } from "./utils/usePointer";
2021
export { useResolution } from "./utils/useResolution";
2122
export { useSingleFBO } from "./utils/useSingleFBO";
23+

0 commit comments

Comments
 (0)