Fragment Shader — 정의, 작업 및 작동 원리

저자: IT Sectr 게시일: 2026-06-11 읽는 시간: 10 분

Fragment Shader는 그래픽 파이프라인의 프로그래밍 가능한 단계로, 이미지의 각 프래그먼트(픽셀)의 최종 색상을 결정합니다. Khronos Group, 2025에 따르면, 프래그먼트 셰이더는 Vertex Shader에서 보간된 데이터를 받아 조명 계산, 텍스처링 및 색상 효과를 수행합니다. Fragment Shader는 각 픽셀에 대해 호출되므로 그래픽 파이프라인에서 가장 리소스 집약적인 단계입니다.

핵심 사항

  • Fragment Shader — 화면의 각 픽셀 색상을 결정하는 GPU의 프로그래밍 가능한 단계.
  • 호출 횟수는 화면 해상도와 같아 렌더링의 주요 계산 부하가 됩니다.
  • 텍스처링 및 Phong 조명은 프래그먼트 셰이더에서 구현되는 일반적인 작업입니다.
  • GLSL 및 Metal Shading Language는 Fragment Shader 작성을 위한 표준 도구를 제공합니다.
  • 성능은 모바일 애플리케이션에서 60 FPS를 달성하는 데 중요합니다.

Fragment Shader란?

Fragment Shader(프래그먼트 또는 픽셀 셰이더)는 이미지의 각 프래그먼트의 최종 색상을 계산하는 그래픽 파이프라인의 프로그래밍 가능한 단계입니다. 프래그먼트는 깊이 및 스텐실 테스트를 통과한 후 화면에서 보이는 픽셀이 될 잠재적 픽셀입니다.

Fragment Shader는 래스터화 후에 실행되며, 3D 프리미티브(삼각형)가 이미 프래그먼트 집합으로 변환된 상태입니다. 셰이더는 Vertex Shader에서 삼각형 정점에 대해 계산되고 삼각형 내부의 각 픽셀에 대해 선형 보간된 보간 속성(텍스처 좌표, 법선, 색상)을 받습니다.

Fragment Shader 진화의 역사

프로그래밍 가능한 셰이더가 등장하기 전(DirectX 8 / OpenGL 2.0 이전)에는 픽셀 색상 계산이 제한된 연산 집합을 가진 고정 파이프라인에 의해 수행되었습니다. 프로그래밍 가능한 Fragment Shader는 2001년에 등장하여 그래픽 기능을 근본적으로 확장했습니다: 개발자는 각 픽셀의 색상을 완전히 제어할 수 있게 되어 사실적인 조명, 복잡한 재질 및 후처리 효과를 구현할 수 있었습니다.

Fragment Shader 작동 방식

Fragment Shader는 래스터라이저가 생성한 각 프래그먼트에 대해 GPU에 의해 실행됩니다. 각 셰이더 호출은 하나의 프래그먼트를 처리하고, 입력 데이터를 읽고, 사용자 코드를 실행하며, 출력 값(RGBA 형식의 프래그먼트 색상)을 씁니다.

입력 및 출력 데이터

Fragment Shader의 입력 데이터에는 Vertex Shader의 보간 속성(텍스처 좌표, 법선, 색상), 균일 변수(광원, 행렬) 및 텍스처 샘플러가 포함됩니다. 출력 데이터는 색상 벡터(OpenGL ES 2.0의 gl_FragColor 또는 ES 3.0의 사용자 정의 변수)로, 컬러 버퍼에 기록됩니다.

glsl
#version 300 es
precision mediump float;

in vec2 vTexCoord;
uniform sampler2D uTexture;
out vec4 fragColor;

void main() {
    fragColor = texture(uTexture, vTexCoord);
}

Fragment Shader의 주요 작업

Fragment Shader는 이미지의 시각적 품질을 담당합니다. 사용자가 화면에서 보는 모든 효과(색상, 그림자, 반사, 투명도)는 그래픽 파이프라인의 이 단계에서 계산됩니다.

텍스처링

가장 빈번한 작업은 보간된 UV 좌표를 사용하여 텍스처에서 색상을 샘플링하는 것입니다. Sampler2D와 texture() 함수를 사용하면 텍스처 아틀라스에서 픽셀 색상을 가져올 수 있습니다. 필터링(이중선형, 삼중선형, 이방성)은 샘플러 매개변수를 통해 제어되며 다양한 시야각에서 이미지 선명도에 영향을 줍니다.

Phong 조명

Phong 셰이딩 모델은 Fragment Shader에서 픽셀 단위로 계산되어 정점 조명(Gouraud 셰이딩)보다 더 부드러운 하이라이트를 제공합니다. Phong 조명에는 세 가지 구성 요소가 포함됩니다: 주변(ambient), 확산(diffuse) 및 반사(specular)입니다.

glsl
// Fragment shader with Phong lighting
in vec3 vNormal;
in vec3 vPosition;
uniform vec3 uLightDir;
uniform vec3 uLightColor;

void main() {
    vec3 norm = normalize(vNormal);
    float diff = max(dot(norm, uLightDir), 0.0);
    fragColor = vec4(uLightColor * diff, 1.0);
}

후처리 효과 및 블렌딩

Fragment Shader를 사용하면 룩업 테이블(LUT)을 통한 색상 보정, 블러, 블룸 효과 및 HDR 렌더링을 위한 톤매핑과 같은 후처리를 적용할 수 있습니다. 이러한 모든 효과는 픽셀 수준에서 작동하며 실시간으로 실행됩니다.

Fragment Shader 성능 및 최적화

Fragment Shader 성능은 최신 모바일 게임에서 FPS를 제한하는 주요 요소입니다. 셰이더가 각 픽셀에 대해 호출되므로 코드 복잡성이 약간만 증가해도 프레임 속도가 눈에 띄게 떨어질 수 있습니다.

주요 성능 문제

  • Overdraw — 객체 겹침으로 인한 동일 픽셀의 재렌더링. 반투명 객체의 경우 특히 중요합니다.
  • 조건 분기 — Fragment Shader의 분기는 SIMD 실행 효율성을 떨어뜨립니다. GPU가 두 분기를 모두 실행해야 하기 때문입니다.
  • 텍스처 샘플링 — 각 텍스처 샘플링은 수십 GPU 클록 사이클의 지연 시간이 있습니다. 샘플러 수를 최소화하면 셰이더가 빨라집니다.

Fragment Shader 최적화 방법

모바일 GPU(Qualcomm Adreno, ARM Mali)의 경우: float 변수에 mediump precision을 사용하고, 텍스처 샘플링을 결합하고, 셰이더 실행 전에 보이지 않는 프래그먼트를 폐기하기 위해 early-z 테스트를 적용하는 것이 좋습니다.

방법설명이득
Mediump precision32비트 대신 16비트 정밀도최대 2배 속도
Early-Z셰이더 전 깊이 테스트호출 감소
Texture atlasing여러 개 대신 하나의 텍스처전환 감소

Fragment Shader vs Vertex Shader: 비교

두 유형의 셰이더 모두 개발자가 프로그래밍할 수 있지만, 파이프라인의 다른 단계에서 작동하고 다른 작업을 해결합니다. Fragment Shader는 호출 횟수로 인해 훨씬 더 리소스 집약적입니다.

매개변수Fragment ShaderVertex Shader
호출 횟수수백만(화면 해상도)수천(정점 수)
입력 데이터보간 속성정점 속성
주요 기능프래그먼트 색상 계산기하 변환
텍스처 접근전체(여러 샘플러)제한됨
성능 영향높음(해상도에 의존)중간(기하에 의존)

Fragment Shader 코드 예제

Fragment Shader는 단순(텍스처 샘플링)하거나 복잡(다중 레이어 조명)할 수 있습니다. 두 가지 실용적인 예를 살펴보겠습니다: 기본 텍스처링과 시간을 사용한 그래디언트 효과입니다.

GLSL의 기본 텍스처링

glsl
#version 300 es
precision mediump float;
in vec2 vTexCoord;
in vec3 vColor;
uniform sampler2D uDiffuseMap;
out vec4 fragColor;

void main() {
    vec4 texColor = texture(uDiffuseMap, vTexCoord);
    fragColor = texColor * vec4(vColor, 1.0);
}

Metal Shading Language 예제

cpp
#include <metal_stdlib>
using namespace metal;

struct FragmentIn {
    float2 texCoord;
    float3 normal;
};

fragment float4
fragmentMain(FragmentIn in [[stage_in]],
              texture2d<float> tex [[texture(0)]]) {
    constexpr sampler s(filter = linear);
    float4 color = tex.sample(s, in.texCoord);
    return color;
}

자주 묻는 질문

간단히 말해 Fragment Shader란 무엇인가요?

Fragment Shader는 GPU의 미니 프로그램으로, 화면의 각 픽셀이 어떤 색상이 될지 결정합니다. Vertex Shader가 객체의 모양을 결정한다면, Fragment Shader는 해당 객체가 어떻게 보이는지(텍스처, 조명, 색상)를 결정합니다.

왜 Fragment Shader가 그렇게 리소스 집약적인가요?

Fragment Shader는 화면의 모든 픽셀에 대해 호출됩니다. 2532x1170(iPhone) 해상도의 기기에서는 프레임당 거의 300만 회 호출됩니다. 60 FPS에서 셰이더는 초당 1억 8천만 번 실행되며, 엄청난 계산 성능이 필요합니다.

Fragment Shader에서 어떤 효과를 만들 수 있나요?

Fragment Shader에서는 텍스처링, 조명(Phong, PBR), 그림자, 반사, 굴절, bloom, 피사계 심도, 색상 보정, LUT 필터 및 절차적 텍스처 생성이 구현됩니다.

모바일 기기에서 Fragment Shader를 최적화하는 방법은?

float에 mediump precision을 사용하고, 텍스처 샘플링 수를 줄이고, early-z 컬링을 적용하고, 셰이더 연산을 결합하고, 셰이더 내 조건 분기를 피하십시오.

Fragment Shader와 Pixel Shader의 차이점은?

같은 것입니다. Fragment Shader라는 용어는 OpenGL / Vulkan에서 사용되고, Pixel Shader는 Direct3D(Microsoft) 용어로 사용됩니다. 기능적으로 동일하며, 둘 다 각 프래그먼트/픽셀의 색상을 계산합니다.

요약

  • Fragment Shader — 이미지의 각 픽셀 색상을 계산하는 GPU의 프로그래밍 가능한 단계.
  • 호출 횟수는 화면 해상도와 같아 가장 리소스 집약적인 렌더링 단계입니다.
  • 텍스처링, Phong 조명 및 후처리 효과가 프래그먼트 셰이더의 주요 작업입니다.
  • 성능은 텍스처 샘플링 수와 highp precision 사용에 직접적으로 의존합니다.
  • Mediump precision 및 early-z 테스트는 모바일 GPU의 주요 최적화 기술입니다.
  • OpenGL ES는 Fragment Shader 용어를 사용하고, Direct3D는 Pixel Shader를 사용합니다 — 의미는 동일합니다.
  • GLSL 및 Metal Shading Language는 모바일 개발에서 Fragment Shader 작성을 위한 주요 언어입니다.

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기