Skip to content

Commit fdd6e6d

Browse files
authored
Merge pull request #55 from takuma-hmng8/dev
v1.0.34
2 parents c5a4d8a + 7c5ae19 commit fdd6e6d

File tree

46 files changed

+1207
-970
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1207
-970
lines changed

.storybook/stories/UseRipple.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export const UseRippleWithTexture = (args: RippleParams) => {
5858
return { size: state.size, dpr: state.viewport.dpr };
5959
});
6060
const [updateFxTexture] = useFxTexture({ size, dpr });
61-
const [updateRipple] = useRipple({ size, texture: ripple });
61+
const [updateRipple] = useRipple({ size, dpr, texture: ripple });
6262

6363
useFrame((props) => {
6464
const fx = updateRipple(props, setConfig());

.storybook/utils/Setup.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export const Setup = ({ children }: { children: React.ReactNode }) => {
1313
factor={1}
1414
onChange={({ factor }) => {
1515
console.log(`dpr:${dpr}`);
16-
setDpr(Math.round((0.5 + 1.5 * factor) * 10) / 10);
16+
setDpr(Math.round((0.5 + 1.0 * factor) * 10) / 10);
1717
}}>
1818
{children}
1919
<Perf position={"bottom-left"} minimal={false} />

README.md

+140-9
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ npm install @hmng8/use-shader-fx
1111

1212
# Usage
1313

14-
From each `fxHooks`, you can receive [`updateFx`, `setParams`, `fxObject`] in array format. The `config` is an object, which varies for each Hook, containing details such as `size` and `dpr`.
14+
From each `fxHooks`, you can receive [`updateFx`, `setParams`, `fxObject`] in array format. The `config` is an object, which varies for each Hook, containing details such as `size`,`dpr` and `samples`.
1515

1616
1. `updateFx` - A function to be invoked inside `useFrame`, returning a `THREE.Texture`.
1717
2. `setParams` - A function to refresh the parameters, beneficial for performance tweaking, etc.
@@ -45,9 +45,8 @@ import { useFluid } from "@hmng8/use-shader-fx";
4545

4646
export const Demo = () => {
4747
const ref = useRef<THREE.ShaderMaterial>(null);
48-
const size = useThree((state) => state.size);
49-
const dpr = useThree((state) => state.viewport.dpr);
50-
const [updateFluid] = useFluid({ size, dpr });
48+
const { size, viewport } = useThree();
49+
const [updateFluid] = useFluid({ size, dpr: viewport.dpr });
5150
useFrame((props) => {
5251
ref.current!.uniforms.u_fx.value = updateFluid(props);
5352
});
@@ -83,6 +82,135 @@ export const Demo = () => {
8382
};
8483
```
8584

85+
## Integrate with r3f scenes.
86+
87+
You can use `r3f/createPortal` to make some mesh render off-screen. All that remains is to combine the generated textures with FX!
88+
89+
```tsx
90+
import * as THREE from "three";
91+
import { useMemo, useRef, useState } from "react";
92+
import { useFrame, useThree, createPortal } from "@react-three/fiber";
93+
import { useNoise, useSingleFBO } from "@hmng8/use-shader-fx";
94+
95+
function Box(props: any) {
96+
// This reference will give us direct access to the mesh
97+
const meshRef = useRef<THREE.Mesh>();
98+
// Set up state for the hovered and active state
99+
const [hovered, setHover] = useState(false);
100+
const [active, setActive] = useState(false);
101+
// Subscribe this component to the render-loop, rotate the mesh every frame
102+
useFrame((state, delta) => {
103+
meshRef.current!.rotation.x += delta;
104+
meshRef.current!.rotation.y -= delta;
105+
});
106+
// Return view, these are regular three.js elements expressed in JSX
107+
return (
108+
<mesh
109+
{...props}
110+
ref={meshRef}
111+
scale={active ? 2 : 1.5}
112+
onClick={(event) => setActive(!active)}
113+
onPointerOver={(event) => setHover(true)}
114+
onPointerOut={(event) => setHover(false)}>
115+
<boxGeometry args={[1, 1, 1]} />
116+
<meshStandardMaterial color={hovered ? "hotpink" : "orange"} />
117+
</mesh>
118+
);
119+
}
120+
121+
export const Home = () => {
122+
const ref = useRef<THREE.ShaderMaterial>(null);
123+
const { size, viewport, camera } = useThree();
124+
const [updateNoise, setNoise] = useNoise({ size, dpr: viewport.dpr });
125+
126+
setNoise({
127+
scale: 0.01,
128+
warpOctaves: 1,
129+
noiseOctaves: 1,
130+
fbmOctaves: 1,
131+
timeStrength: 1.2,
132+
warpStrength: 20.0,
133+
});
134+
135+
// This scene is rendered offscreen
136+
const offscreenScene = useMemo(() => new THREE.Scene(), []);
137+
138+
// create FBO for offscreen rendering
139+
const [_, updateRenderTarget] = useSingleFBO({
140+
scene: offscreenScene,
141+
camera,
142+
size,
143+
dpr: viewport.dpr,
144+
samples: 4,
145+
});
146+
147+
useFrame((props) => {
148+
const noise = updateNoise(props);
149+
ref.current!.uniforms.u_fx.value = noise;
150+
ref.current!.uniforms.u_texture.value = updateRenderTarget(props.gl);
151+
});
152+
153+
return (
154+
<>
155+
{createPortal(
156+
<mesh>
157+
<ambientLight intensity={Math.PI} />
158+
<spotLight
159+
position={[10, 10, 10]}
160+
angle={0.15}
161+
penumbra={1}
162+
decay={0}
163+
intensity={Math.PI}
164+
/>
165+
<pointLight
166+
position={[-10, -10, -10]}
167+
decay={0}
168+
intensity={Math.PI}
169+
/>
170+
<Box position={[-1.5, 0, 0]} />
171+
<Box position={[1.5, 0, 0]} />
172+
</mesh>,
173+
offscreenScene
174+
)}
175+
<mesh>
176+
<planeGeometry args={[2, 2]} />
177+
<shaderMaterial
178+
ref={ref}
179+
transparent
180+
vertexShader={`
181+
varying vec2 vUv;
182+
void main() {
183+
vUv = uv;
184+
gl_Position = vec4(position, 1.0);
185+
}
186+
`}
187+
fragmentShader={`
188+
precision highp float;
189+
varying vec2 vUv;
190+
uniform sampler2D u_fx;
191+
uniform sampler2D u_texture;
192+
193+
void main() {
194+
vec2 uv = vUv;
195+
vec3 noiseMap = texture2D(u_fx, uv).rgb;
196+
vec3 nNoiseMap = noiseMap * 2.0 - 1.0;
197+
uv = uv * 2.0 - 1.0;
198+
uv *= mix(vec2(1.0), abs(nNoiseMap.rg), .6);
199+
uv = (uv + 1.0) / 2.0;
200+
gl_FragColor = texture2D(u_texture, uv);
201+
}
202+
`}
203+
uniforms={{
204+
u_texture: { value: null },
205+
u_fx: { value: null },
206+
}}
207+
/>
208+
</mesh>
209+
</>
210+
);
211+
};
212+
```
213+
86214
# Performance
87215

88216
You can control the `dpr` using the `PerformanceMonitor` from [drei](https://github.com/pmndrs/drei). For more details, please refer to the [scaling-performance](https://docs.pmnd.rs/react-three-fiber/advanced/scaling-performance) of r3f.
@@ -146,8 +274,14 @@ type UseFboProps = {
146274
size: Size;
147275
/** If dpr is set, dpr will be multiplied, default:false */
148276
dpr?: number | false;
149-
/** Whether to resize on resizes. If isDpr is true, set FBO to setSize even if dpr is changed, default:false */
277+
/** Whether to resize when resizing occurs. If isDpr is true, set FBO to setSize even if dpr is changed, default:false */
150278
isSizeUpdate?: boolean;
279+
/** Defines the count of MSAA samples. Can only be used with WebGL 2. Default is 0. */
280+
samples?: number;
281+
/** Renders to the depth buffer. Unlike the three.js, Default is false. */
282+
depthBuffer?: boolean;
283+
/** If set, the scene depth will be rendered to this texture. Default is false. */
284+
depthTexture?: boolean;
151285
};
152286

153287
const [velocityFBO, updateVelocityFBO] = useDoubleFBO(UseFboProps);
@@ -230,10 +364,7 @@ const [params, setParams] = useParams<HooksParams>;
230364
Generate an FBO array to copy the texture.
231365

232366
```tsx
233-
const [renderTargets, copyTexture] = useCopyTexture(
234-
{ scene, camera, size, dpr },
235-
length
236-
);
367+
const [renderTargets, copyTexture] = useCopyTexture(UseFboProps, length);
237368
copyTexture(gl, index); // return texture
238369
```
239370

app/ShaderFx.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export const ShaderFx = ({ children }: { children: React.ReactNode }) => {
1616
setDpr(Math.round((0.5 + 1.0 * factor) * 10) / 10);
1717
}}>
1818
<Suspense fallback={null}>{children}</Suspense>
19-
{/* <Perf position={"bottom-left"} minimal={false} /> */}
19+
<Perf position={"bottom-left"} minimal={false} />
2020
</PerformanceMonitor>
2121
</Canvas>
2222
);

app/_home/index.tsx

+67-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ export const Home = () => {
162162
vec3 color = mix(texColor,noiseMap,0.5);
163163
164164
float luminance = length(color);
165-
165+
166166
float edge0 = 0.0;
167167
float edge1 = .2;
168168
float alpha = smoothstep(edge0, edge1, luminance);
@@ -180,3 +180,69 @@ export const Home = () => {
180180
</>
181181
);
182182
};
183+
184+
// import * as THREE from "three";
185+
// import { useEffect, useMemo, useRef, useState } from "react";
186+
// import { useFrame, useThree, createPortal } from "@react-three/fiber";
187+
// import {
188+
// useNoise,
189+
// useFluid,
190+
// useFxBlending,
191+
// useColorStrata,
192+
// useBrightnessPicker,
193+
// useSingleFBO,
194+
// } from "@/packages/use-shader-fx/src";
195+
196+
// export const Home = () => {
197+
// const ref = useRef<THREE.ShaderMaterial>(null);
198+
// const { size, viewport, camera } = useThree();
199+
// const dpr = viewport.dpr;
200+
201+
// const [updateFluid, setFluid] = useFluid({ size, dpr });
202+
203+
// setFluid({
204+
// density_dissipation: 0.96,
205+
// velocity_dissipation: 0.99,
206+
// curl_strength: 0.0,
207+
// splat_radius: 0.0045,
208+
// pressure_iterations: 1,
209+
// });
210+
211+
// useFrame((props) => {
212+
// const fluid = updateFluid(props);
213+
214+
// ref.current!.uniforms.u_fx.value = fluid;
215+
// });
216+
217+
// return (
218+
// <>
219+
// <mesh>
220+
// <planeGeometry args={[2, 2]} />
221+
// <shaderMaterial
222+
// ref={ref}
223+
// transparent
224+
// vertexShader={`
225+
// varying vec2 vUv;
226+
// void main() {
227+
// vUv = uv;
228+
// gl_Position = vec4(position, 1.0);
229+
// }
230+
// `}
231+
// fragmentShader={`
232+
// precision highp float;
233+
// varying vec2 vUv;
234+
// uniform sampler2D u_fx;
235+
// void main() {
236+
// vec2 uv = vUv;
237+
// gl_FragColor = texture2D(u_fx, uv);
238+
239+
// }
240+
// `}
241+
// uniforms={{
242+
// u_fx: { value: null },
243+
// }}
244+
// />
245+
// </mesh>
246+
// </>
247+
// );
248+
// };

app/playground/Playground.tsx

+37-2
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,20 @@ import { useGUI } from "@/utils/useGUI";
2424
const CONFIG = {
2525
colorStrata: {
2626
...structuredClone(COLORSTRATA_PARAMS),
27-
laminateLayer: 20,
27+
laminateLayer: 10,
2828
laminateInterval: new THREE.Vector2(0.1, 0.1),
2929
laminateDetail: new THREE.Vector2(0.7, 0.7),
3030
distortion: new THREE.Vector2(10.0, 10.0),
3131
colorFactor: new THREE.Vector3(1, 1, 1),
3232
timeStrength: new THREE.Vector2(1, 1),
3333
noiseStrength: new THREE.Vector2(1, 1),
3434
} as ColorStrataParams,
35+
color: {
36+
color0: new THREE.Color(0xff0000),
37+
color1: new THREE.Color(0x0000ff),
38+
color2: new THREE.Color(0x00ff00),
39+
color3: new THREE.Color(0xffff00),
40+
},
3541
};
3642

3743
const setGUI = (gui: GUI) => {
@@ -58,11 +64,18 @@ const setGUI = (gui: GUI) => {
5864
const noiseStrength = colorStrata.addFolder("noiseStrength");
5965
noiseStrength.add(CONFIG.colorStrata.noiseStrength!, "x", 0, 5, 0.01);
6066
noiseStrength.add(CONFIG.colorStrata.noiseStrength!, "y", 0, 5, 0.01);
67+
// color
68+
const color = gui.addFolder("color");
69+
color.addColor(CONFIG.color, "color0");
70+
color.addColor(CONFIG.color, "color1");
71+
color.addColor(CONFIG.color, "color2");
72+
color.addColor(CONFIG.color, "color3");
6173
};
6274

6375
const setConfig = () => {
6476
return {
6577
colorStrata: { ...CONFIG.colorStrata },
78+
color: { ...CONFIG.color },
6679
};
6780
};
6881

@@ -83,6 +96,10 @@ export const Playground = () => {
8396
noise: false,
8497
});
8598
ref.current!.uniforms.u_fx.value = colorStrata;
99+
ref.current!.uniforms.u_color0.value = setConfig().color.color0;
100+
ref.current!.uniforms.u_color1.value = setConfig().color.color1;
101+
ref.current!.uniforms.u_color2.value = setConfig().color.color2;
102+
ref.current!.uniforms.u_color3.value = setConfig().color.color3;
86103
updateGUI();
87104
});
88105

@@ -102,14 +119,32 @@ export const Playground = () => {
102119
precision highp float;
103120
varying vec2 vUv;
104121
uniform sampler2D u_fx;
122+
uniform vec3 u_color0;
123+
uniform vec3 u_color1;
124+
uniform vec3 u_color2;
125+
uniform vec3 u_color3;
105126
106127
void main() {
107128
vec2 uv = vUv;
108-
gl_FragColor = texture2D(u_fx, uv);
129+
130+
vec2 map = texture2D(u_fx, uv).rg;
131+
vec2 normalizedMap = map * 2.0 - 1.0;
132+
133+
uv = uv * 2.0 - 1.0;
134+
uv *= mix(vec2(1.0), abs(normalizedMap), 3.0);
135+
uv = (uv + 1.0) / 2.0;
136+
137+
vec3 col = mix(mix(u_color0, u_color1, uv.x), mix(u_color2, u_color3, uv.x), uv.y);
138+
139+
gl_FragColor = vec4(col, 1.0);
109140
}
110141
`}
111142
uniforms={{
112143
u_fx: { value: null },
144+
u_color0: { value: null },
145+
u_color1: { value: null },
146+
u_color2: { value: null },
147+
u_color3: { value: null },
113148
}}
114149
/>
115150
</mesh>

0 commit comments

Comments
 (0)