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 فراهم می‌کنند.
  • عملکرد Fragment Shader برای دستیابی به 60 FPS در برنامه‌های موبایل حیاتی است.

Fragment Shader چیست؟

Fragment Shader (شیدر فرگمنت یا پیکسل) — یک مرحله برنامه‌پذیر از خط لوله گرافیکی است که رنگ نهایی هر فرگمنت تصویر را محاسبه می‌کند. فرگمنت یک پیکسل بالقوه است که پس از عبور از تست‌های عمق و استنسیل به یک پیکسل قابل مشاهده روی صفحه تبدیل می‌شود.

Fragment Shader پس از رسترایزیشن اجرا می‌شود، زمانی که primitives سه‌بعدی (مثلث‌ها) به مجموعه‌ای از فرگمنت‌ها تبدیل شده‌اند. شیدر در ورودی ویژگی‌های درون‌یابی شده — مختصات بافت، نرمال‌ها، رنگ‌ها را دریافت می‌کند که در Vertex Shader برای رئوس مثلث محاسبه شده و به صورت خطی برای هر پیکسل داخل آن درون‌یابی شده‌اند.

تاریخچه تکامل Fragment Shader

پیش از ظهور شیدرهای برنامه‌پذیر (پیش از DirectX 8 / OpenGL 2.0) محاسبه رنگ پیکسل توسط خط لوله ثابت با مجموعه محدودی از عملیات انجام می‌شد. Fragment Shader برنامه‌پذیر در سال 2001 ظاهر شد و قابلیت‌های گرافیک را به طور اساسی گسترش داد: توسعه‌دهندگان کنترل کامل روی رنگ هر پیکسل به دست آوردند که امکان پیاده‌سازی نورپردازی فوتورئالیستیک، مواد پیچیده و پست‌افکت‌ها را فراهم کرد.

Fragment Shader چگونه کار می‌کند؟

Fragment Shader توسط GPU برای هر فرگمنت تولید شده توسط رسترایزر اجرا می‌شود. هر فراخوانی شیدر یک فرگمنت را پردازش می‌کند، داده‌های ورودی آن را می‌خواند، کد کاربر را اجرا می‌کند و مقدار خروجی — رنگ فرگمنت در قالب RGBA را می‌نویسد.

داده‌های ورودی و خروجی

داده‌های ورودی Fragment Shader شامل ویژگی‌های درون‌یابی شده از Vertex Shader (مختصات بافت، نرمال‌ها، رنگ‌ها)، متغیرهای uniform (منابع نور، ماتریس‌ها) و سمپلرهای بافت هستند. داده خروجی — بردار رنگ (gl_FragColor در OpenGL ES 2.0 یا متغیر کاربر در 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() امکان دریافت رنگ پیکسل از اطلس بافت را فراهم می‌کنند. فیلتراسیون (bilinear، trilinear، anizotropic) توسط پارامترهای سمپلر کنترل می‌شود و بر وضوح تصویر در زوایای دید مختلف تأثیر می‌گذارد.

نورپردازی Phong

مدل نورپردازی Phong (Phong shading) در Fragment Shader برای هر پیکسل محاسبه می‌شود که بازتاب‌های نرم‌تری نسبت به نورپردازی راسی (Gouraud shading) ایجاد می‌کند. Phong lighting شامل سه مؤلفه است: ambient (محیطی)، diffuse (پخشیده) و specular (آینه‌ای).

glsl
// شیدر فرگمنت با نورپردازی Phong
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);
}

پست‌افکت‌ها و blending

Fragment Shader امکان اعمال پست‌پردازش را فراهم می‌کند: تصحیح رنگ از طریق جداول LUT، تاری (blur)، افکت درخشش (bloom) و tonemapping برای رندرینگ HDR. همه این افکت‌ها در سطح پیکسل کار می‌کنند و در زمان واقعی اجرا می‌شوند.

عملکرد Fragment Shader و بهینه‌سازی

عملکرد Fragment Shader — عامل اصلی محدودکننده FPS در بازی‌های مدرن موبایل است. از آنجا که شیدر برای هر پیکسل فراخوانی می‌شود، حتی افزایش کوچک در پیچیدگی کد می‌تواند به کاهش محسوس نرخ فریم منجر شود.

مشکلات اصلی عملکرد

  • Overdraw — ترسیم مجدد همان پیکسل به دلیل هم‌پوشانی اشیاء. به ویژه برای اشیاء نیمه‌شفاف حیاتی است.
  • شاخه‌های شرطی — شاخه‌بندی در Fragment Shader کارایی اجرای SIMD را کاهش می‌دهد، زیرا GPU مجبور است هر دو مسیر را اجرا کند.
  • نمونه‌برداری از بافت — هر نمونه‌برداری بافت (texture lookup) تأخیر ده‌ها چرخه GPU دارد. به حداقل رساندن تعداد سمپلرها شیدر را سرعت می‌بخشد.

روش‌های بهینه‌سازی Fragment Shader

برای GPUهای موبایل (Qualcomm Adreno، ARM Mali) توصیه می‌شود: استفاده از mediump precision برای متغیرهای float، ترکیب نمونه‌برداری‌های بافت، اعمال تست‌های early-z برای حذف فرگمنت‌های نامرئی قبل از اجرای شیدر.

روشتوضیحاتبهره‌وری
Mediump precisionدقت 16 بیتی به جای 32 بیتیتا 2 برابر سرعت
Early-Zتست عمق قبل از شیدرکاهش فراخوانی‌ها
Texture atlasingیک بافت به جای چندینتغییرات کمتر

Fragment Shader در مقابل 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) این تقریباً 3 میلیون فراخوانی در هر فریم است. در 60 FPS، شیدر 180 میلیون بار در ثانیه اجرا می‌شود که به قدرت محاسباتی عظیمی نیاز دارد.

چه افکت‌هایی را می‌توان در Fragment Shader ایجاد کرد؟

در Fragment Shader پیاده‌سازی می‌شوند: بافت‌دهی، نورپردازی (Phong, PBR)، سایه‌ها، بازتاب‌ها، شکست نور، bloom، عمق میدان، تصحیح رنگ، فیلترهای LUT و تولید رویه‌ای بافت.

چگونه Fragment Shader را در دستگاه‌های موبایل بهینه‌سازی کنیم؟

از mediump precision برای float استفاده کنید، تعداد نمونه‌برداری‌های بافت را کاهش دهید، از حذف 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 را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید