Skip to content

Commit fb198d4

Browse files
authored
Merge branch 'main' into minor-update
2 parents fd8559e + d9d0ec1 commit fb198d4

File tree

6 files changed

+265
-0
lines changed

6 files changed

+265
-0
lines changed

.storybook/stories/UseCosPalette.tsx

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import * as React from "react";
2+
import * as THREE from "three";
3+
import { useFrame, extend, useThree, useLoader } from "@react-three/fiber";
4+
import { FxMaterial, FxMaterialProps } from "../../utils/fxMaterial";
5+
import { CONSTANT } from "../constant";
6+
import GUI from "lil-gui";
7+
import { useGUI } from "../../utils/useGUI";
8+
import { useCosPalette, useFxTexture } from "../../packages/use-shader-fx/src";
9+
import {
10+
CosPaletteParams,
11+
COSPALETTE_PARAMS,
12+
} from "../../packages/use-shader-fx/src/hooks/useCosPalette";
13+
14+
extend({ FxMaterial });
15+
16+
const CONFIG: CosPaletteParams = structuredClone(COSPALETTE_PARAMS);
17+
const setGUI = (gui: GUI) => {
18+
gui.addColor(CONFIG, "color1");
19+
gui.addColor(CONFIG, "color2");
20+
gui.addColor(CONFIG, "color3");
21+
gui.addColor(CONFIG, "color4");
22+
gui.add(CONFIG.rgbWeight!, "x", 0, 1, 0.299);
23+
gui.add(CONFIG.rgbWeight!, "y", 0, 1, 0.587);
24+
gui.add(CONFIG.rgbWeight!, "z", 0, 1, 0.114);
25+
};
26+
const setConfig = () => {
27+
return {
28+
...CONFIG,
29+
} as CosPaletteParams;
30+
};
31+
32+
33+
export const UseCosPalette = (args: CosPaletteParams) => {
34+
const updateGUI = useGUI(setGUI);
35+
const [bg] = useLoader(THREE.TextureLoader, ["momo.jpg"]);
36+
37+
const fxRef = React.useRef<FxMaterialProps>();
38+
const { size, dpr } = useThree((state) => {
39+
return { size: state.size, dpr: state.viewport.dpr };
40+
});
41+
const [updateCosPalette] = useCosPalette({ size, dpr });
42+
const [updateFxTexture, setFxTexture] = useFxTexture({ size, dpr });
43+
44+
setFxTexture({
45+
textureResolution: CONSTANT.textureResolution,
46+
texture0: bg,
47+
});
48+
49+
useFrame((props) => {
50+
const tex = updateFxTexture(props);
51+
const fx = updateCosPalette(props, {
52+
...setConfig(),
53+
texture: tex,
54+
});
55+
fxRef.current!.u_fx = fx;
56+
updateGUI();
57+
});
58+
59+
return (
60+
<mesh>
61+
<planeGeometry args={[2, 2]} />
62+
<fxMaterial key={FxMaterial.key} ref={fxRef} />
63+
</mesh>
64+
);
65+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
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 { UseCosPalette } from "./UseCosPalette";
7+
import {
8+
COSPALETTE_PARAMS,
9+
CosPaletteParams,
10+
} from "../../packages/use-shader-fx/src/hooks/useCosPalette";
11+
12+
const meta = {
13+
title: "useCosPalette",
14+
component: UseCosPalette,
15+
tags: ["autodocs"],
16+
decorators: [(storyFn: any) => <Setup>{storyFn()}</Setup>],
17+
} satisfies Meta<typeof UseCosPalette>;
18+
19+
export default meta;
20+
type Story = StoryObj<typeof meta>;
21+
22+
const storySetting = {
23+
args: COSPALETTE_PARAMS,
24+
argTypes: setArgTypes<CosPaletteParams>(COSPALETTE_PARAMS),
25+
};
26+
27+
export const Default: Story = {
28+
render: (args) => <UseCosPalette {...args} />,
29+
...storySetting,
30+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import { useCallback, useMemo } from "react";
2+
import * as THREE from "three";
3+
import { useMesh } from "./useMesh";
4+
import { RootState } from "@react-three/fiber";
5+
import { useCamera } from "../../utils/useCamera";
6+
import { useSingleFBO } from "../../utils/useSingleFBO";
7+
import { setUniform } from "../../utils/setUniforms";
8+
import { useParams } from "../../utils/useParams";
9+
import { HooksProps, HooksReturn } from "../types";
10+
11+
export type CosPaletteParams = {
12+
/** color1, default:rgb(50%, 50%, 50%) */
13+
color1?: THREE.Color;
14+
/** color2, default:rgb(50%, 50%, 50%) */
15+
color2?: THREE.Color;
16+
/** color3, default:rgb(100%, 100%, 100%) */
17+
color3?: THREE.Color;
18+
/** color4, default:rgb(0%, 10%, 20%) */
19+
color4?: THREE.Color;
20+
/** texture to be used as a palette */
21+
texture?: THREE.Texture;
22+
/** weight of the rgb, default:THREE.Vector3(1.0,0.0,0.0) */
23+
rgbWeight?: THREE.Vector3;
24+
};
25+
26+
export type ColorPaletteObject = {
27+
scene: THREE.Scene;
28+
material: THREE.Material;
29+
camera: THREE.Camera;
30+
renderTarget: THREE.WebGLRenderTarget;
31+
output: THREE.Texture;
32+
};
33+
34+
export const COSPALETTE_PARAMS: CosPaletteParams = {
35+
texture: new THREE.Texture(),
36+
color1: new THREE.Color().set(0.5,0.5,0.5),
37+
color2: new THREE.Color().set(0.5,0.5,0.5),
38+
color3: new THREE.Color().set(1,1,1),
39+
color4: new THREE.Color().set(0,0.1,0.2),
40+
rgbWeight: new THREE.Vector3(0.299,0.587,0.114),
41+
};
42+
43+
/**
44+
* @link https://github.com/takuma-hmng8/use-shader-fx#usage
45+
*/
46+
export const useCosPalette = ({
47+
size,
48+
dpr,
49+
samples = 0,
50+
}: HooksProps): HooksReturn<CosPaletteParams, ColorPaletteObject> => {
51+
const scene = useMemo(() => new THREE.Scene(), []);
52+
const material = useMesh(scene);
53+
const camera = useCamera(size);
54+
const [renderTarget, updateRenderTarget] = useSingleFBO({
55+
scene,
56+
camera,
57+
size,
58+
dpr,
59+
samples,
60+
});
61+
62+
const [params, setParams] = useParams<CosPaletteParams>(COSPALETTE_PARAMS);
63+
64+
const updateFx = useCallback(
65+
(props: RootState, updateParams?: CosPaletteParams) => {
66+
const { gl } = props;
67+
68+
updateParams && setParams(updateParams);
69+
70+
setUniform(material, "uTexture", params.texture!);
71+
setUniform(material, "uColor1", params.color1!);
72+
setUniform(material, "uColor2", params.color2!);
73+
setUniform(material, "uColor3", params.color3!);
74+
setUniform(material, "uColor4", params.color4!);
75+
setUniform(material, "uRgbWeight", params.rgbWeight!);
76+
77+
return updateRenderTarget(gl);
78+
},
79+
[updateRenderTarget, material, setParams, params]
80+
);
81+
82+
return [
83+
updateFx,
84+
setParams,
85+
{
86+
scene: scene,
87+
material: material,
88+
camera: camera,
89+
renderTarget: renderTarget,
90+
output: renderTarget.texture,
91+
},
92+
];
93+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
precision highp float;
2+
precision highp int;
3+
4+
varying vec2 vUv;
5+
uniform sampler2D uTexture;
6+
uniform vec3 uColor1;
7+
uniform vec3 uColor2;
8+
uniform vec3 uColor3;
9+
uniform vec3 uColor4;
10+
uniform vec3 uRgbWeight;
11+
12+
13+
// Based on glsl-cos-palette by Erkaman
14+
// https://github.com/Erkaman/glsl-cos-palette
15+
vec3 cosPalette( float t, vec3 color1, vec3 color2, vec3 color3, vec3 color4 ){
16+
return color1 + color2 * cos( 6.28318 * ( color3 * t + color4) );
17+
}
18+
19+
void main() {
20+
21+
vec4 tex = texture2D(uTexture, vUv);
22+
float gray = dot(tex.rgb, uRgbWeight);
23+
24+
vec3 outColor = cosPalette(
25+
gray,
26+
uColor1,
27+
uColor2,
28+
uColor3,
29+
uColor4
30+
);
31+
32+
gl_FragColor = vec4(outColor, tex.a);
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
varying vec2 vUv;
2+
3+
void main() {
4+
vUv = uv;
5+
gl_Position = vec4(position, 1.0);
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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+
import { useAddMesh } from "../../utils/useAddMesh";
6+
7+
export class CosPaletteMaterial extends THREE.ShaderMaterial {
8+
uniforms!: {
9+
uTexture: { value: THREE.Texture };
10+
uRgbWeight: { value: THREE.Vector3 };
11+
uColor1: { value: THREE.Color };
12+
uColor2: { value: THREE.Color };
13+
uColor3: { value: THREE.Color };
14+
uColor4: { value: THREE.Color };
15+
};
16+
}
17+
18+
export const useMesh = (scene: THREE.Scene) => {
19+
const geometry = useMemo(() => new THREE.PlaneGeometry(2, 2), []);
20+
const material = useMemo(
21+
() =>
22+
new THREE.ShaderMaterial({
23+
uniforms: {
24+
uTexture: { value: new THREE.Texture() },
25+
uRgbWeight: { value: new THREE.Vector3(0.299,0.587,0.114)},
26+
uColor1: { value: new THREE.Color().set(0.5,0.5,0.5) },
27+
uColor2: { value: new THREE.Color().set(0.5,0.5,0.5) },
28+
uColor3: { value: new THREE.Color().set(1,1,1) },
29+
uColor4: { value: new THREE.Color().set(0,0.1,0.2) },
30+
},
31+
vertexShader: vertexShader,
32+
fragmentShader: fragmentShader,
33+
}),
34+
[]
35+
);
36+
useAddMesh(scene, geometry, material);
37+
return material as CosPaletteMaterial;
38+
};

0 commit comments

Comments
 (0)