커스텀 셰이더

Custom shader

기본 컴포넌트로 표현하기 어려운 픽셀 효과를 `defineShader`로 직접 정의합니다.

다른 이름: Custom componentShader authoring

WebGPU 를 지원하는 브라우저에서 움직입니다

이 기기에서는 데모를 그리지 못해 정지 화면을 보여 줍니다

React
// WebGPU 를 지원하는 브라우저에서만 그립니다.
import { Shader, Circle, Ring } from 'shaders/react'

export default function ShaderEffect() {
  return (
    <Shader style={{ width: '100%', height: 320 }} disableTelemetry>
      <Circle
        color="#fbbf24"
        radius={0.19}
        softness={0.2} />
      <Ring
        color="#22d3ee"
        radius={0.34}
        softness={0.06}
        thickness={0.035} />
      <Ring
        color="#a855f7"
        radius={0.44}
        softness={0.12}
        thickness={0.012} />
    </Shader>
  )
}
Vue
<!-- WebGPU 를 지원하는 브라우저에서만 그립니다. -->
<script setup lang="ts">
import { Shader, Circle, Ring } from 'shaders/vue'
</script>

<template>
  <Shader style="width: 100%; height: 320px" :disable-telemetry="true">
    <Circle
      color="#fbbf24"
      :radius="0.19"
      :softness="0.2"/>
    <Ring
      color="#22d3ee"
      :radius="0.34"
      :softness="0.06"
      :thickness="0.035"/>
    <Ring
      color="#a855f7"
      :radius="0.44"
      :softness="0.12"
      :thickness="0.012"/>
  </Shader>
</template>
Svelte
<!-- WebGPU 를 지원하는 브라우저에서만 그립니다. -->
<script>
  import { Shader, Circle, Ring } from 'shaders/svelte'
</script>

<Shader style="width: 100%; height: 320px" disableTelemetry>
  <Circle
    color="#fbbf24"
    radius={0.19}
    softness={0.2} />
  <Ring
    color="#22d3ee"
    radius={0.34}
    softness={0.06}
    thickness={0.035} />
  <Ring
    color="#a855f7"
    radius={0.44}
    softness={0.12}
    thickness={0.012} />
</Shader>
Solid
// WebGPU 를 지원하는 브라우저에서만 그립니다.
import { Shader, Circle, Ring } from 'shaders/solid'

export default function ShaderEffect() {
  return (
    <Shader style={{ width: '100%', height: '320px' }} disableTelemetry>
      <Circle
        color="#fbbf24"
        radius={0.19}
        softness={0.2} />
      <Ring
        color="#22d3ee"
        radius={0.34}
        softness={0.06}
        thickness={0.035} />
      <Ring
        color="#a855f7"
        radius={0.44}
        softness={0.12}
        thickness={0.012} />
    </Shader>
  )
}
JavaScript
// WebGPU 를 지원하는 브라우저에서만 그립니다.
// <canvas id="canvas" style="width:100%;height:320px"></canvas> 가 페이지에 있어야 한다
import { createShader } from 'shaders/js'

const shader = await createShader(document.getElementById("canvas"), {
  components: [
    {
      type: 'Circle',
      props: {
        color: '#fbbf24',
        radius: 0.19,
        softness: 0.2,
      },
    },
    {
      type: 'Ring',
      props: {
        color: '#22d3ee',
        radius: 0.34,
        softness: 0.06,
        thickness: 0.035,
      },
    },
    {
      type: 'Ring',
      props: {
        color: '#a855f7',
        radius: 0.44,
        softness: 0.12,
        thickness: 0.012,
      },
    }
  ]
}, { disableTelemetry: true })

속성(props) · Circle

값을 바꾸면 위 데모와 코드 탭에 바로 반영됩니다. 설명은 라이브러리 레지스트리의 영어 원문(MIT)입니다.

이름값기본값범위·선택지설명(원문)
originOrigin코드에서 지정center—Reference edge the center position is measured from (center default). Lets you pin the shape relative to a corner or the canvas centre.
colorColor#ffffff—The color of the circle
radiusRadius10 – 2 (step 0.01)The radius of the circle. A value of one (1) is sets the circle to fit the canvas.
softnessSoftness00 – 1 (step 0.01)Edge softness. Lower values like zero (0) are sharp, higher values like one (1) are softer.
centerCenter Position
x0.5y0.5
{"x":0.5,"y":0.5}x, y: 0 – 1The center point of the circle
strokeThicknessStroke Thickness00 – 0.5 (step 0.01)The thickness of the stroke outline. Zero (0) means no stroke.
strokeColorStroke Color#000000—The color of the stroke outline
strokePositionStroke Positioncenteroutside · center · insidePosition of the stroke relative to the circle edge
colorSpaceColor Blendinglinearlinear · oklch · oklab · hsl · hsv · lchColor space for blending fill and stroke colors in soft edges

모든 컴포넌트 공통: blendMode · opacity · visible · maskSource/maskType · boundingBox · id

커스텀 셰이더는 라이브러리의 기본 재료만으로 만들기 어려운 모양이나 반응을 직접 그리는 방법입니다. 기성 도형으로는 만들 수 없는 후광을 위해 나만의 물감 혼합법을 추가하는 것과 같습니다.

업스트림 README의 `Halo` 예제처럼 `defineShader`에 `name`, 기본값과 변환 함수를 가진 `props`, 픽셀을 그리는 `paint`를 넘깁니다. 예제는 `wgsl` 안에서 중심과 반지름으로 픽셀 거리를 계산하고, `<CustomShader src={Halo}>`로 장면에 넣습니다.

이 데모는 번들에 이미 포함된 `Circle`과 `Ring`을 조합해 후광의 결과를 보여 줍니다. 전용 코드는 WGSL과 셰이더 입력을 이해하고 유지해야 하므로, 먼저 기본 컴포넌트 조합으로 표현할 수 있는지 확인하세요.

언제 쓰나

고유한 픽셀 계산이 필요한 브랜드 효과, 기존 컴포넌트 조합으로 표현되지 않는 패턴, 반복 재사용할 셰이더 구성 요소를 만들 때 유용합니다. 기본 효과의 색·크기 조절로 해결되거나 GPU 코드 유지보수 여력이 없으면 직접 작성하지 마세요.

페이지로 열기 ↗