11import * as THREE from "three" ;
2- import { useRef } from "react" ;
2+ import { useMemo , useRef , useState , useEffect } from "react" ;
33import { useFrame , useThree } from "@react-three/fiber" ;
44import {
55 useNoise ,
66 useFluid ,
77 useFxBlending ,
88 useColorStrata ,
99 useBrightnessPicker ,
10+ useSingleFBO ,
1011} from "@/packages/use-shader-fx/src" ;
1112
13+ function Box ( props : any ) {
14+ // This reference will give us direct access to the mesh
15+ const meshRef = useRef < THREE . Mesh > ( ) ;
16+ // Set up state for the hovered and active state
17+ const [ hovered , setHover ] = useState ( false ) ;
18+ const [ active , setActive ] = useState ( false ) ;
19+ // Subscribe this component to the render-loop, rotate the mesh every frame
20+ useFrame ( ( state , delta ) => {
21+ meshRef . current ! . rotation . x += delta ;
22+ meshRef . current ! . rotation . y -= delta ;
23+ } ) ;
24+ // Return view, these are regular three.js elements expressed in JSX
25+ return (
26+ < mesh
27+ { ...props }
28+ ref = { meshRef }
29+ scale = { active ? 2 : 1.5 }
30+ onClick = { ( event ) => setActive ( ! active ) }
31+ onPointerOver = { ( event ) => setHover ( true ) }
32+ onPointerOut = { ( event ) => setHover ( false ) } >
33+ < boxGeometry args = { [ 1 , 1 , 1 ] } />
34+ < meshStandardMaterial color = { hovered ? "hotpink" : "orange" } />
35+ </ mesh >
36+ ) ;
37+ }
38+
1239export const Home = ( ) => {
1340 const ref = useRef < THREE . ShaderMaterial > ( null ) ;
14- const { size, dpr } = useThree ( ( state ) => {
15- return { size : state . size , dpr : state . viewport . dpr } ;
16- } ) ;
41+ const { size, viewport, camera } = useThree ( ) ;
42+ const dpr = viewport . dpr ;
1743 const [ updateNoise , setNoise ] = useNoise ( { size, dpr } ) ;
1844 const [ updateFluid , setFluid ] = useFluid ( { size, dpr } ) ;
1945 const [ updateFxBlending , setFxBlending ] = useFxBlending ( { size, dpr } ) ;
@@ -54,6 +80,20 @@ export const Home = () => {
5480 noiseStrength : new THREE . Vector2 ( 1 , 1 ) ,
5581 } ) ;
5682
83+ // This scene is rendered offscreen
84+ const offscreenScene = useMemo ( ( ) => new THREE . Scene ( ) , [ ] ) ;
85+ const offscreenMesh = useRef < THREE . Mesh > ( null ) ;
86+ // create FBO for offscreen rendering
87+ const [ _ , updateRenderTarget ] = useSingleFBO ( {
88+ scene : offscreenScene ,
89+ camera,
90+ size,
91+ dpr : viewport . dpr ,
92+ } ) ;
93+ useEffect ( ( ) => {
94+ offscreenScene . add ( offscreenMesh . current ! ) ;
95+ } , [ offscreenScene ] ) ;
96+
5797 useFrame ( ( props ) => {
5898 const noise = updateNoise ( props ) ;
5999 const fluid = updateFluid ( props ) ;
@@ -69,34 +109,184 @@ export const Home = () => {
69109 noise : noise ,
70110 } ) ;
71111 ref . current ! . uniforms . u_fx . value = colorStrata ;
112+ ref . current ! . uniforms . u_texture . value = updateRenderTarget ( props . gl ) ;
72113 } ) ;
73114
74115 return (
75- < mesh >
76- < planeGeometry args = { [ 2 , 2 ] } />
77- < shaderMaterial
78- ref = { ref }
79- vertexShader = { `
116+ < >
117+ < mesh ref = { offscreenMesh } >
118+ < ambientLight intensity = { Math . PI } />
119+ < spotLight
120+ position = { [ 10 , 10 , 10 ] }
121+ angle = { 0.15 }
122+ penumbra = { 1 }
123+ decay = { 0 }
124+ intensity = { Math . PI }
125+ />
126+ < pointLight
127+ position = { [ - 10 , - 10 , - 10 ] }
128+ decay = { 0 }
129+ intensity = { Math . PI }
130+ />
131+ < Box position = { [ - 1.5 , 0 , 0 ] } />
132+ < Box position = { [ 1.5 , 0 , 0 ] } />
133+ </ mesh >
134+ < mesh >
135+ < planeGeometry args = { [ 2 , 2 ] } />
136+ < shaderMaterial
137+ ref = { ref }
138+ transparent
139+ vertexShader = { `
80140 varying vec2 vUv;
81141 void main() {
82142 vUv = uv;
83143 gl_Position = vec4(position, 1.0);
84144 }
85145 ` }
86- fragmentShader = { `
146+ fragmentShader = { `
87147 precision highp float;
88148 varying vec2 vUv;
89149 uniform sampler2D u_fx;
150+ uniform sampler2D u_texture;
90151
91152 void main() {
92153 vec2 uv = vUv;
93- gl_FragColor = texture2D(u_fx, uv);
154+ vec3 noiseMap = texture2D(u_fx, uv).rgb;
155+ vec3 nNoiseMap = noiseMap * 2.0 - 1.0;
156+ uv = uv * 2.0 - 1.0;
157+ uv *= mix(vec2(1.0), abs(nNoiseMap.rg), 1.);
158+ uv = (uv + 1.0) / 2.0;
159+
160+ vec3 texColor = texture2D(u_texture, uv).rgb;
161+ vec3 color = mix(texColor,noiseMap,0.5);
162+
163+ float luminance = length(color);
164+
165+ float edge0 = 0.0;
166+ float edge1 = .2;
167+ float alpha = smoothstep(edge0, edge1, luminance);
168+
169+ gl_FragColor = vec4(color,alpha);
170+
94171 }
95172 ` }
96- uniforms = { {
97- u_fx : { value : null } ,
98- } }
99- />
100- </ mesh >
173+ uniforms = { {
174+ u_texture : { value : null } ,
175+ u_fx : { value : null } ,
176+ } }
177+ />
178+ </ mesh >
179+ </ >
101180 ) ;
102181} ;
182+
183+ // import * as THREE from "three";
184+ // import { useEffect, useMemo, useRef, useState } from "react";
185+ // import { useFrame, useThree } from "@react-three/fiber";
186+ // import { useNoise, useSingleFBO } from "@/packages/use-shader-fx/src";
187+
188+ // function Box(props: any) {
189+ // // This reference will give us direct access to the mesh
190+ // const meshRef = useRef<THREE.Mesh>();
191+ // // Set up state for the hovered and active state
192+ // const [hovered, setHover] = useState(false);
193+ // const [active, setActive] = useState(false);
194+ // // Subscribe this component to the render-loop, rotate the mesh every frame
195+ // useFrame((state, delta) => (meshRef.current!.rotation.x += delta));
196+ // // Return view, these are regular three.js elements expressed in JSX
197+ // return (
198+ // <mesh
199+ // {...props}
200+ // ref={meshRef}
201+ // scale={active ? 1.5 : 1}
202+ // onClick={(event) => setActive(!active)}
203+ // onPointerOver={(event) => setHover(true)}
204+ // onPointerOut={(event) => setHover(false)}>
205+ // <boxGeometry args={[1, 1, 1]} />
206+ // <meshStandardMaterial color={hovered ? "hotpink" : "orange"} />
207+ // </mesh>
208+ // );
209+ // }
210+
211+ // export const Home = () => {
212+ // const { size, viewport, camera, gl } = useThree();
213+
214+ // // This scene is rendered offscreen
215+ // const offscreenScene = useMemo(() => new THREE.Scene(), []);
216+ // const offscreenMesh = useRef<THREE.Mesh>(null);
217+ // // create FBO for offscreen rendering
218+ // const [_, updateRenderTarget] = useSingleFBO({
219+ // scene: offscreenScene,
220+ // camera,
221+ // size,
222+ // dpr: viewport.dpr,
223+ // });
224+ // useEffect(() => {
225+ // offscreenScene.add(offscreenMesh.current!);
226+ // }, [offscreenScene]);
227+
228+ // // generate noise
229+ // const shaderMaterial = useRef<THREE.ShaderMaterial>(null);
230+ // const [updateNoise] = useNoise({ size, dpr: viewport.dpr });
231+
232+ // useFrame((props) => {
233+ // shaderMaterial.current!.uniforms.u_fx.value = updateNoise(props);
234+ // shaderMaterial.current!.uniforms.u_texture.value = updateRenderTarget(gl);
235+ // });
236+
237+ // return (
238+ // <>
239+ // <mesh ref={offscreenMesh}>
240+ // <ambientLight intensity={Math.PI / 2} />
241+ // <spotLight
242+ // position={[10, 10, 10]}
243+ // angle={0.15}
244+ // penumbra={1}
245+ // decay={0}
246+ // intensity={Math.PI}
247+ // />
248+ // <pointLight
249+ // position={[-10, -10, -10]}
250+ // decay={0}
251+ // intensity={Math.PI}
252+ // />
253+ // <Box position={[-1.2, 0, 0]} />
254+ // <Box position={[1.2, 0, 0]} />
255+ // </mesh>
256+ // <mesh>
257+ // <planeGeometry args={[2, 2]} />
258+ // <shaderMaterial
259+ // ref={shaderMaterial}
260+ // transparent
261+ // vertexShader={`
262+ // varying vec2 vUv;
263+ // void main() {
264+ // vUv = uv;
265+ // gl_Position = vec4(position, 1.0);
266+ // }
267+ // `}
268+ // fragmentShader={`
269+ // precision highp float;
270+ // varying vec2 vUv;
271+ // uniform sampler2D u_fx;
272+ // uniform sampler2D u_texture;
273+
274+ // void main() {
275+ // vec2 uv = vUv;
276+ // vec3 noiseMap = texture2D(u_fx, uv).rgb;
277+ // vec3 nNoiseMap = noiseMap * 2.0 - 1.0;
278+ // uv = uv * 2.0 - 1.0;
279+ // uv *= mix(vec2(1.0), abs(nNoiseMap.rg), .6);
280+ // uv = (uv + 1.0) / 2.0;
281+ // gl_FragColor = texture2D(u_texture, uv);
282+ // }
283+ // `}
284+ // uniforms={{
285+ // u_texture: { value: null },
286+ // u_fx: { value: null },
287+ // }}
288+ // />
289+ // </mesh>
290+ // </>
291+ // );
292+ // };
0 commit comments