Perspective

원근 변형

A flat image tilts in 3D, with perspective changing the apparent size of its near and far sides.

Also known as: PerspectivePerspective warp

Moves in browsers that support WebGPU

This device could not render the demo — showing a still

React
// Renders only in browsers with WebGPU.
// /samples/… are this site’s sample files — point them at your own image or video.
import { Shader, ImageTexture, Perspective } from 'shaders/react'

export default function ShaderEffect() {
  return (
    <Shader style={{ width: '100%', height: 320 }} disableTelemetry>
      <ImageTexture
        objectFit="cover"
        url="/samples/poster.jpg" />
      <Perspective
        pan={{
          type: "auto-animate",
          mode: "ping-pong",
          outputMin: -30,
          outputMax: 30,
          speed: 0.4
        }}
        tilt={15} />
    </Shader>
  )
}
Vue
<!-- Renders only in browsers with WebGPU. -->
<!-- /samples/… are this site’s sample files — point them at your own image or video. -->
<script setup lang="ts">
import { Shader, ImageTexture, Perspective } from 'shaders/vue'
</script>

<template>
  <Shader style="width: 100%; height: 320px" :disable-telemetry="true">
    <ImageTexture
      object-fit="cover"
      url="/samples/poster.jpg"/>
    <Perspective
      :pan="{
        type: 'auto-animate',
        mode: 'ping-pong',
        outputMin: -30,
        outputMax: 30,
        speed: 0.4
      }"
      :tilt="15"/>
  </Shader>
</template>
Svelte
<!-- Renders only in browsers with WebGPU. -->
<!-- /samples/… are this site’s sample files — point them at your own image or video. -->
<script>
  import { Shader, ImageTexture, Perspective } from 'shaders/svelte'
</script>

<Shader style="width: 100%; height: 320px" disableTelemetry>
  <ImageTexture
    objectFit="cover"
    url="/samples/poster.jpg" />
  <Perspective
    pan={{
      type: "auto-animate",
      mode: "ping-pong",
      outputMin: -30,
      outputMax: 30,
      speed: 0.4
    }}
    tilt={15} />
</Shader>
Solid
// Renders only in browsers with WebGPU.
// /samples/… are this site’s sample files — point them at your own image or video.
import { Shader, ImageTexture, Perspective } from 'shaders/solid'

export default function ShaderEffect() {
  return (
    <Shader style={{ width: '100%', height: '320px' }} disableTelemetry>
      <ImageTexture
        objectFit="cover"
        url="/samples/poster.jpg" />
      <Perspective
        pan={{
          type: "auto-animate",
          mode: "ping-pong",
          outputMin: -30,
          outputMax: 30,
          speed: 0.4
        }}
        tilt={15} />
    </Shader>
  )
}
JavaScript
// Renders only in browsers with WebGPU.
// /samples/… are this site’s sample files — point them at your own image or video.
// expects <canvas id="canvas" style="width:100%;height:320px"></canvas> on the page
import { createShader } from 'shaders/js'

const shader = await createShader(document.getElementById("canvas"), {
  components: [
    {
      type: 'ImageTexture',
      props: {
        objectFit: 'cover',
        url: '/samples/poster.jpg',
      },
    },
    {
      type: 'Perspective',
      props: {
        pan: {
          type: 'auto-animate',
          mode: 'ping-pong',
          outputMin: -30,
          outputMax: 30,
          speed: 0.4
        },
        tilt: 15,
      },
    }
  ]
}, { disableTelemetry: true })

Props · Perspective

Changes apply to the demo above and to the code tabs. Descriptions come from the library registry (MIT).

NameValueDefaultRange / optionsDescription
centerCenter
x0.5y0.5
{"x":0.5,"y":0.5}x, y: 0 – 1Center point of rotation
panPanAuto-animated in the demo — moving it pins the value0-90 – 90 (step 0.1)Horizontal rotation (left/right)
tiltTilt0-90 – 90 (step 0.1)Vertical rotation (up/down)
fovFOV6030 – 120 (step 1)Field of view - controls perspective intensity
zoomZoom10.5 – 3 (step 0.1)Zoom in to fill the frame after rotation
offsetOffset
x0.5y0.5
{"x":0.5,"y":0.5}x, y: 0 – 1Shift the result in X/Y
edgesEdgestransparentstretch · transparent · mirror · wrapHow to handle edges

Every component also takes blendMode · opacity · visible · maskSource/maskType · boundingBox · id

Like lifting a photo from a desk and viewing it at an angle, the flat input tilts so its near and far sides appear different in size.

`pan` sets the left-to-right rotation and `tilt` sets the up-and-down rotation. Increase `fov` for stronger perspective and use `zoom` to fill the frame after rotation; `center` changes the pivot point.

Place it above an image layer. Pair it with `CornerPin` when individual corners need further adjustment. Strong tilts distort text and may expose empty edges, so check the `edges` setting.

When to use

Use it for tilted card or poster mockups, perspective hero images, and short panel transitions. Avoid it when small copy must stay readable or alignment must remain flat.

Open as page ↗