Chapters 0, 1, 2 Unchecked

pull/393/head
nikos-maximus 1 year ago
parent f9cfdbdda6
commit 1ecb87820b

@ -0,0 +1,47 @@
# Εισαγωγή
<canvas id="custom" class="canvas" data-fragment-url="cmyk-halftone.frag" data-textures="vangogh.jpg" width="700px" height="320px"></canvas>
Οι παραπάνω εικόνες φτιάχτηκαν με διαφορετικούς τρόπους. Η πρώτη φτιάχτηκε από το χέρι του Van Gogh, προσθέτοντας στρώματα χρώματος, το ένα πάνω στο άλλο. Του χρειάστηκαν ώρες. Η δεύτερη δημιουργήθηκε σε δευτερόλεπτα από τον συνδυασμό τεσσάρων πινάκων από pixels: έναν για το κυανό (cyan), έναν για το πορφυρό (magenta), έναν για το κίτρινο και έναν για το μαύρο. Η βασική διαφορά είναι πως η δεύτερη εικόνα δημιουργήθηκε με μη-σειριακό τρόπο (δηλαδή, όχι ένα-ένα βήμα, αλλά ολόκληρη την ίδια στιγμή)
Αυτό το βιβλίο πραγματεύεται την επαναστατική υπολογιστική τεχνική, *fragment shaders* (φωτοσκιαστές τεμαχίων), η οποία ανεβάζει τις ψηφιακά παραγόμενες εικόνες σε επόμενο επίπεδο. Σκεφτείτε το σαν το αντίστοιχο του πιεστηρίου του Γουτεμβέργιου για τα graphics.
![Τυπογραφείο του Γουτεμβέργιου](gutenpress.jpg)
Οι fragment shaders μας δίνουν πλήρη έλεγχο πάνω στα pixels που ζωγραφίζονται στην οθόνη, σε υπερυψηλές ταχύτητες. Γι' αυτό το λόγο χρησιμοποιούνται σε όλων των ειδών τις περιπτώσεις, από φίλτρα βίντεο σε κινητά τηλέφωνα μέχρι απίστευτα 3D βιντεοπαιχνίδια.
![Journey απο That Game Company](journey.jpg)
Στα επόμενα κεφάλαια θα ανακαλύψετε πόσο απίστευτα γρήγορη και ισχυρή είναι αυτή η τεχνική και πως να τη χρησιμοποιήσετε στην επαγγελματική και προσωπική σας δουλειά.
## Σε ποιούς απευθύνεται αυτό το βιβλίο;
Αυτό το βιβλίο γράφτηκε για δημιουργικούς coders, game developers και μηχανικούς με εμπειρία στο coding, βασικές γνώσεις γραμμικής άλγεβρας και τριγωνομετρίας, που θέλουν να ανεβάσουν τη δουλειά τους σε ένα συναρπαστικό νέο επίπεδο ποιότητας γραφικών. (Αν θέλετε να μάθετε πως να γράφετε κώδικα, προτείνω ιδιαίτερα να ξεκινήσετε με την [Processing](https://processing.org/) και να επιστρέψετε όταν έχετε αποκτήσει μια σχετική άνεση με αυτή.)
Αυτό το βιβλίο θα σας δείξει πως να χρησιμοποιείτε και να ενσωματώνετε shaders στα δικά σας έργα, βελτιώνοντας την απόδοση και την οπτική τους ποιότητα. Επειδή οι shaders που είναι γραμμένοι σε GLSL (η γλώσσα για περιγραφή shaders που ορίζει η OpenGL) μεταγλωττίζονται και τρέχουν σε μια πληθώρα από περιβάλλοντα, θα μπορείτε να εφαρμόσετε ο,τι μάθετε εδώ σε οποιοδήποτε περιβάλλον χρησιμοποιεί OpenGL, OpenGL ES ή WebGL. Με άλλα λόγια, θα μπορείτε να εφαρμόσετε και να χρησιμοποιήσετε τις γνώσεις σας με αρχεία [Processing](https://processing.org/), εφαρμογές [openFrameworks](http://openframeworks.cc/), διαδραστικά περιβάλλοντα [Cinder](http://libcinder.org/), ιστοσελίδες [Three.js](http://threejs.org/) ή παιχνίδια σε iOS/Android.
## Τι καλύπτει αυτό το βιβλίο;
Αυτό το βιβλίο εστιάζει στη χρήση pixel shaders σε GLSL. Πρώτα θα ορίσουμε τι είναι οι shaders, στη συνέχεια θα μάθουμε πως να φτιάχνουμε διαδικάστικά (procedural) σχήματα, μοτίβα, υφές (textures) και animations (κίνηση) με αυτούς. Θα μάθετε τις αρχές της γλώσσας περιγραφής shaders και θα την χρησιμοποιήσετε σε πιο χρηστικά σενάρια όπως: επεξεργασία εικόνας (χειρισμούς εικόνας, συγκερασμούς (convolution) πινάκων, θόλωμα (blur), φίλτρα χρώματος, πίνακες αναζήτησης (lookup tables) και άλλα εφέ) και προσομοιώσεις (Conway's game of life, Gray-Scott's reaction-diffusion, κυματισμούς νερού, εφέ νερομπογιάς, στοιχεία Voronoi, κτλ.). Προς το τέλος του βιβλίου θα δούμε ένα σύνολο απο προχωρημένες τεχνικές βασισμένες σε Ray Marching (βηματισμό ακτίνων).
*Υπάρχουν διαδραστικά παραδείγματα με τα οποία μπορείτε να παίξετε σε κάθε κεφάλαιο* Όταν αλλάζετε τον κώδικα, θα μπορείτε να βλέπετε τις αλλαγές άμεσα. Οι έννοιες μπορεί να είναι αφηρημένες και περίπλοκες, οπότε τα διαδραστικά παραδείγματα είναι απαραίτητα ώστε να σας βοηθήσουν να μάθετε το υλικό. Όσο πιο σύντομα βάλετε σε "κίνηση" τις έννοιες, τόσο ευκολότερη θα γίνει η διαδικασία της αφομοίωσης.
Τι δεν καλύπτει αυτό το βιβλίο:
* Αυτό *δεν είναι* ενα βιβλίο για την OpenGL ή τη webGL. Η OpenGL/webGL είναι ένα αντικέιμενο μεγαλύτερο από την GLSL και τους fragment shaders. Για να μάθετε περισσότερα σχετικά με OpenGL/webGL, προτείνω να ρίξετε μια ματιά σε: [OpenGL Introduction](https://open.gl/introduction), [8η έκδοση του βιβλίου OpenGL Programming Guide](http://www.amazon.com/OpenGL-Programming-Guide-Official-Learning/dp/0321773039/ref=sr_1_1?s=books&ie=UTF8&qid=1424007417&sr=1-1&keywords=open+gl+programming+guide) (γνωστό επίσης ως "το κόκκινο βιβλίο") ή [WebGL: Up and Running](http://www.amazon.com/WebGL-Up-Running-Tony-Parisi/dp/144932357X/ref=sr_1_4?s=books&ie=UTF8&qid=1425147254&sr=1-4&keywords=webgl)
* Αυτό *δεν είναι* ένα βιβλίο μαθηματικών. Αν και θα καλύψουμε ένα σύνολο απο αλγορίθμους και τεχνικές που βασίζονται στην κατανόηση άλγεβρας και τριγωνομετρίας, δε θα τις εξηγήσουμε με λεπτομέρεια. Για απορίες σχετικές με τα μαθηματικά προτείνω να έχετε πρόχειρο ένα από τα ακόλουθα βιβλία: [3η Έκδοση του Mathematics for 3D Game Programming and computer Graphics](http://www.amazon.com/Mathematics-Programming-Computer-Graphics-Third/dp/1435458869/ref=sr_1_1?ie=UTF8&qid=1424007839&sr=8-1&keywords=mathematics+for+games) ή [2η Έκδοση του Essential Mathematics for Games and Interactive Applications](http://www.amazon.com/Essential-Mathematics-Games-Interactive-Applications/dp/0123742978/ref=sr_1_1?ie=UTF8&qid=1424007889&sr=8-1&keywords=essentials+mathematics+for+developers).
## Τι χρειάζεται για να ξεκινήσετε;
Όχι πολλά! Αν έχετε ένα σύγχρονο browser που υποστηρίζει WebGL (όπως οι Chrome, Firefox, Safari) και μια σύνδεση στο internet, πατήστε "Next" (επόμενο κεφάλαιο) στο τέλος αυτής της σελίδας για να ξεκινήσετε.
Εναλλακτικά, ανάλογα με τι έχετε ή τι χρειάζεστε από αυτό το βιβλίο μπορείτε:
- [Να φτιάξετε μια off-line εκδοχή του βιβλίου](https://thebookofshaders.com/appendix/00/)
- [Να τρέξετε τα παραδείγματα σε ενα Raspberry Pi χωρίς browser](https://thebookofshaders.com/appendix/01/)
- [να φτιάξετε ενα PDF του βιβλίου για εκτύπωση](https://thebookofshaders.com/appendix/02/)
- Συμβουλευτείτε το [αποθετήριο GitHub (repository)](https://github.com/patriciogonzalezvivo/thebookofshaders) του βιβλίου για επίλυση προβλημάτων και για να μοιραστείτε κώδικα.

@ -0,0 +1 @@
# Εισαγωγή

@ -0,0 +1,48 @@
# Ξεκινώντας
## Τι είναι ένας fragment shader;
Στο προηγούμενο κεφάλαιο περιγράψαμε τους shaders σαν το αντίστοιχο του πιεστηρίου του Γουτεμβέργιου για τα γραφικά. Γιατί; Και πιό σημαντικό: τι είναι ενας shader?
![Από έναν-ένα χαρακτήρα/γράμμα, Δεξιά: William Blades (1891). Στο μια-μια Σελίδα, Αριστερά: Rolt-Wheeler (1920).](print.png)
Αν έχετε ήδη εμπειρία στο να δημιουργείτε ζωγραφιές με υπολογιστές, ξέρετε πως μέρος της διαδικασίας είναι να ζωγραφίσετε έναν κύκλο, μετά ένα τετράγωνο, μια γραμμή, μερικά τρίγωνα μέχρι να συνθέσετε την εικόνα που θέλετε. Αυτή η διαδικασία είναι πολύ παρόμοια με το να γράφετε ένα γράμμα ή ένα βιβλίο με το χέρι - είναι ένα σύνολο από οδηγίες που πραγματοποιούν μια εργασία μετά την άλλη.
Οι shaders είναι επίσης ένα σύνολο απο οδηγίες, αλλά οι οδηγίες εκτελούνται όλες ταυτόχρονα για κάθε ένα pixel στην οθόνη. Αυτό σημαίνει πως ο κώδικας που γράφετε πρέπει να συμπεριφερθεί διαφορετικά ανάλογα με τη θέση του pixel στην οθόνη. Ανάλογα με ένα πιεστήριο τυπογραφείου, το πρόγραμμα θα συμπεριφερθεί σα μια συνάρτηση που παίρνει στην είσοδο μια θέση και επιστρέφει στην έξοδο ένα χρώμα, και που αφού μεταγλωττιστεί θα εκτελεστεί εκπληκτικά γρήγορα.
![Κινητοί Κινέζικοι χαρακτήρες](typepress.jpg)
## Γιατί είναι γρήγοροι οι shaders;
Για να το απαντήσουμε αυτό, σας παρουσιάζω το θαύμα της *παράλληλης επεξεργασίας*.
Φανταστείτε την CPU (επεξεργαστή) του υπολογιστή σας σαν έναν μεγάλο βιομηχανικό σωλήνα, και κάθε εργασία (task) σαν κάτι που περνάει μέσα απο αυτόν - σαν εργοστασιακή γραμμή παραγωγής. Κάποιες εργασίες είναι μεγαλύτερες από άλλες, που σημαίνει πως απαιτούν περισσότερο χρόνο και ενέργεια. Λέμε πως απαιτούν μεγαλύτερη υπολογιστική ισχύ. Λόγω της αρχιτεκτονικής των υπολογιστών οι εργασίες πρέπει να τρέχουν σε σειρά: κάθε εργασία πρέπει να τελειώνει μία τη φορά. Οι σύγχρονοι υπολογιστές συνήθως έχουν ομάδες τεσσάρων επεξεργαστών που λειτουργούν όπως αυτοί οι σωλήνες, ολοκληρώνοντας εργασίες τη μια μετά την άλλη ώστε τα πράγματα να συνεχίσουν να λειτουργούν ομαλά. Κάθε σωλήνας είναι επίσης γνωστός και σαν *thread (νήμα)*.
![CPU (επεξεργαστής)](00.jpeg)
Τα video games και άλλες εφαργμογές με γραφικά απαιτούν πολύ περισσότερη επεξεργαστική ισχύ από άλλα προγράμματα. Εξ' αιτίας του οπτικού τους περιεχομένου χρειάζεται να πραγματοποιούν πολύ μεγάλο αριθμό από λειτουργίες pixel προς pixel. Κάθε ένα pixel στην οθόνη χρειάζεται να υπολογιστεί, και σε 3D παιχνίδια, η γεωμετρία και η προοπτική πρέπει επίσης να υπολογιστούν.
Ας πάμε πίσω στην αναλογία με τους σωλήνες και τις εργασίες. Κάθε pixel στην οθόνη αντιπροσωπέυει μια μικρή εργασία. Από μόνη της, μια εργασία για ένα pixel δεν είναι τίποτα σπουδαίο για την CPU, αλλά (και εδώ είναι το πρόβλημα), η μικροσκοπική εργασία πρέπει να γίνει για κάθε pixel στην οθόνη! Αυτό σημαίνει πως σε μια παλιά οθόνη (με ανάλυση) 800x600, πρέπει σε κάθε frame (καρέ) να επεξεργαστούμε 480.000 pixels που σημαίνει 14.400.000 υπολογισμούς το δευτερόλεπτο! Ναι! Αυτό είναι ένα πρόβλημα αρκετά μεγάλο ώστε να καταβάλλει έναν επεξεργαστή. Σε μια σύγχρονη οθόνη retina 2880x1800 που ανανεώνεται στα 60 frames το δευτερόλεπτο, αυτός ο υπολογισμός καταλήγει σε 311.040.000 υπολογισμούς το δευτερόλεπτο. Πως λύνουν αυτό το πρόβλημα οι μηχανικοί των γραφικών?
![](03.jpeg)
Εδώ είναι που η παράλληλη επεξεργασία δίνει μια καλή λύση. Αντί να έχουμε λίγους μεγάλους και δυνατούς επεξεργαστές, η *σωλήνες*, είναι αποδοτικότερο να έχουμε πολλούς μικροσκοπικούς επεξεργαστές που λειτουργούν παράλληλα και ταυτόχρονα. Αυτό είναι μια Graphics Processing Unit (GPU) - (μονάδα επεξεργασίας γραφικών)
![GPU](04.jpeg)
Φανταστείτε τους μικρούς επεξεργαστές σαν ένα τραπέζει από σωλήνες, και τα δεδομένα για κάθε pixel σαν ένα μπαλάκι του πινγκ πονγκ. 14.400.000 μπάλες του πινγκ πονγκ το δευτερόλεπτο μπορούν να φράξουν λίγο - πολύ οποιοδήποτε σωλήνα. Αλλά ένα τραπέζι από 800x600 μικρούς σωλήνες από τους οποίους περνάνε 30 κύματα των 480.000 pixels το δευτερόλεπτο είναι κάτι που μπορούμε να διαχειριστούμε με άνεση. Αυτό δουλεύει με τον ίδιο τρόπο σε υψηλότερες αναλύσεις - όσο περισσότερο παράλληλο hardware (υλικό) διαθέτουμε, τόσο μεγαλύτερη η ροή που μπορεί να διαχειριστεί.
Άλλη μια "σούπερ δύναμη" των GPU είναι πως επιταχύνουν μέσω hardware ειδικές μαθηματικές συναρτήσεις, ώστε περίπλοκες μαθηματικές πράξεις επιλύονται κατευθείαν στο microchip, αντί για το software (λογισμικό). Αυτό σημαίνει εξαιρετικά γρήγορες πράξεις τριγωνομετρίας και άλγεβρας πινάκων - σε ταχύτητες που περιορίζονται μόνο από την ταχύτητα του ηλεκτρισμού.
## Τι είναι η GLSL;
GLSL σημαίνει OpenGL Shading Language (γλώσσα περιγραφής shaders της OpenGL), η οποία είναι το συγκεκριμένο πρότυπο για προγράμματα shaders που θα δείτε στα επόμενα κεφάλαια. Υπάρχουν και άλλοι τύποι shaders ανάλογα με το hardware και το Λειτουργικό Σύστημα. Εδώ θα δουλέψουμε με το πρότυπο OpenGL όπως το ορίζει το [Khronos Group](https://www.khronos.org/opengl/). Κάποια γνώση της ιστορίας της OpenGL μπορεί να φανέι χρήσιμη στο να καταλάβουμε αρκετές από τις περίεργες συμβάσεις της, και γι' αυτό προτείνω να ρίξετε μια ματιά στο: [openglbook.com/chapter-0-preface-what-is-opengl.html](http://openglbook.com/chapter-0-preface-what-is-opengl.html)
## Γιατί έχουν οι Shaders τη φήμη πως είναι δύσκολοι;
Όπως είπε και ο Θείος Ben "η μεγάλη δύναμη απαιτεί μεγάλη υπευθυνότητα", και η παράλληλη επεξεργασία ακολουθεί αυτό τον κανόνα. Ο ισχυρός αρχιτεκτονικός σχεδιασμός της GPU φέρνει τους δικούς του περιορισμούς και κανόνες.
Προκειμένου να λειτουργεί παράλληλα, κάθε σωλήνας - ή thread (νήμα) - πρέπει να είναι ανεξάρτητο από κάθε άλλο thread. Λέμε πως τα threads είναι *τυφλά* ως προς το τι κάνουν τα άλλα threads. Αυτός ο περιορισμός υπονοεί πως όλα τα δεδομένα κινούνται προς την ίδια κατεύθυνση. Κατά συνέπεια, είναι αδύνατο να δούμε το αποτέλεσμα ενός άλλου thread, να αλλάξουμε τα δεδομένα εισόδου, ή να οδηγήσουμε το αποτέλεσμα ενός thread σε ένα άλλο thread. Το να επιτρέψουμε επικοινωνία μεταξύ threads, βάζει σε κίνδυνο τη συνέπεια των δεδομένων.
Επίσης, η GPU κρατάει τον παράλληλο επεξεργαστή (τους σωλήνες) διαρκώς απασχολημένο. Μόλις αποδεσμευτούν, παίρνουν καινούριες πληροφορίες για επεξεργασία. Είναι αδύνατο για ένα thread να ξέρει τι έκανε μια στιγμή νωρίτερα. Θα μπορούσε να ζωγραφίζει ένα κουμπί για το UI (διεπαφή χρήστη) του λειτουργικού συστήματος, μετά να ζωγραφίζει ένα τμήμα του ουρανού για κάποιο παιχνίδι, μετά να δείχνει το κείμενο ενός email. Κάθε thread δεν είναι μόνο **τυφλό**, αλλά και **χωρίς μνήμη**. Εκτός από την αφαίρεση που απαιτείται για να γράψουμε (σε κώδικα) μια γενική συνάρτηση που αλλάζει το αποτέλεσμα ενός pixel τη φορά βάσει της θέσης του, οι περιορισμοί "τυφλότητας" και "έλλειψης μνήμης" (του thread) κάνουν τους λιγότερο έμπειρους προγραμματιστές να αποφεύγουν τους shaders.
Μην ανησυχείτε! Στα επόμενα κεφάλαια, θα μάθουμε βήμα - βήμα πως να πάμε από απλούς σε προχωρημένους υπολογισμούς με shaders. Αν διαβάζετε αυτό το κείμενο σε έναν σύγχρονο browser, θα μπορέσετε να παίξετε με τα διαδραστικά παραδείγματα. Ας μην καθυστερούμε άλλο τη διασκέδαση λοιπόν, πατήστε *Next >>* για να κάνουμε βουτιά κατ' ευθείαν στον κώδικα!

@ -0,0 +1,2 @@
# Ξεκινώντας
## Τί είναι ένας fragment shader (φωτοσκιαστής τεμαχίων);

@ -0,0 +1,53 @@
## Hello World
Συνήθως το παράδειγμα "Hello world!" είναι το πρώτο βήμα για να μάθει κανείς μια νέα γλώσσα. Είναι ένα απλό πρόγραμμα της μιας γραμμής που τυπώνει ένα ενθουσιώδες καλοσώρισμα και αναγέλλει τις δυνατότητες που μας περιμένουν.
Στη χώρα της GPU, ο σχεδιασμός χαρακτήρων είναι μια υπερβολικά περίπλοκη εργασία για πρώτο βήμα, οπότε θα προτιμήσουμε ένα φωτεινό φιλόξενο χρώμα για να διακυρήξουμε τον ενθουσιασμό μας!
<div class="codeAndCanvas" data="hello_world.frag"></div>
Αμ διαβάζετε αυτό το κείμενο σε browser, το προηγούμενο τμήμα κώδικα είναι διαδραστικό. Αυτό σημαίνει πως μπορείτε να κάνετε κλικ και να αλλάξετε όποιο μέρος του κώδικα θέλετε να εξερευνήσετε. Οι αλλαγές θα γίνουν άμεσα ορατές χάρη στην αρχιτεκτονική της GPU που μεταγλωττίζει (compiles) και αντικαθιστά τους shaders "στον αέρα". Κάντε μια δοκιμή να αλλάξετε τις τιμές στη γραμμή 8.
Αν και αυτές οι απλές γραμμές κώδικα δε δείχνουν τίποτα σπουδαίο, μπορούμε να εξάγουμε σημαντικές γνώσεις από αυτές:
1. Η γλώσσα των shaders έχει μια μοναδική συνάρτηση `main` που επιστρέφει ένα χρώμα στο τέλος, παρόμοια με τη C.
2. Το τελικό χρώμα του pixel ανατίθεται (γράφεται) στην δεσμευμένη (reserved) καθολική μεταβλητή `gl_FragColor`.
3. Αυτή η παρόμοια-με-C γλώσσα έχει ενσωματωμένες *μεταβλητές* (όπως η `gl_FragColor`), *συναρτήσεις* και *τύπους*. Σε αυτό το παράδειγμα συστηθήκαμε μόνο με το `vec4` που αντιπροσωπεύει ένα διάνυσμα 4 διαστάσεων και ακρίβειας τύπου μονής κινητής υποδιαστολής (float). Αργότερα θα δούμε και άλλους τύπους όπως `vec3` και `vec2` όπως και τους γνωστούς: `float`, `int` και `bool`.
4. Αν παρατηρήσουμε τον τύπο `vec4` μπορούμε να συμπεράνουμε οτι τα τέσσερα μέρη αντιστοιχούν στα κανάλια χρώματος RED, GREEN, BLUE και ALPHA. Επίσης μπορούμε να δούμε πως οι τιμές τους είναι *κανονικοποιημένες*, που σημαίνει πως το εύρος τους είναι από `0.0` ως `1.0`. Αργότερα θα δούμε πως η κανονικοποίηση των τιμών μας διευκολύνει στο να αντιστοιχίζουμε τιμές ανάμεσα σε μεταβλητές.
5. Άλλο ένα σημαντικό *χαρακτηριστικό σαν της C* που βλέπουμε σε αυτό το παράδειγμα είναι η ύπαρξη preprocessor macros (μακροεντολών προεπεξεργαστή). Οι macros είναι μέρος ενός βήματος προ-μεταγλώττισης. Με αυτές μπορούμε να ορίσουμε (`#define`) καθολικές μεταβλητές και να κάνουμε κάποιες βασικές επιλογές υπό συνθήκη (conditional operations - με `#ifdef` και `#endif`). Όλες οι μακροεντολές ξεκινάνε με ένα hashtag (`#`). Η προ-μεταγλώττιση συμβαίνει ακριβώς πριν τη μεταγλώττιση, και αντιγράφει όλες τις κλήσεις σε `#defines` και ελέγχει τις συνθήκες `#ifdef` (κάτι είναι ορισμένο) και `#ifndef` (κάτι δεν είναι ορισμένο). Στο "hello world!" παράδειγμά μας παραπάνω, προσθέσαμε μόνο τη γραμμή 2 (αν έχει οριστεί η `GL_ES`), το οποίο κυρίως συμβαίνει όταν ο κώδικας μεταγλωττίζεται σε φορητές συσκευές και browsers.
6. Οι τύποι κινητής υποδιαστολής είναι απαραίτητοι στους shaders, οπότε και το επίπεδο *ακρίβειας* είναι καίριο. Χαμηλότερη ακρίβεια σημαίνει γρηγορότερη απεικόνιση (rendering), αλλάμ με κόστος σε ποιότητα. Μπορείτε να είστε επιλεκτικοί και να προσδιορίσετε την ακρίβεια σε κάθε μεταβλητή που χρησιμοποιεί κινητή υποδιαστολή. Στη δεύτερη γραμμή (`precision mediump float;`) θέτουμε όλους τους floats σε μέση ακρίβεια. Μπορούμε επίσης να αποφασίσουμε να τους θέσουμε σε χαμηλή (`precision lowp float;`) ή υψηλή (`precision highp float;`).
7. Η τελευταία, και ίσως πιο σημαντική λεπτομέρεια είναι πως το πρότυπο της GLSL δεν εγγυάται πως όλες οι μεταβλητές μετατρέπονται αυτόματα. Τι σημαίνει αυτό; Οι κατασκευαστές έχουν διαφορετικές προσεγγίσεις στο να επιταχύνουν τις διεργασίες των καρτών γραφικών, αλλά είναι υποχρεωμένοι να εγγυηθούν κάποιες ελάχιστες προδιαγραφές. Η αυτόματη μετατροπή δεν είναι μια απο αυτές. Στο “hello world!” παράδειγμά μας, το `vec4` έχει ακρίβεια float (μονής κινητής υποδιαστολής), οπότε περιμένει να του αναθέσουμε `float` τιμές. Αν θέλετε να έχετε καλό και σταθερό κώδικα αντί να ξοδεύετε ώρες προσπαθώντας να διορθώσετε (debug) λευκές οθόνες, συνηθίστε να βάζετε την υποδιαστολή (`.`) στους floats σας. Κώδικας σαν κι αυτόν δε δουλεύει πάντα σωστα:
```glsl
void main() {
gl_FragColor = vec4(1,0,0,1); // ERROR
}
```
Τώρα που περιγράψαμε τα πιο απαραίτητα στοιχεία του "hello world!" προγράμματός μας, ώρα να κάνετε κλικ στο τμήμα κώδικα και να αρχίσετε να δοκιμάζετε όλα όσα μάθαμε. Θα διαπιστώσετε πως σε περίπτωση λαθών το πρόγραμμα δεν θα μεταγλωττιστεί, και θα δείξει μια λευκή οθόνη. Υπάρχουν μερικά πράγματα να δοκιμάσετε, για παράδειγμα:
* Δοκιμάστε να αντικαταστήσετε τους float με integers, η κάρτα γραφικών σας ίσως να μην ανεχτεί αυτή τη συμπεριφορά!
* Δοκιμάστε να βάλετε σε σχόλια τη γραμμή 8 και να μη δώσετε τιμή για το pixel στη συνάρτηση
* Δοκιμάστε να φτιάξετε μια ξεχωριστή συνάρτηση που επιστρέφει ένα συγκεκριμένο χρώμα και να την καλέσετε μέσα στη `main()`. Σα βοήθημα, αυτός είναι ο κώδικας μιας συνάρτησης που επιστρέφει κόκκινο:
```glsl
vec4 red(){
return vec4(1.0,0.0,0.0,1.0);
}
```
* Υπάρχουν διάφοροι τρόποι για να αρχικοποιήσετε τυπους `vec4`, δοκιμάστε να ανακαλύψετε και άλλους. Ο ακόλουθος είνα ένας από αυτούς:
```glsl
vec4 color = vec4(vec3(1.0,0.0,1.0),1.0);
```
Αν και αυτό το παράδειγμα δεν είναι ιδιαίτερα ενδιαφέρον, είναι το πιο βασικό - αλλάζουμε όλα τα pixels μέσα στον καμβά (για την ακρίβεια στο canvas element) στο ίδιο ακριβώς χρώμα. Στο επόμενο κεφάλαιο θα δούμε πως να αλλάζουμε το χρώμα κάθε pixel χρησιμοποιώντας δύο τύπους εισόδου: το χώρο (τη θέση του pixel στην οθόνη) και το χρόνο (τον αριθμό των δευτερολέπτων από τη στιγμή που φορτώθηκε η σελιδα).
Loading…
Cancel
Save