Skip to content

Commit f5a699f

Browse files
feat: add hue & saturation (#151)
* init hue saturation * add hue-saturation effect * fix warning import * fix name .md * update package V2 * delete import --------- Co-authored-by: Alvaro Saburido <[email protected]>
1 parent f3da309 commit f5a699f

File tree

8 files changed

+228
-1
lines changed

8 files changed

+228
-1
lines changed

docs/.vitepress/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export default defineConfig({
5656
{ text: 'Scanline', link: '/guide/pmndrs/scanline' },
5757
{ text: 'Pixelation', link: '/guide/pmndrs/pixelation' },
5858
{ text: 'Vignette', link: '/guide/pmndrs/vignette' },
59+
{ text: 'Hue & Saturation', link: '/guide/pmndrs/hue-saturation' },
5960
],
6061
},
6162
{
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<script setup lang="ts">
2+
import { Environment, OrbitControls } from '@tresjs/cientos'
3+
import { TresCanvas } from '@tresjs/core'
4+
import { TresLeches, useControls } from '@tresjs/leches'
5+
import { EffectComposerPmndrs, HueSaturationPmndrs } from '@tresjs/post-processing'
6+
7+
import { BlendFunction } from 'postprocessing'
8+
import { NoToneMapping } from 'three'
9+
10+
import '@tresjs/leches/styles'
11+
12+
const gl = {
13+
toneMapping: NoToneMapping,
14+
multisampling: 8,
15+
}
16+
17+
const { saturation, hue, blendFunction } = useControls({
18+
hue: { value: -Math.PI, min: -Math.PI, max: Math.PI, step: 0.001 },
19+
saturation: { value: 1, min: -1, max: 1, step: 0.001 },
20+
blendFunction: {
21+
options: Object.keys(BlendFunction).map(key => ({
22+
text: key,
23+
value: BlendFunction[key],
24+
})),
25+
value: BlendFunction.SRC,
26+
},
27+
})
28+
</script>
29+
30+
<template>
31+
<TresLeches style="left: initial;right:10px; top:10px;" />
32+
33+
<TresCanvas
34+
v-bind="gl"
35+
>
36+
<TresPerspectiveCamera
37+
:position="[5, 5, 5]"
38+
:look-at="[0, 0, 0]"
39+
/>
40+
<OrbitControls auto-rotate />
41+
42+
<TresMesh :position="[0, 1, 0]">
43+
<TresBoxGeometry :args="[2, 2, 2]" />
44+
<TresMeshPhysicalMaterial color="white" />
45+
</TresMesh>
46+
47+
<Suspense>
48+
<Environment background :blur=".25" preset="modern" />
49+
</Suspense>
50+
51+
<Suspense>
52+
<EffectComposerPmndrs>
53+
<HueSaturationPmndrs :blendFunction="Number(blendFunction.value)" :hue="hue.value" :saturation="saturation.value" />
54+
</EffectComposerPmndrs>
55+
</Suspense>
56+
</TresCanvas>
57+
</template>

docs/components.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ declare module 'vue' {
1515
GlitchDemo: typeof import('./.vitepress/theme/components/pmdrs/GlitchDemo.vue')['default']
1616
GlitchThreeDemo: typeof import('./.vitepress/theme/components/three/GlitchThreeDemo.vue')['default']
1717
HalftoneThreeDemo: typeof import('./.vitepress/theme/components/three/HalftoneThreeDemo.vue')['default']
18+
HueSaturation: typeof import('./.vitepress/theme/components/pmdrs/HueSaturationDemo.vue')['default']
19+
HueSaturationDemo: typeof import('./.vitepress/theme/components/pmdrs/HueSaturationDemo.vue')['default']
1820
LoveVueThreeJS: typeof import('./.vitepress/theme/components/LoveVueThreeJS.vue')['default']
1921
NoiseDemo: typeof import('./.vitepress/theme/components/pmdrs/NoiseDemo.vue')['default']
2022
OutlineDemo: typeof import('./.vitepress/theme/components/pmdrs/OutlineDemo.vue')['default']

docs/guide/pmndrs/hue-saturation.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Hue & Saturation
2+
3+
<DocsDemo>
4+
<HueSaturationDemo />
5+
</DocsDemo>
6+
7+
The `HueSaturation` effect is part of the [`postprocessing`](https://pmndrs.github.io/postprocessing/public/docs/class/src/effects/HueSaturationEffect.js~HueSaturationEffect.html) package. It allows you to adjust the hue and saturation of your scene, providing flexibility for color grading and artistic effects.
8+
9+
## Usage
10+
11+
The `<HueSaturationPmndrs>` component is straightforward to use and provides customizable options to fine-tune the hue and saturation of your visuals.
12+
13+
```vue{2,5-9,26-32}
14+
<script setup lang="ts">
15+
import { EffectComposerPmndrs, HueSaturationPmndrs } from '@tresjs/post-processing'
16+
import { BlendFunction } from 'postprocessing'
17+
18+
const effectProps = {
19+
saturation: 1,
20+
hue: -Math.PI,
21+
blendFunction: BlendFunction.SRC,
22+
}
23+
</script>
24+
25+
<template>
26+
<TresCanvas>
27+
<TresPerspectiveCamera
28+
:position="[5, 5, 5]"
29+
:look-at="[0, 0, 0]"
30+
/>
31+
32+
<OrbitControls auto-rotate />
33+
34+
<TresMesh :position="[0, 1, 0]">
35+
<TresBoxGeometry :args="[2, 2, 2]" />
36+
<TresMeshPhysicalMaterial color="white" />
37+
</TresMesh>
38+
39+
<Suspense>
40+
<EffectComposerPmndrs>
41+
<HueSaturationPmndrs
42+
v-bind="effectProps"
43+
/>
44+
</EffectComposerPmndrs>
45+
</Suspense>
46+
</TresCanvas>
47+
</template>
48+
```
49+
50+
## Props
51+
52+
| Prop | Description | Default |
53+
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
54+
| **saturation** | The saturation adjustment. A value of `0.0` results in grayscale, while `1.0` leaves saturation unchanged. Range: `[0.0, 1.0]`. | `0.0` |
55+
| **hue** | The hue adjustment in radians. Values range from `[-π, π]` (or `[0, 2π]` for a full rotation). | `0.0` |
56+
| **blendFunction** | Defines how the effect blends with the original scene. See the [`BlendFunction`](https://pmndrs.github.io/postprocessing/public/docs/variable/index.html#static-variable-BlendFunction) options. | `BlendFunction.SRC` |
57+
58+
## Further Reading
59+
60+
For more details, see the [HueSaturation documentation](https://pmndrs.github.io/postprocessing/public/docs/class/src/effects/HueSaturationEffect.js~HueSaturationEffect.html).
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<script setup lang="ts">
2+
import { Environment, OrbitControls } from '@tresjs/cientos'
3+
import { TresCanvas } from '@tresjs/core'
4+
import { TresLeches, useControls } from '@tresjs/leches'
5+
import { EffectComposerPmndrs, HueSaturationPmndrs } from '@tresjs/post-processing'
6+
import { BlendFunction } from 'postprocessing'
7+
import { NoToneMapping } from 'three'
8+
9+
import '@tresjs/leches/styles'
10+
11+
const gl = {
12+
toneMapping: NoToneMapping,
13+
multisampling: 8,
14+
}
15+
16+
const { saturation, hue, blendFunction } = useControls({
17+
hue: { value: 0, min: -Math.PI, max: Math.PI, step: 0.001 },
18+
saturation: { value: 0, min: -1, max: 1, step: 0.001 },
19+
blendFunction: {
20+
options: Object.keys(BlendFunction).map(key => ({
21+
text: key,
22+
value: BlendFunction[key],
23+
})),
24+
value: BlendFunction.SRC,
25+
},
26+
})
27+
</script>
28+
29+
<template>
30+
<TresLeches />
31+
32+
<TresCanvas
33+
v-bind="gl"
34+
>
35+
<TresPerspectiveCamera
36+
:position="[5, 5, 5]"
37+
:look-at="[0, 0, 0]"
38+
/>
39+
<OrbitControls auto-rotate />
40+
41+
<TresMesh :position="[0, 1, 0]">
42+
<TresBoxGeometry :args="[2, 2, 2]" />
43+
<TresMeshPhysicalMaterial color="white" :roughness="1" :transmission="0" />
44+
</TresMesh>
45+
46+
<Suspense>
47+
<Environment background :blur=".25" preset="modern" />
48+
</Suspense>
49+
50+
<Suspense>
51+
<EffectComposerPmndrs>
52+
<HueSaturationPmndrs :blendFunction="Number(blendFunction.value)" :hue="hue.value" :saturation="saturation.value" />
53+
</EffectComposerPmndrs>
54+
</Suspense>
55+
</TresCanvas>
56+
</template>

playground/src/router.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export const postProcessingRoutes = [
3535
makeRoute('Outline', '🔲', false),
3636
makeRoute('Glitch', '📺', false),
3737
makeRoute('Depth of Field', '📷', false),
38+
makeRoute('Hue & Saturation', '📷', false),
3839
makeRoute('Pixelation', '👾', false),
3940
makeRoute('Bloom', '🌼', false),
4041
makeRoute('Noise', '📟', false),
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<script lang="ts" setup>
2+
import type { BlendFunction } from 'postprocessing'
3+
import { HueSaturationEffect } from 'postprocessing'
4+
import { makePropWatchers } from '../../util/prop'
5+
import { useEffectPmndrs } from './composables/useEffectPmndrs'
6+
7+
export interface HueSaturationPmndrsProps {
8+
/**
9+
* The saturation adjustment. A value of 0.0 results in grayscale, and 1.0 leaves saturation unchanged.
10+
* Range: [0.0, 1.0]
11+
*/
12+
saturation?: number
13+
14+
/**
15+
* The hue adjustment in radians.
16+
* Range: [-π, π] (or [0, 2π] for a full rotation)
17+
*/
18+
hue?: number
19+
20+
/**
21+
* The blend function. Defines how the effect blends with the original scene.
22+
*/
23+
blendFunction?: BlendFunction
24+
25+
}
26+
27+
const props = withDefaults(
28+
defineProps<HueSaturationPmndrsProps>(),
29+
{
30+
saturation: 0.0,
31+
hue: 0.0,
32+
},
33+
)
34+
35+
const { pass, effect } = useEffectPmndrs(() => new HueSaturationEffect(props), props)
36+
37+
defineExpose({ pass, effect })
38+
39+
makePropWatchers(
40+
[
41+
[() => props.blendFunction, 'blendMode.blendFunction'],
42+
[() => props.hue, 'hue'],
43+
[() => props.saturation, 'saturation'],
44+
],
45+
effect,
46+
() => new HueSaturationEffect(),
47+
)
48+
</script>

src/core/pmndrs/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import NoisePmndrs, { type NoisePmndrsProps } from './NoisePmndrs.vue'
99
import OutlinePmndrs, { type OutlinePmndrsProps } from './OutlinePmndrs.vue'
1010
import PixelationPmndrs, { type PixelationPmndrsProps } from './PixelationPmndrs.vue'
1111
import VignettePmndrs, { type VignettePmndrsProps } from './VignettePmndrs.vue'
12+
import HueSaturationPmndrs, { type HueSaturationPmndrsProps } from './HueSaturationPmndrs.vue'
1213
import ScanlinePmndrs, { type ScanlinePmndrsProps } from './ScanlinePmndrs.vue'
1314

1415
export {
@@ -21,8 +22,8 @@ export {
2122
PixelationPmndrs,
2223
useEffectPmndrs,
2324
VignettePmndrs,
25+
HueSaturationPmndrs,
2426
ScanlinePmndrs,
25-
2627
BloomPmndrsProps,
2728
DepthOfFieldPmndrsProps,
2829
EffectComposerPmndrsProps,
@@ -31,5 +32,6 @@ export {
3132
OutlinePmndrsProps,
3233
PixelationPmndrsProps,
3334
VignettePmndrsProps,
35+
HueSaturationPmndrsProps,
3436
ScanlinePmndrsProps,
3537
}

0 commit comments

Comments
 (0)