Skip to content

Commit

Permalink
feat: lens distortion effect (#162)
Browse files Browse the repository at this point in the history
* add lens distortion with doc

* update code, props, doc

---------

Co-authored-by: Tino Koch <17991193+Tinoooo@users.noreply.github.com>
  • Loading branch information
damienmontastier and Tinoooo authored Jan 12, 2025
1 parent 6fa0e3c commit 0ee8267
Show file tree
Hide file tree
Showing 10 changed files with 269 additions and 8 deletions.
17 changes: 9 additions & 8 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,22 +48,23 @@ export default defineConfig({
{
text: 'Pmndrs',
items: [
{ text: 'Barrel blur', link: '/guide/pmndrs/barrel-blur' },
{ text: 'Bloom', link: '/guide/pmndrs/bloom' },
{ text: 'Chromatic Aberration', link: '/guide/pmndrs/chromatic-aberration' },
{ text: 'Depth of Field', link: '/guide/pmndrs/depth-of-field' },
{ text: 'Dot Screen', link: '/guide/pmndrs/dot-screen' },
{ text: 'Glitch', link: '/guide/pmndrs/glitch' },
{ text: 'Hue & Saturation', link: '/guide/pmndrs/hue-saturation' },
{ text: 'Lens Distortion', link: '/guide/pmndrs/lens-distortion' },
{ text: 'Noise', link: '/guide/pmndrs/noise' },
{ text: 'Outline', link: '/guide/pmndrs/outline' },
{ text: 'Tone Mapping', link: '/guide/pmndrs/tone-mapping' },
{ text: 'Chromatic Aberration', link: '/guide/pmndrs/chromatic-aberration' },
{ text: 'Sepia', link: '/guide/pmndrs/sepia' },
{ text: 'Pixelation', link: '/guide/pmndrs/pixelation' },
{ text: 'Scanline', link: '/guide/pmndrs/scanline' },
{ text: 'Sepia', link: '/guide/pmndrs/sepia' },
{ text: 'Shock Wave', link: '/guide/pmndrs/shock-wave' },
{ text: 'Pixelation', link: '/guide/pmndrs/pixelation' },
{ text: 'Vignette', link: '/guide/pmndrs/vignette' },
{ text: 'Barrel blur', link: '/guide/pmndrs/barrel-blur' },
{ text: 'Hue & Saturation', link: '/guide/pmndrs/hue-saturation' },
{ text: 'Tilt Shift', link: '/guide/pmndrs/tilt-shift' },
{ text: 'Dot Screen', link: '/guide/pmndrs/dot-screen' },
{ text: 'Tone Mapping', link: '/guide/pmndrs/tone-mapping' },
{ text: 'Vignette', link: '/guide/pmndrs/vignette' },
],
},
{
Expand Down
68 changes: 68 additions & 0 deletions docs/.vitepress/theme/components/pmdrs/LensDistortionDemo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<script setup lang="ts">
import { Environment, OrbitControls } from '@tresjs/cientos'
import { TresCanvas, useTexture } from '@tresjs/core'
import { TresLeches, useControls } from '@tresjs/leches'
import { EffectComposerPmndrs, LensDistortionPmndrs } from '@tresjs/post-processing'
import { BackSide, NoToneMapping, SRGBColorSpace, Vector2 } from 'three'
import '@tresjs/leches/styles'
const gl = {
toneMapping: NoToneMapping,
multisampling: 8,
}
const { distortion, principalPoint, focalLength, skew } = useControls({
distortion: { value: new Vector2(0.5, 0.5), min: 0, max: 1, step: 0.001 },
principalPoint: { value: new Vector2(0.0, 0.0), min: 0, max: 1, step: 0.001 },
focalLength: { value: new Vector2(0.5, 0.5), min: 0, max: 2, step: 0.001 },
skew: { value: 0, min: -1, max: 1, step: 0.001 },
})
const pbrTexture = await useTexture({
map: '/lens-distortion/room-map.png',
normalMap: '/lens-distortion/room-normal.png',
})
pbrTexture.map.colorSpace = SRGBColorSpace
</script>

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

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

<TresMesh :position="[0, 2, 0]">
<TresBoxGeometry :args="[8, 8, 8]" />
<TresMeshStandardMaterial :side="BackSide" :map="pbrTexture.map" :normal-map="pbrTexture.normalMap" />
</TresMesh>

<TresMesh :position="[0, 0, 0]">
<TresBoxGeometry :args="[1.65, 1.65, 1.65]" />
<TresMeshNormalMaterial />
</TresMesh>

<TresAmbientLight :intensity="2" />

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

<Suspense>
<EffectComposerPmndrs>
<LensDistortionPmndrs
:distortion="distortion.value"
:principalPoint="principalPoint.value"
:focalLength="focalLength.value"
:skew="skew.value"
/>
</EffectComposerPmndrs>
</Suspense>
</TresCanvas>
</template>
1 change: 1 addition & 0 deletions docs/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ declare module 'vue' {
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']
LensDistortionDemo: typeof import('./.vitepress/theme/components/pmdrs/LensDistortionDemo.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
85 changes: 85 additions & 0 deletions docs/guide/pmndrs/lens-distortion.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Lens Distortion

<DocsDemo>
<LensDistortionDemo />
</DocsDemo>

The `LensDistortion` effect is part of the [`postprocessing`](https://pmndrs.github.io/postprocessing/public/docs/class/src/effects/LensDistortionEffect.js~LensDistortionEffect.html) package. It allows you to apply a lens distortion effect to your scene, providing flexibility for creating realistic camera effects.

## Usage

The `<LensDistortionPmndrs>` component is straightforward to use and provides customizable options to fine-tune the distortion effect of your visuals.

```vue{3,12-17,52-56}
<script setup lang="ts">
import { Vector2 } from 'three'
import { EffectComposerPmndrs, LensDistortionPmndrs } from '@tresjs/post-processing'
import { Environment, OrbitControls } from '@tresjs/cientos'
import { TresCanvas, useTexture } from '@tresjs/core'
const gl = {
toneMapping: NoToneMapping,
multisampling: 8,
}
const effectProps = {
distortion: new Vector2(0.5, 0.5),
principalPoint: new Vector2(0.0, 0.0),
focalLength: new Vector2(0.5, 0.5),
skew: 0,
}
const pbrTexture = await useTexture({
map: '/lens-distortion/room-map.png',
normalMap: '/lens-distortion/room-normal.png',
})
pbrTexture.map.colorSpace = SRGBColorSpace
</script>
<template>
<TresCanvas
v-bind="gl"
>
<TresPerspectiveCamera
:position="[-2, 1, 5]"
/>
<OrbitControls auto-rotate />
<TresMesh :position="[0, 2, 0]">
<TresBoxGeometry :args="[8, 8, 8]" />
<TresMeshStandardMaterial :side="BackSide" :map="pbrTexture.map" :normal-map="pbrTexture.normalMap" />
</TresMesh>
<TresMesh :position="[0, 0, 0]">
<TresBoxGeometry :args="[1.65, 1.65, 1.65]" />
<TresMeshNormalMaterial />
</TresMesh>
<TresAmbientLight :intensity="2" />
<Suspense>
<Environment background :blur=".25" preset="snow" />
</Suspense>
<Suspense>
<EffectComposerPmndrs>
<LensDistortionPmndrs v-bind="effectProps" />
</EffectComposerPmndrs>
</Suspense>
</TresCanvas>
</template>
```

## Props

| Prop | Description | Default |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
| **distortion** | The distortion effect strength. <br> Accepts `Vector2` or `[number, number]`. | `[0.0, 0.0]` |
| **principalPoint** | The center point. <br> Accepts `Vector2` or `[number, number]`. | `[0.0, 0.0]` |
| **focalLength** | The focal length. <br> Accepts `Vector2` or `[number, number]`. | `[1.0, 1.0]` |
| **skew** | The skew value. | `0` |

## Further Reading

For more details, see the [LensDistortion documentation](https://pmndrs.github.io/postprocessing/public/docs/class/src/effects/LensDistortionEffect.js~LensDistortionEffect.html).
Binary file added docs/public/lens-distortion/room-map.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/lens-distortion/room-normal.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
54 changes: 54 additions & 0 deletions playground/src/pages/postprocessing/lens-distortion.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<script setup lang="ts">
import { Environment, OrbitControls } from '@tresjs/cientos'
import { TresCanvas } from '@tresjs/core'
import { TresLeches, useControls } from '@tresjs/leches'
import { EffectComposerPmndrs, LensDistortionPmndrs } from '@tresjs/post-processing'
import { NoToneMapping, Vector2 } from 'three'
import '@tresjs/leches/styles'
const gl = {
toneMapping: NoToneMapping,
multisampling: 8,
}
const { distortion, principalPoint, focalLength, skew } = useControls({
distortion: { value: new Vector2(0.5, 0.5), min: -1, max: 1, step: 0.001 },
principalPoint: { value: new Vector2(0.0, 0.0), min: -0.5, max: 0.5, step: 0.001 },
focalLength: { value: new Vector2(0.5, 0.5), min: -1, max: 1, step: 0.001 },
skew: { value: 0, min: -1, max: 1, step: 0.001 },
})
</script>

<template>
<TresLeches />

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

<TresMesh :position="[0, 1, 0]">
<TresBoxGeometry :args="[2, 2, 2]" />
<TresMeshPhysicalMaterial color="#0f0f0f" :roughness=".5" />
</TresMesh>

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

<Suspense>
<EffectComposerPmndrs>
<LensDistortionPmndrs
:distortion="distortion.value"
:principalPoint="principalPoint.value"
:focalLength="focalLength.value"
:skew="skew.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 @@ -43,6 +43,7 @@ export const postProcessingRoutes = [
makeRoute('Bloom', '🌼', false),
makeRoute('Noise', '📟', false),
makeRoute('Chromatic Aberration', '🌈', false),
makeRoute('Lens Distortion', '🔍', false),
makeRoute('Sepia', '🌅', false),
makeRoute('Scanline', '📺', false),
makeRoute('Shock Wave', '🌊', false),
Expand Down
48 changes: 48 additions & 0 deletions src/core/pmndrs/LensDistortionPmndrs.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<script lang="ts" setup>
import { LensDistortionEffect } from 'postprocessing'
import { makePropWatchersUsingAllProps } from '../../util/prop'
import { useEffectPmndrs } from './composables/useEffectPmndrs'
import { Vector2 } from 'three'
export interface LensDistortionPmndrsProps {
/**
* The distortion effect strength.
*/
distortion?: Vector2 | [number, number]
/**
* The center point.
*/
principalPoint?: Vector2 | [number, number]
/**
* The focal length.
*/
focalLength?: Vector2 | [number, number]
/**
* The skew value.
*/
skew?: number
}
const props = defineProps<LensDistortionPmndrsProps>()
const { pass, effect } = useEffectPmndrs(
() => new LensDistortionEffect({
...props,
distortion: props.distortion ? (Array.isArray(props.distortion) ? new Vector2(...props.distortion) : props.distortion) : new Vector2(),
principalPoint: props.principalPoint ? (Array.isArray(props.principalPoint) ? new Vector2(...props.principalPoint) : props.principalPoint) : new Vector2(),
focalLength: props.focalLength ? (Array.isArray(props.focalLength) ? new Vector2(...props.focalLength) : props.focalLength) : new Vector2(),
}),
props,
)
defineExpose({ pass, effect })
makePropWatchersUsingAllProps(
props,
effect,
() => new LensDistortionEffect(),
)
</script>
3 changes: 3 additions & 0 deletions src/core/pmndrs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import ToneMappingPmndrs, { type ToneMappingPmndrsProps } from './ToneMappingPmn
import ChromaticAberrationPmndrs, { type ChromaticAberrationPmndrsProps } from './ChromaticAberrationPmndrs.vue'
import HueSaturationPmndrs, { type HueSaturationPmndrsProps } from './HueSaturationPmndrs.vue'
import ScanlinePmndrs, { type ScanlinePmndrsProps } from './ScanlinePmndrs.vue'
import LensDistortionPmndrs, { type LensDistortionPmndrsProps } from './LensDistortionPmndrs.vue'
import ShockWavePmndrs, { type ShockWavePmndrsProps } from './ShockWavePmndrs.vue'
import DepthPickingPassPmndrs, { type DepthPickingPassPmndrsProps } from './DepthPickingPassPmndrs.vue'
import TiltShiftPmndrs, { type TiltShiftPmndrsProps } from './TiltShiftPmndrs.vue'
Expand All @@ -37,6 +38,7 @@ export {
ChromaticAberrationPmndrs,
HueSaturationPmndrs,
ScanlinePmndrs,
LensDistortionPmndrs,
ShockWavePmndrs,
DepthPickingPassPmndrs,
TiltShiftPmndrs,
Expand All @@ -56,6 +58,7 @@ export {
ChromaticAberrationPmndrsProps,
HueSaturationPmndrsProps,
ScanlinePmndrsProps,
LensDistortionPmndrsProps,
ShockWavePmndrsProps,
DepthPickingPassPmndrsProps,
TiltShiftPmndrsProps,
Expand Down

0 comments on commit 0ee8267

Please sign in to comment.