맞춤 필터 (CSS 셰이더라고도 함) 소개

맞춤 필터(이전 명칭: CSS 셰이더)를 사용하면 DOM 콘텐츠에서 WebGL 셰이더의 성능을 활용할 수 있습니다. 현재 구현에서 사용되는 셰이더는 WebGL의 셰이더와 거의 동일하므로 잠시 멈추고 몇 가지 3D 용어와 그래픽 파이프라인을 이해해야 합니다.

최근 LondonJS에 전달한 프레젠테이션의 녹화 버전을 포함했습니다. 이 동영상에서는 이해해야 하는 3D 용어에 대한 개요, 사용하게 될 다양한 변수 유형, 지금 바로 맞춤 필터를 사용해 볼 수 있는 방법을 설명합니다. 데모를 직접 실행할 수 있도록 슬라이드를 가져와야 합니다.

셰이더 소개

이전에 셰이더 소개를 작성하여 셰이더의 정의와 WebGL 관점에서 셰이더를 사용하는 방법을 자세히 설명했습니다. 셰이더를 다뤄 본 적이 없다면 더 나아가기 전에 셰이더에 관해 읽어봐야 합니다. 맞춤 필터의 많은 개념과 언어는 기존 WebGL 셰이더 용어에 의존하기 때문입니다.

이제 맞춤 필터를 사용 설정하고 계속 진행해 보겠습니다.

맞춤 필터 사용 설정

맞춤 필터는 Chrome, Canary, Android용 Chrome에서 모두 사용할 수 있습니다. about:flags로 이동하여 'CSS 셰이더'를 검색한 후 사용 설정하고 브라우저를 다시 시작하면 됩니다. 이제 준비가 끝났습니다.

문법

맞춤 필터는 이미 DOM 요소에 적용할 수 있는 필터 집합(예: blur 또는 sepia)을 확장합니다. 에릭 비델만은 이를 위한 멋진 플레이그라운드 도구를 작성했으니 확인해 보세요.

DOM 요소에 맞춤 필터를 적용하려면 다음 문법을 사용합니다.

.customShader {
    -webkit-filter:

    custom(
        url(vertexshader.vert)
        mix(url(fragment.frag) normal source-atop),

    /* Row, columns - the vertices are made automatically */
    4 5,

    /* We set uniforms; we can't set attributes */
    time 0)
}

여기에서 정점 및 프래그먼트 셰이더, DOM 요소를 분할하려는 행 및 열의 수, 전달하려는 모든 유니폼을 선언합니다.

마지막으로 언급할 사항은 프래그먼트 셰이더 주변에서 혼합 모드 (normal) 및 합성 모드 (source-atop)로 mix() 함수를 사용한다는 점입니다. mix() 함수가 필요한 이유를 알아보려면 프래그먼트 셰이더 자체를 살펴보겠습니다.

픽셀 푸시

WebGL의 셰이더에 익숙하다면 맞춤 필터에서 약간 다른 점이 있음을 알 수 있습니다. 하나는 프래그먼트 셰이더가 픽셀을 채우는 데 사용하는 텍스처를 만들지 않는다는 점입니다. 대신 필터가 적용된 DOM 콘텐츠가 자동으로 텍스처에 매핑됩니다. 이는 다음 두 가지를 의미합니다.

  1. 보안상의 이유로 DOM 텍스처의 개별 픽셀 색상 값을 쿼리할 수 없습니다.
  2. 최소한 현재 구현에서는 최종 픽셀 색상을 직접 설정하지 않습니다. 즉, gl_FragColor는 허용되지 않습니다. 대신 DOM 콘텐츠를 렌더링하려고 한다고 가정하고 css_ColorMatrixcss_MixColor를 통해 픽셀을 간접적으로 조작합니다.

즉, 프래그먼트 셰이더의 Hello World는 다음과 같이 표시됩니다.

void main() {
    css_ColorMatrix = mat4(1.0, 0.0, 0.0, 0.0,
                            0.0, 1.0, 0.0, 0.0,
                            0.0, 0.0, 1.0, 0.0,
                            0.0, 0.0, 0.0, 1.0);

    css_MixColor = vec4(0.0, 0.0, 0.0, 0.0);

    // umm, where did gl_FragColor go?
}

DOM 콘텐츠의 각 픽셀에 css_ColorMatrix가 곱해집니다. 위의 경우 css_ColorMatrix아이덴티티 행렬이므로 아무것도 하지 않으며 RGBA 값을 변경하지 않습니다. 예를 들어 빨간색 값만 유지하려면 다음과 같이 css_ColorMatrix를 사용합니다.

// keep only red and alpha
css_ColorMatrix = mat4(1.0, 0.0, 0.0, 0.0,
                        0.0, 0.0, 0.0, 0.0,
                        0.0, 0.0, 0.0, 0.0,
                        0.0, 0.0, 0.0, 1.0);

4D (RGBA) 픽셀 값에 행렬을 곱하면 다른 쪽에서 조작된 픽셀 값을 얻을 수 있습니다. 이 경우 녹색 및 파란색 구성요소를 0으로 설정하는 값이 반환됩니다.

css_MixColor는 주로 DOM 콘텐츠와 혼합할 기본 색상으로 사용됩니다. 혼합은 아트 패키지에서 익숙한 블렌딩 모드(오버레이, 화면, 색상 보정, 하드 라이트 등)를 통해 이루어집니다.

이 두 변수를 사용하여 픽셀을 조작하는 방법은 다양합니다. 혼합 모드와 합성 모드가 상호작용하는 방식을 더 잘 이해하려면 필터 효과 사양을 확인하세요.

Vertex Creation

WebGL에서는 메시의 3D 포인트 생성을 전적으로 담당하지만 맞춤 필터에서는 원하는 행과 열 수를 지정하기만 하면 브라우저가 DOM 콘텐츠를 여러 삼각형으로 자동 분할합니다.

꼭짓점 생성
행과 열로 분할되는 이미지

그런 다음 각 정점은 조작을 위해 정점 셰이더에 전달되므로 필요에 따라 3D 공간에서 정점을 움직일 수 있습니다. 곧 멋진 효과를 만들 수 있을 겁니다.

아코디언 효과
아코디언 효과로 왜곡된 이미지

셰이더로 애니메이션 처리

셰이더에 애니메이션을 가져오면 재미있고 매력적인 셰이더를 만들 수 있습니다. 이렇게 하려면 CSS에서 전환 (또는 애니메이션)을 사용하여 균일한 값을 업데이트하면 됩니다.

.shader {
    /* transition on the filter property */
    -webkit-transition: -webkit-filter 2500ms ease-out;

    -webkit-filter: custom(
    url(vshader.vert)
    mix(url(fshader.frag) normal source-atop),
    1 1,
    time 0);
}

    .shader:hover {
    -webkit-filter: custom(
    url(vshader.vert)
    mix(url(fshader.frag) normal source-atop),
    1 1,
    time 1);
}

위의 코드에서 주목해야 할 점은 전환 중에 시간이 0에서 1로 완만하게 변한다는 것입니다. 셰이더 내에서 균일한 time를 선언하고 현재 값을 사용할 수 있습니다.

    uniform float time;

uniform mat4 u_projectionMatrix;
attribute vec4 a_position;

void main() {
    // copy a_position to position - attributes are read only!
    vec4 position = a_position;

    // use our time uniform from the CSS declaration
    position.x += time;

    gl_Position = u_projectionMatrix * position;
}

플레이하기

맞춤 필터는 사용하기 매우 재미있으며, 이 필터 없이는 놀라운 효과를 만들기 어렵거나 불가능한 경우도 있습니다. 아직 초기 단계이며 많은 변화가 있지만 이 기능을 추가하면 프로젝트에 약간의 스howbiz가 추가되므로 한번 사용해 보세요.

추가 리소스