--- id: wiki-2026-0508-fragment-shading title: Fragment Shading category: 10_Wiki/Topics status: verified canonical_id: self aliases: [Pixel Shader, Fragment Shader] duplicate_of: none source_trust_level: A confidence_score: 0.9 verification_status: applied tags: [graphics, gpu, shaders, webgl] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: glsl framework: webgl --- # Fragment Shading ## 매 한 줄 > **"매 rasterized fragment 마다 매 한 번 실행되어 final color 를 계산"**. 매 GPU pipeline (vertex → primitive assembly → rasterization → **fragment** → blending) 의 final programmable stage. 2026 시점 WebGPU + WGSL 가 WebGL2 + GLSL 의 후속, native 는 Metal MSL / HLSL SM 6.x / Vulkan SPIR-V. ## 매 핵심 ### 매 input / output - **Input**: interpolated vertex output (UV, normal, world pos), uniforms, textures. - **Output**: 매 RGBA color (+ optional depth, MRT). - 매 fragment ≠ pixel — 매 multi-sampling / overdraw 시 매 fragment 가 pixel 보다 많을 수 있다. ### 매 pipeline (rasterization) 1. Vertex shader → clip space. 2. Primitive assembly + clipping. 3. Rasterization → 매 fragment 생성. 4. **Fragment shader** → color. 5. Depth/stencil test + blending → framebuffer. ### 매 cost factor - **Overdraw**: 매 같은 pixel 이 여러 번 shaded. - **Texture bandwidth**: 매 sample count + filter. - **ALU**: 매 복잡한 BRDF, lighting loop. - **Branch divergence**: warp / wave 내 분기. ### 매 응용 1. PBR lighting (Cook-Torrance, GGX). 2. Post-processing (bloom, SSAO, FXAA, TAA). 3. Procedural texture / SDF. 4. Compute-like (pre-WebGPU 의 GPGPU hack). ## 💻 패턴 ### GLSL — basic textured + Lambert ```glsl // fragment.glsl (WebGL2 / GLSL ES 3.00) #version 300 es precision highp float; in vec2 vUV; in vec3 vNormalW; in vec3 vPosW; uniform sampler2D uAlbedo; uniform vec3 uLightDirW; out vec4 outColor; void main() { vec3 albedo = texture(uAlbedo, vUV).rgb; float ndl = max(dot(normalize(vNormalW), -normalize(uLightDirW)), 0.0); outColor = vec4(albedo * (0.1 + 0.9 * ndl), 1.0); } ``` ### GLSL — GGX specular (PBR) ```glsl float D_GGX(float NoH, float a) { float a2 = a * a; float f = (NoH * a2 - NoH) * NoH + 1.0; return a2 / (3.14159 * f * f); } float V_SmithGGXCorrelated(float NoV, float NoL, float a) { float a2 = a * a; float gv = NoL * sqrt(NoV * NoV * (1.0 - a2) + a2); float gl = NoV * sqrt(NoL * NoL * (1.0 - a2) + a2); return 0.5 / (gv + gl); } ``` ### WGSL — fragment (WebGPU 2026) ```wgsl struct VsOut { @builtin(position) pos: vec4f, @location(0) uv: vec2f }; @group(0) @binding(0) var samp: sampler; @group(0) @binding(1) var tex: texture_2d; @fragment fn fs_main(in: VsOut) -> @location(0) vec4f { return textureSample(tex, samp, in.uv); } ``` ### GLSL — SDF circle (procedural) ```glsl float sdCircle(vec2 p, float r) { return length(p) - r; } void main() { vec2 uv = gl_FragCoord.xy / uResolution.xy * 2.0 - 1.0; float d = sdCircle(uv, 0.5); float a = smoothstep(0.0, 0.005, -d); outColor = vec4(vec3(1.0), a); } ``` ### Three.js custom material ```ts import * as THREE from "three"; const mat = new THREE.ShaderMaterial({ uniforms: { uTime: { value: 0 } }, vertexShader: `varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); }`, fragmentShader: `uniform float uTime; varying vec2 vUv; void main() { gl_FragColor = vec4(vUv, 0.5 + 0.5*sin(uTime), 1.0); }`, }); ``` ### Discard for cutout (alpha test) ```glsl vec4 c = texture(uAlbedo, vUV); if (c.a < 0.5) discard; // 매 early-Z 깨질 수 있음 — 매 주의 outColor = c; ``` ### Post-process (full-screen quad) ```glsl // FXAA-lite vec3 rgbNW = texture(uTex, vUV + vec2(-1.0, -1.0)/uRes).rgb; vec3 rgbNE = texture(uTex, vUV + vec2( 1.0, -1.0)/uRes).rgb; vec3 rgbSW = texture(uTex, vUV + vec2(-1.0, 1.0)/uRes).rgb; vec3 rgbSE = texture(uTex, vUV + vec2( 1.0, 1.0)/uRes).rgb; vec3 rgbM = texture(uTex, vUV).rgb; outColor = vec4((rgbNW + rgbNE + rgbSW + rgbSE + rgbM) / 5.0, 1.0); ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | Web 2026 | WebGPU + WGSL (Chrome/Edge/Safari 17+) | | Web legacy | WebGL2 + GLSL ES 3.00 | | Native Apple | Metal + MSL | | Native cross-plat | Vulkan + SPIR-V (cross-compile from HLSL/Slang) | | Heavy overdraw | Z-prepass / depth sort / Hi-Z | | Branch-heavy | uniform branch 또는 per-tile compute | **기본값**: 2026 신규 web project 는 WebGPU. 매 wide compatibility 필요하면 WebGL2 fallback. ## 🔗 Graph - 부모: [[GPU Pipeline]] · [[Computer Graphics]] - 변형: [[Vertex Shader]] · [[Compute Shader]] - 응용: [[PBR]] · [[Post-Processing]] - Adjacent: [[GPGPU]] ## 🤖 LLM 활용 **언제**: shader code review / lighting model 도출 / WebGL→WebGPU 마이그레이션. **언제 X**: 매 raw rendering loop 의 micro-perf — 매 GPU profiler (Nsight, Xcode GPU) 가 우선. ## ❌ 안티패턴 - **Texture sample in non-uniform branch**: 매 derivative 깨짐 (mipmap LOD). - **discard everywhere**: 매 early-Z 무력화 → fillrate 폭증. - **High precision 남용**: 매 mobile 에서 highp 필요 부분만. - **CPU readback every frame**: 매 GPU sync stall. - **Loop count = uniform without unroll hint**: 매 driver 별 perf 변동. ## 🧪 검증 / 중복 - Verified (Khronos GLSL 4.60 spec, WebGPU spec 2025, Real-Time Rendering 4ed, Filament docs). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — fragment shader + WebGPU/WGSL 2026 정리 |