Τα shaders αποτελούν ένα εξαιρετικά δυνατό εργαλείο για τον σχεδιασμό web, προσφέροντας ζωντανά και διαδραστικά εφέ που προσελκύουν το ενδιαφέρον των χρηστών. Στο παρόν άρθρο, θα δούμε πώς μπορείτε να δημιουργήσετε ένα διακριτικό εφέ φόντου χρησιμοποιώντας το React Three Fiber και το Drei, σε τέσσερα απλά βήματα.
Βήμα 1: Δημιουργία Δικτύου με Κουκίδες
Το πρώτο βήμα είναι να ορίσουμε τη βάση του εφέ, ένα δίκτυο από κουκίδες, το οποίο θα είναι το σημείο εκκίνησής μας. Για αυτό το μοτίβο, χρησιμοποιούμε μία επίπεδη γεωμετρία (screen quad) και ένα custom shader. Η γεωμετρία αυτή είναι απλή, αφού δεν χρειάζεται τρισδιάστατη προβολή, κάνοντας τον κώδικα πιο εύκολο και λιγότερο απαιτητικό. Στον vertex shader, ορίζουμε τη θέση κάθε σημείου:
void main() {
gl_Position = vec4(position.xy, 0.0, 1.0);
}
Στη συνέχεια, ορίζουμε το fragment shader για το δίκτυο. Εδώ χρησιμοποιούμε τις συντεταγμένες της οθόνης (UV) για να καθορίσουμε τη θέση της κάθε κουκίδας.
void main() {
vec2 screenUv = gl_FragCoord.xy / resolution;
vec2 uv = coverUv(screenUv);
vec2 gridUv = fract(uv * gridSize);
gl_FragColor = vec4(gridUv.x, gridUv.y, 0.0, 1.0);
}
Με αυτόν τον κώδικα, το αποτέλεσμα θα εμφανίζεται σαν ένα δίκτυο από τετράγωνα. Για να μετατρέψουμε τα τετράγωνα σε στρογγυλές κουκίδες, θα χρησιμοποιήσουμε τη λειτουργία Signed Distance Function (SDF), η οποία υπολογίζει την απόσταση από το κέντρο κάθε κουκίδας.
float baseDot = sdfCircle(gridUv, radius);
gl_FragColor = vec4(vec3(baseDot), 1.0);
Βήμα 2: Δημιουργία Ίχνους Ποντικιού (Mouse Trail)
Το επόμενο βήμα είναι η προσθήκη ενός ίχνους που θα ακολουθεί την κίνηση του ποντικιού. Με τη βοήθεια της βιβλιοθήκης @react-three/drei, μπορούμε να αξιοποιήσουμε ένα έτοιμο hook που παρακολουθεί την κίνηση του ποντικιού και ενημερώνει τη θέση της κάθε κουκίδας. Το hook χρησιμοποιεί ένα καμβά 2D και το event onPointerMove
, παρέχοντας το event.uv
για να μας δείχνει πού βρίσκεται η κουκίδα σε σχέση με την κίνηση του ποντικιού.
Το mouse trail μπορεί να λειτουργήσει σαν μάσκα, επιτρέποντάς μας να δίνουμε έμφαση στις κουκίδες που “αγγίζει” ο δείκτης του ποντικιού. Έτσι, κάθε κουκίδα μπορεί να αλλάζει μέγεθος, χρώμα ή διαφάνεια όταν πλησιάζει το ποντίκι, δημιουργώντας έναν δυναμικό, διαδραστικό σχεδιασμό.
Βήμα 3: Η Μάσκα
Σε αυτό το βήμα, προσθέτουμε μία μάσκα που θα δώσει βάθος και ποικιλία στο εφέ φόντου. Αρχικά, ορίζουμε ένα κυκλικό gradient, το οποίο ξεκινά από το κάτω μέρος της οθόνης. Έπειτα, προσθέτουμε ένα γραμμικό gradient από πάνω προς τα κάτω και ένα ακόμη κυκλικό gradient που βασίζεται στον χρόνο, προσθέτοντας κινούμενη δυναμική.
Ο κώδικας για τη μάσκα μοιάζει ως εξής:
float circleMaskCenter = length(uv - vec2(0.70, 1.0));
float circleMask = smoothstep(0.4, 1.0, circleMaskCenter);
float circleAnimatedMask = sin(time * 2.0 + circleMaskCenter * 10.0);
float screenMask = smoothstep(0.0, 1.0, 1.0 - uv.y);
// Συνδυασμός των μασκών
float combinedMask = screenMask * circleMask;
Με τη μάσκα αυτή, μπορούμε να ελέγξουμε πόσο εμφανής ή αμυδρή είναι η κάθε κουκίδα, δίνοντας ένα βάθος και μια αίσθηση προοπτικής στο εφέ.
Βήμα 4: Σύνθεση του Τελικού Εφέ
Τώρα που έχουμε τις βασικές δομές, είμαστε έτοιμοι για τη σύνθεση του τελικού εφέ. Θα καθορίσουμε τα χρώματα του φόντου και των κουκίδων, και θα επιλέξουμε πώς θα αλληλεπιδρούν οι διαφορετικές στρώσεις του εφέ με τη μάσκα και το ίχνος του ποντικιού.
Ορίστε ένα παράδειγμα σύνθεσης για το τελικό αποτέλεσμα:
float mouseInfluence = texture2D(mouseTrail, gridUvCenterInScreenCoords).r;
float scaleInfluence = max(mouseInfluence * 0.5, circleAnimatedMask * 0.3);
float opacityInfluence = max(mouseInfluence * 15.0, circleAnimatedMask * 0.5);
float sdfDot = sdfCircle(gridUv, dotSize * (1.0 + scaleInfluence * 0.5));
float smoothDot = smoothstep(0.05, 0.0, sdfDot);
vec3 composition = mix(bgColor, dotColor, smoothDot * combinedMask * dotOpacity * (1.0 + opacityInfluence));
gl_FragColor = vec4(composition, 1.0);
Σε αυτό το στάδιο, είναι σημαντικό να προσαρμόσουμε τη χρωματική απόδοση του εφέ χρησιμοποιώντας tone mapping, για να εξασφαλίσουμε ότι τα χρώματα εμφανίζονται σωστά στον τελικό καμβά. Η βιβλιοθήκη threejs προσφέρει έτοιμα κομμάτια κώδικα που μπορούν να συμπεριληφθούν για αυτή τη διαδικασία.
#include <tonemapping_fragment>
#include <colorspace_fragment>
Με αυτά τα τέσσερα βήματα, μπορείτε να δημιουργήσετε ένα εντυπωσιακό, διακριτικό εφέ φόντου που αντιδρά με την κίνηση του χρήστη. Αυτό το εφέ μπορεί να αναβαθμίσει τη σχεδιαστική εμπειρία του χρήστη, προσδίδοντας ζωντάνια και μοντέρνα αίσθηση σε οποιοδήποτε website.
Ελπίζουμε αυτός ο οδηγός να σας ενέπνευσε για νέες ιδέες στον δημιουργικό σας σχεδιασμό.