Fragment Shader — είναι ένα προγραμματιζόμενο στάδιο της γραφικής αλυσίδας που καθορίζει το τελικό χρώμα κάθε τμήματος (pixel) της εικόνας. Σύμφωνα με στοιχεία της Khronos Group, 2025, το fragment shader λαμβάνει παρεμβαλλόμενα δεδομένα από το Vertex Shader και εκτελεί υπολογισμούς φωτισμού, υφής και χρωματικών εφέ. Fragment Shader καλείται για κάθε pixel, καθιστώντας το το πιο απαιτητικό σε πόρους στάδιο της γραφικής αλυσίδας.
Κύρια σημεία
Fragment Shader (fragment ή pixel shader) — είναι ένα προγραμματιζόμενο στάδιο της γραφικής αλυσίδας που υπολογίζει το τελικό χρώμα κάθε τμήματος της εικόνας. Ένα τμήμα είναι ένα δυνητικό pixel που, αφού περάσει τις δοκιμές βάθους και stencil, γίνεται ορατό pixel στην οθόνη.
Το Fragment Shader εκτελείται μετά τη rasterization, όταν τα τρισδιάστατα πρωτόγονα (τρίγωνα) έχουν ήδη μετατραπεί σε ένα σύνολο τμημάτων. Ο shader λαμβάνει στην είσοδο παρεμβαλλόμενα χαρακτηριστικά — συντεταγμένες υφής, κανονικές, χρώματα που υπολογίστηκαν στο Vertex Shader για τις κορυφές του τριγώνου και γραμμικά παρεμβλήθηκαν για κάθε pixel εντός αυτού.
Πριν από την εμφάνιση προγραμματιζόμενων shader (πριν από DirectX 8 / OpenGL 2.0) ο υπολογισμός του χρώματος του pixel γινόταν από σταθερή αλυσίδα με περιορισμένο σύνολο λειτουργιών. Προγραμματιζόμενο Fragment Shader εμφανίστηκε το 2001 και επέκτεινε ριζικά τις δυνατότητες γραφικών: οι προγραμματιστές απέκτησαν πλήρη έλεγχο του χρώματος κάθε pixel, επιτρέποντας την υλοποίηση φωτορεαλιστικού φωτισμού, σύνθετων υλικών και εφέ μετα-επεξεργασίας.
Fragment Shader εκκινείται από την GPU για κάθε τμήμα που δημιουργείται από τον rasterizer. Κάθε κλήση shader επεξεργάζεται ένα τμήμα, διαβάζει τα δεδομένα εισόδου του, εκτελεί τον κώδικα χρήστη και γράφει την τιμή εξόδου — το χρώμα του τμήματος σε μορφή RGBA.
Τα δεδομένα εισόδου του Fragment Shader περιλαμβάνουν παρεμβαλλόμενα χαρακτηριστικά από το Vertex Shader (συντεταγμένες υφής, κανονικές, χρώματα), μεταβλητές uniform (πηγές φωτός, πίνακες) και sampler υφής. Τα δεδομένα εξόδου — διάνυσμα χρώματος (gl_FragColor σε OpenGL ES 2.0 ή μεταβλητή χρήστη σε ES 3.0) που γράφεται στο buffer χρώματος.
#version 300 es
precision mediump float;
in vec2 vTexCoord;
uniform sampler2D uTexture;
out vec4 fragColor;
void main() {
fragColor = texture(uTexture, vTexCoord);
}
Fragment Shader είναι υπεύθυνο για την οπτική ποιότητα της εικόνας. Όλα τα εφέ που βλέπει ο χρήστης στην οθόνη — χρώμα, σκιές, αντανακλάσεις, διαφάνεια — υπολογίζονται ακριβώς σε αυτό το στάδιο της γραφικής αλυσίδας.
Η πιο συνηθισμένη λειτουργία — λήψη χρώματος από την υφή βάσει παρεμβαλλόμενων συντεταγμένων UV. Sampler2D και η συνάρτηση texture() επιτρέπουν τη λήψη του χρώματος pixel από τον άτλαντα υφών. Το φιλτράρισμα (διγραμμικό, τριγραμμικό, ανισότροπο) ελέγχεται μέσω παραμέτρων sampler και επηρεάζει την ευκρίνεια της εικόνας σε διαφορετικές γωνίες θέασης.
Το μοντέλο φωτισμού Phong (Phong shading) υπολογίζεται στο Fragment Shader για κάθε pixel, δίνοντας πιο ομαλές ανταύγειες από τον φωτισμό κορυφής (Gouraud shading). Phong lighting περιλαμβάνει τρία στοιχεία: ambient (περιβάλλον), diffuse (διάχυτο) και specular (κατοπτρικό).
// Fragment shader με φωτισμό 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);
}
Το Fragment Shader επιτρέπει την εφαρμογή μετα-επεξεργασίας: διόρθωση χρώματος μέσω πινάκων LUT, θόλωμα (blur), εφέ λάμψης (bloom) και tonemapping για απόδοση HDR. Όλα αυτά τα εφέ λειτουργούν σε επίπεδο pixel και εκτελούνται σε πραγματικό χρόνο.
Απόδοση του Fragment Shader — ο κύριος παράγοντας που περιορίζει τα FPS στα σύγχρονα παιχνίδια κινητών. Δεδομένου ότι ο shader καλείται για κάθε pixel, ακόμη και μια μικρή αύξηση στην πολυπλοκότητα του κώδικα μπορεί να οδηγήσει σε αισθητή πτώση του ρυθμού καρέ.
Για κινητές GPU (Qualcomm Adreno, ARM Mali) συνιστάται: χρήση mediump precision για μεταβλητές float, συνδυασμός λήψεων υφής, εφαρμογή δοκιμών early-z για απόρριψη αόρατων τμημάτων πριν από την εκτέλεση του shader.
| Μέθοδος | Περιγραφή | Όφελος |
|---|---|---|
| Mediump precision | Ακρίβεια 16-bit αντί για 32-bit | Έως 2x ταχύτητα |
| Early-Z | Δοκιμή βάθους πριν από τον shader | Μείωση κλήσεων |
| Texture atlasing | Μία υφή αντί για πολλές | Λιγότερες εναλλαγές |
Και οι δύο τύποι shader προγραμματίζονται από τον προγραμματιστή, αλλά λειτουργούν σε διαφορετικά στάδια της αλυσίδας και επιλύουν διαφορετικές εργασίες. Fragment Shader είναι σημαντικά πιο απαιτητικό σε πόρους λόγω του αριθμού κλήσεων.
| Παράμετρος | Fragment Shader | Vertex Shader |
|---|---|---|
| Αριθμός κλήσεων | Εκατομμύρια (ανάλυση οθόνης) | Χιλιάδες (αριθμός κορυφών) |
| Δεδομένα εισόδου | Παρεμβαλλόμενα χαρακτηριστικά | Χαρακτηριστικά κορυφών |
| Κύρια λειτουργία | Υπολογισμός χρώματος τμήματος | Μετασχηματισμός γεωμετρίας |
| Πρόσβαση σε υφές | Πλήρης (πολλαπλοί sampler) | Περιορισμένη |
| Επίπτωση στην απόδοση | Υψηλή (εξαρτάται από ανάλυση) | Μέτρια (εξαρτάται από γεωμετρία) |
Fragment Shader μπορεί να είναι απλό (λήψη υφής) ή σύνθετο (πολυεπίπεδος φωτισμός). Ας εξετάσουμε δύο πρακτικά παραδείγματα: βασική υφή και εφέ διαβάθμισης με χρήση χρόνου.
#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);
}
#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 — είναι ένα μικρό πρόγραμμα στην GPU που καθορίζει τι χρώμα θα έχει κάθε pixel στην οθόνη. Αν το Vertex Shader καθορίζει το σχήμα του αντικειμένου, τότε το Fragment Shader καθορίζει πώς φαίνεται αυτό το αντικείμενο — υφή, φωτισμός, χρώμα.
Το Fragment Shader καλείται για κάθε pixel στην οθόνη. Σε μια συσκευή με ανάλυση 2532x1170 (iPhone) αυτό είναι σχεδόν 3 εκατομμύρια κλήσεις ανά καρέ. Στα 60 FPS, ο shader εκτελείται 180 εκατομμύρια φορές το δευτερόλεπτο, που απαιτεί τεράστια υπολογιστική ισχύ.
Στο Fragment Shader υλοποιούνται: υφή, φωτισμός (Phong, PBR), σκιές, αντανακλάσεις, διάθλαση, bloom, βάθος πεδίου, διόρθωση χρώματος, φίλτρα LUT και διαδικαστική δημιουργία υφών.
Χρησιμοποιήστε mediump precision για float, μειώστε τον αριθμό λήψεων υφής, εφαρμόστε απόρριψη early-z, συνδυάστε λειτουργίες shader και αποφύγετε υπό συνθήκη διακλαδώσεις μέσα στον shader.
Είναι το ίδιο πράγμα. Ο όρος Fragment Shader χρησιμοποιείται σε OpenGL / Vulkan, ενώ Pixel Shader στην ορολογία του Direct3D (Microsoft). Λειτουργικά είναι πανομοιότυπα: και τα δύο υπολογίζουν το χρώμα κάθε τμήματος/pixel.
Περίληψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης