Skip to content

Commit

Permalink
feat: add hue & saturation (#151)
Browse files Browse the repository at this point in the history
* 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]>
  • Loading branch information
damienmontastier and alvarosabu authored Jan 4, 2025
1 parent f3da309 commit f5a699f
Show file tree
Hide file tree
Showing 8 changed files with 228 additions and 1 deletion.
1 change: 1 addition & 0 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export default defineConfig({
{ text: 'Scanline', link: '/guide/pmndrs/scanline' },
{ text: 'Pixelation', link: '/guide/pmndrs/pixelation' },
{ text: 'Vignette', link: '/guide/pmndrs/vignette' },
{ text: 'Hue & Saturation', link: '/guide/pmndrs/hue-saturation' },
],
},
{
Expand Down
57 changes: 57 additions & 0 deletions docs/.vitepress/theme/components/pmdrs/HueSaturationDemo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<script setup lang="ts">
import { Environment, OrbitControls } from '@tresjs/cientos'
import { TresCanvas } from '@tresjs/core'
import { TresLeches, useControls } from '@tresjs/leches'
import { EffectComposerPmndrs, HueSaturationPmndrs } from '@tresjs/post-processing'
import { BlendFunction } from 'postprocessing'
import { NoToneMapping } from 'three'
import '@tresjs/leches/styles'
const gl = {
toneMapping: NoToneMapping,
multisampling: 8,
}
const { saturation, hue, blendFunction } = useControls({
hue: { value: -Math.PI, min: -Math.PI, max: Math.PI, step: 0.001 },
saturation: { value: 1, min: -1, max: 1, step: 0.001 },
blendFunction: {
options: Object.keys(BlendFunction).map(key => ({
text: key,
value: BlendFunction[key],
})),
value: BlendFunction.SRC,
},
})
</script>

<template>
<TresLeches style="left: initial;right:10px; top:10px;" />

<TresCanvas
v-bind="gl"
>
<TresPerspectiveCamera
:position="[5, 5, 5]"
:look-at="[0, 0, 0]"
/>
<OrbitControls auto-rotate />

<TresMesh :position="[0, 1, 0]">
<TresBoxGeometry :args="[2, 2, 2]" />
<TresMeshPhysicalMaterial color="white" />
</TresMesh>

<Suspense>
<Environment background :blur=".25" preset="modern" />
</Suspense>

<Suspense>
<EffectComposerPmndrs>
<HueSaturationPmndrs :blendFunction="Number(blendFunction.value)" :hue="hue.value" :saturation="saturation.value" />
</EffectComposerPmndrs>
</Suspense>
</TresCanvas>
</template>
2 changes: 2 additions & 0 deletions docs/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ declare module 'vue' {
GlitchDemo: typeof import('./.vitepress/theme/components/pmdrs/GlitchDemo.vue')['default']
GlitchThreeDemo: typeof import('./.vitepress/theme/components/three/GlitchThreeDemo.vue')['default']
HalftoneThreeDemo: typeof import('./.vitepress/theme/components/three/HalftoneThreeDemo.vue')['default']
HueSaturation: typeof import('./.vitepress/theme/components/pmdrs/HueSaturationDemo.vue')['default']
HueSaturationDemo: typeof import('./.vitepress/theme/components/pmdrs/HueSaturationDemo.vue')['default']
LoveVueThreeJS: typeof import('./.vitepress/theme/components/LoveVueThreeJS.vue')['default']
NoiseDemo: typeof import('./.vitepress/theme/components/pmdrs/NoiseDemo.vue')['default']
OutlineDemo: typeof import('./.vitepress/theme/components/pmdrs/OutlineDemo.vue')['default']
Expand Down
60 changes: 60 additions & 0 deletions docs/guide/pmndrs/hue-saturation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Hue & Saturation

<DocsDemo>
<HueSaturationDemo />
</DocsDemo>

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.

## Usage

The `<HueSaturationPmndrs>` component is straightforward to use and provides customizable options to fine-tune the hue and saturation of your visuals.

```vue{2,5-9,26-32}
<script setup lang="ts">
import { EffectComposerPmndrs, HueSaturationPmndrs } from '@tresjs/post-processing'
import { BlendFunction } from 'postprocessing'
const effectProps = {
saturation: 1,
hue: -Math.PI,
blendFunction: BlendFunction.SRC,
}
</script>
<template>
<TresCanvas>
<TresPerspectiveCamera
:position="[5, 5, 5]"
:look-at="[0, 0, 0]"
/>
<OrbitControls auto-rotate />
<TresMesh :position="[0, 1, 0]">
<TresBoxGeometry :args="[2, 2, 2]" />
<TresMeshPhysicalMaterial color="white" />
</TresMesh>
<Suspense>
<EffectComposerPmndrs>
<HueSaturationPmndrs
v-bind="effectProps"
/>
</EffectComposerPmndrs>
</Suspense>
</TresCanvas>
</template>
```

## Props

| Prop | Description | Default |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
| **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` |
| **hue** | The hue adjustment in radians. Values range from `[-π, π]` (or `[0, 2π]` for a full rotation). | `0.0` |
| **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` |

## Further Reading

For more details, see the [HueSaturation documentation](https://pmndrs.github.io/postprocessing/public/docs/class/src/effects/HueSaturationEffect.js~HueSaturationEffect.html).
56 changes: 56 additions & 0 deletions playground/src/pages/postprocessing/hue-saturation.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<script setup lang="ts">
import { Environment, OrbitControls } from '@tresjs/cientos'
import { TresCanvas } from '@tresjs/core'
import { TresLeches, useControls } from '@tresjs/leches'
import { EffectComposerPmndrs, HueSaturationPmndrs } from '@tresjs/post-processing'
import { BlendFunction } from 'postprocessing'
import { NoToneMapping } from 'three'
import '@tresjs/leches/styles'
const gl = {
toneMapping: NoToneMapping,
multisampling: 8,
}
const { saturation, hue, blendFunction } = useControls({
hue: { value: 0, min: -Math.PI, max: Math.PI, step: 0.001 },
saturation: { value: 0, min: -1, max: 1, step: 0.001 },
blendFunction: {
options: Object.keys(BlendFunction).map(key => ({
text: key,
value: BlendFunction[key],
})),
value: BlendFunction.SRC,
},
})
</script>

<template>
<TresLeches />

<TresCanvas
v-bind="gl"
>
<TresPerspectiveCamera
:position="[5, 5, 5]"
:look-at="[0, 0, 0]"
/>
<OrbitControls auto-rotate />

<TresMesh :position="[0, 1, 0]">
<TresBoxGeometry :args="[2, 2, 2]" />
<TresMeshPhysicalMaterial color="white" :roughness="1" :transmission="0" />
</TresMesh>

<Suspense>
<Environment background :blur=".25" preset="modern" />
</Suspense>

<Suspense>
<EffectComposerPmndrs>
<HueSaturationPmndrs :blendFunction="Number(blendFunction.value)" :hue="hue.value" :saturation="saturation.value" />
</EffectComposerPmndrs>
</Suspense>
</TresCanvas>
</template>
1 change: 1 addition & 0 deletions playground/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export const postProcessingRoutes = [
makeRoute('Outline', '🔲', false),
makeRoute('Glitch', '📺', false),
makeRoute('Depth of Field', '📷', false),
makeRoute('Hue & Saturation', '📷', false),
makeRoute('Pixelation', '👾', false),
makeRoute('Bloom', '🌼', false),
makeRoute('Noise', '📟', false),
Expand Down
48 changes: 48 additions & 0 deletions src/core/pmndrs/HueSaturationPmndrs.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<script lang="ts" setup>
import type { BlendFunction } from 'postprocessing'
import { HueSaturationEffect } from 'postprocessing'
import { makePropWatchers } from '../../util/prop'
import { useEffectPmndrs } from './composables/useEffectPmndrs'
export interface HueSaturationPmndrsProps {
/**
* The saturation adjustment. A value of 0.0 results in grayscale, and 1.0 leaves saturation unchanged.
* Range: [0.0, 1.0]
*/
saturation?: number
/**
* The hue adjustment in radians.
* Range: [-π, π] (or [0, 2π] for a full rotation)
*/
hue?: number
/**
* The blend function. Defines how the effect blends with the original scene.
*/
blendFunction?: BlendFunction
}
const props = withDefaults(
defineProps<HueSaturationPmndrsProps>(),
{
saturation: 0.0,
hue: 0.0,
},
)
const { pass, effect } = useEffectPmndrs(() => new HueSaturationEffect(props), props)
defineExpose({ pass, effect })
makePropWatchers(
[
[() => props.blendFunction, 'blendMode.blendFunction'],
[() => props.hue, 'hue'],
[() => props.saturation, 'saturation'],
],
effect,
() => new HueSaturationEffect(),
)
</script>
4 changes: 3 additions & 1 deletion src/core/pmndrs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import NoisePmndrs, { type NoisePmndrsProps } from './NoisePmndrs.vue'
import OutlinePmndrs, { type OutlinePmndrsProps } from './OutlinePmndrs.vue'
import PixelationPmndrs, { type PixelationPmndrsProps } from './PixelationPmndrs.vue'
import VignettePmndrs, { type VignettePmndrsProps } from './VignettePmndrs.vue'
import HueSaturationPmndrs, { type HueSaturationPmndrsProps } from './HueSaturationPmndrs.vue'
import ScanlinePmndrs, { type ScanlinePmndrsProps } from './ScanlinePmndrs.vue'

export {
Expand All @@ -21,8 +22,8 @@ export {
PixelationPmndrs,
useEffectPmndrs,
VignettePmndrs,
HueSaturationPmndrs,
ScanlinePmndrs,

BloomPmndrsProps,
DepthOfFieldPmndrsProps,
EffectComposerPmndrsProps,
Expand All @@ -31,5 +32,6 @@ export {
OutlinePmndrsProps,
PixelationPmndrsProps,
VignettePmndrsProps,
HueSaturationPmndrsProps,
ScanlinePmndrsProps,
}

0 comments on commit f5a699f

Please sign in to comment.