사전 셰이더
개념

셰이더

gabury1

그림을 그리는 절차 중 비어 있는 칸에 끼워 넣는 작은 프로그램입니다. 무엇을 어떻게 계산할지를 만드는 쪽이 직접 적어 넣는 자리입니다. 점 하나, 화면 조각 하나마다 같은 프로그램이 따로 한 번씩 돕니다.

상세

그림을 그리는 절차는 정해진 순서로 돕니다. 그 순서 안의 몇 칸이 비어 있습니다. 그 칸에 넣는 프로그램이 셰이더입니다. 절차 자체를 새로 짜는 것이 아니라 비어 있는 칸을 채우는 것입니다.

셰이더는 한 번 돌고 끝나지 않습니다. 그 칸을 지나가는 원소 하나마다 따로 한 번씩 돕니다. 점 하나가 들어오면 그 점 하나에 대해 돕니다. 화면 조각 하나가 들어오면 그 조각에 대해 돕니다. 원소가 수백만 개면 같은 프로그램이 수백만 번 도는 셈입니다.

그 수백만 번은 하나씩 차례로 돌지 않습니다. 한꺼번에 돕니다.

시험장에 앉은 수백 명이 같은 문제지를 한 장씩 받습니다. 시작 신호가 떨어지면 모두가 한꺼번에 제 답안지를 채웁니다. 옆 사람이 무엇을 적는지도, 누가 먼저 끝낼지도 알 수 없습니다.

그래서 한 번 도는 셰이더는 자기 몫의 원소만 봅니다. 옆 원소가 무엇을 계산했는지 알지 못합니다. 누가 먼저 돌지도 정하지 못합니다. 칸과 칸 사이로 데이터가 오가는 통로는 그 칸으로 들어온 입력 변수와 다음 칸으로 내보내는 출력 변수입니다. 그 밖에 실행 환경에 놓여 있는 값을 함께 읽기도 합니다.

배경

예전에는 그리는 절차가 통째로 고정돼 있었습니다. 표면이 빛을 어떻게 받는지 계산하는 방식이 미리 몇 가지로 정해져 있었습니다. 만드는 쪽은 그 정해진 모형에 값만 맞춰 넣을 수 있었습니다. 모형에 없는 재질을 내고 싶으면 방법이 없었습니다.

필요한 것은 값이 아니라 계산 방식 자체를 적어 넣을 자리였습니다. 절차 전체를 열 필요는 없었습니다. 음영을 정하는 칸만 비워 두면 됩니다. 그 칸에 넣을 조각은 만드는 쪽이 짜 옵니다.

이름은 그 칸이 하던 일에서 왔습니다. 1984년 Robert L. Cook 이 낸 「Shade Trees」는 셰이더라는 말을 이미 있는 것으로 놓고 씁니다. 그때까지의 셰이더가 모든 표면이 따라야 하는 고정된 모형에 기대 왔다고 적습니다. 그 자리에 넓은 범위의 음영 성질을 나타낼 수 있는 트리 구조의 유연한 음영 모형을 내놓습니다. 지금은 그 칸에 음영과 무관한 계산을 적어 넣기도 합니다. 무엇을 계산하느냐가 넓어졌을 뿐 꽂히는 자리는 그대로입니다.

갈래

파이프라인의 어느 칸에 꽂히느냐가 갈리는 축입니다. 칸마다 받는 것이 다릅니다. 하나씩 도는 단위도 다릅니다.

flowchart TD
    V["정점 셰이더"] -->|켜져 있으면| T["테셀레이션 · 기하 셰이더"]
    T --> R["래스터화"]
    V --> R
    R --> F["조각 셰이더"]
    C["계산 셰이더 · 별개 파이프라인"]

Vulkan 공식 명세가 적는 순서는 이렇습니다. 그래픽 파이프라인은 프리미티브 조립의 결과로 정점 셰이더를 실행합니다. 켜져 있으면 패치 위에서 도는 테셀레이션 제어·평가 셰이더가 뒤따릅니다. 켜져 있으면 프리미티브 위에서 도는 기하 셰이더가 뒤따릅니다. 있으면 래스터화가 만들어 낸 조각 위에서 조각 셰이더가 돕니다.

정점 셰이더

받는 단위는 정점 하나입니다. MDN(Mozilla Developer Network)은 도형을 그릴 때마다 정점 셰이더가 그 도형의 정점마다 한 번씩 돈다고 적습니다. 하는 일은 들어온 정점을 원래 좌표계에서 클립 공간 좌표계로 옮기는 것입니다. WebGL(Web Graphics Library)이 쓰는 클립 공간은 화면 비율이나 실제 크기 같은 요인과 무관하게 각 축이 -1.0 에서 1.0 까지입니다.

조각 셰이더

받는 단위는 래스터화가 만들어 낸 조각 하나입니다. MDN 은 도형의 정점이 정점 셰이더를 거친 뒤 그려질 도형의 픽셀마다 조각 셰이더가 한 번씩 불린다고 적습니다. 하는 일은 그 픽셀의 색을 정하는 것입니다.

Microsoft 공식 문서는 HLSL(High-Level Shader Language)을 DirectX 에서 프로그램 가능한 셰이더를 적는 데 쓰는 C 계열 고수준 셰이더 언어로 소개합니다. 그 문서는 HLSL 로 정점 셰이더나 픽셀 셰이더를 짤 수 있다고 적습니다.

계산 셰이더

그리기와 떨어져 있는 칸입니다. Vulkan 공식 명세는 계산 파이프라인에 계산 셰이더 단계만 들어 있다고 적습니다. 계산 셰이더가 도는 단위는 워크그룹 안의 계산 호출 하나입니다. 계산 파이프라인은 그래픽 파이프라인과 별개의 파이프라인입니다. 1차원·2차원·3차원 워크그룹 위에서 돕니다.

하는 일이 화면에 무언가를 내는 것일 필요가 없습니다. Microsoft 공식 문서는 계산 셰이더로 물리 시뮬레이션을 구현하는 것을 예로 듭니다.

그 밖의 칸

그래픽 파이프라인 안에는 테셀레이션 제어 셰이더 · 테셀레이션 평가 셰이더 · 기하 셰이더가 더 있습니다. 메시 셰이딩 파이프라인을 쓰면 입력 프리미티브가 암묵적으로 조립되지 않습니다. 대신 메시 셰이더를 통해 명시적으로 조립됩니다. Vulkan 공식 명세는 파이프라인 자체를 그래픽 · 레이 트레이싱 · 계산 셋으로 가릅니다.

예시

브라우저에서 도는 정점·조각 셰이더 한 벌

MDN 의 WebGL 튜토리얼이 싣고 있는 GLSL(OpenGL Shading Language) 소스입니다.

JavaScript
const vsSource = `
    attribute vec4 aVertexPosition;
    uniform mat4 uModelViewMatrix;
    uniform mat4 uProjectionMatrix;
    void main() {
      gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;
    }
  `;

정점 셰이더입니다. 들어온 정점 위치에 모델뷰 행렬과 투영 행렬을 곱해 gl_Position 에 넣습니다.

JavaScript
const fsSource = `
    void main() {
      gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
    }
  `;

조각 셰이더입니다. 조명을 쓰지 않고 언제나 흰색을 돌려줍니다. 이 두 벌이 화면에 흰 사각형 하나를 냅니다.

브라우저 표준이 정의하는 셰이더

W3C(World Wide Web Consortium)의 WGSL(WebGPU Shading Language) 명세는 셰이더를 파이프라인의 셰이더 단계 하나를 실행하는 WGSL 프로그램의 부분이라고 정의합니다. WebGPU 명세는 프로그램 가능한 단계가 셰이더를 실행한다고 적습니다. 그리고 셰이더를 GPU(Graphics Processing Unit, 그래픽 처리 장치) 하드웨어에서 돌도록 만들어진 특별한 프로그램이라고 적습니다.

wgsl
@fragment
fn fragmentMain(@location(0) worldPos : vec3f,
                @location(1) normal : vec3f,
                @location(2) uv : vec2f) -> @location(0) vec4f {
  let baseColor = textureSample(baseColorTexture, baseColorSampler, uv);
  // ... 나머지 구현
  return vec4(surfaceColor, baseColor.a);
}

@fragment 가 이 함수를 조각 단계의 진입점으로 지정합니다. 들어오는 값은 위치·법선·텍스처 좌표입니다. 나가는 값은 @location(0) 에 실리는 네 성분짜리 색입니다.

오프라인 렌더링의 표면 셰이더

Open Shading Language 공식 문서는 셰이더 종류로 surface · displacement · light · volume · generic 을 듭니다. 이 중 표면 셰이더는 표면의 기본 재질 속성과 그 표면이 빛에 어떻게 반응하는지를 정합니다. 하는 일은 재질을 기술하는 색상 클로저를 계산하는 것입니다. 원한다면 사용자가 정의한 다른 출력 변수를 함께 설정합니다.

관련 항목

셰이더가 하나씩 처리하는 단위

정점 · 프래그먼트 · 패치 · 프리미티브 · 워크그룹

셰이더가 걸리는 파이프라인 갈래와 단계

파이프라인 · 렌더링 파이프라인 · 컴퓨트 파이프라인 · 메시 셰이딩 · 레이 트레이싱 · 프리미티브 조립 · 래스터화

셰이더를 적는 언어와 형식

GLSL · HLSL · WGSL · Open Shading Language · SPIR-V

셰이더가 다루는 값

텍스처 · 유니폼 · 클립 공간 · 법선 · 색상 클로저 · 재질

셰이더가 도는 API·하드웨어

GPU · WebGL · WebGPU · Vulkan · DirectX · Direct3D

셰이더가 속하는 상위 분야

그래픽스 · 렌더링 · 오프라인 렌더링

셰이더를 문서로 정의하는 기관

MDN · Microsoft · W3C

다른 이름: shader · 셰이더 프로그램