Hier ist, wie ich das machen würde. Stellen Sie zunächst sicher, dass Ihnen die UVs oder Weltkoordinaten des Objekts (die Sie von Ihrem Vertex-Shader aus durchlaufen können) zur Verfügung stehen. Wenn es sich nur um einen Hintergrund handelt, können Sie auch nur Fragmentkoordinaten ( gl_FragCoord
) verwenden.
Nehmen wir zum Beispiel an, wir verwenden UV-Koordinaten. Ein Fragment-Shader mit nur:
gl_FragColor = vec4(vec3(uv.x),1.0);
sieht ungefähr so aus:
Und ähnlich gl_FragColor = vec4(vec3(uv.y),1.0);
wird es aussehen wie:
Wenn Sie Weltkoordinaten oder Fragmentkoordinaten verwenden, können Sie trotzdem skalieren und übersetzen, um auf (0,0) -> (1, 1) zu normalisieren. Wir müssen jedoch trotzdem erneut skalieren und übersetzen, damit Sie überspringen können dieser Schritt. Stellen Sie stattdessen sicher, dass Ihre Koordinaten zwischen (-1,0, -1,0) und (1,0, 1,0) liegen, um die nächsten Schritte zu vereinfachen.uv = 2.0 * uv - 1.0;
Bevor wir weiter gehen, machen wir einen supereinfachen radialen Gradienten. Denken Sie daran, dass die Gleichung eines Kreises x² + y² = r² ist. Wenn Sie also die transformierten UVs als Koordinatensystem verwenden, kann ein Einheitskreis (r = 1) erstellt werden, der ungefähr so gl_FragColor = vec4(vec3(uv.x * uv.x + uv.y * uv.y),1.0);
aussieht:
Der nächste Schritt ist die Animation. Dazu müssen Sie nur mit dem Wert "r" herumspielen und den Radius ändern. Sie müssen sich keine Gedanken über das Festklemmen von Farbwerten zwischen 0,0 und 1,0 machen, da dies ohnehin automatisch geschieht.
Alles in allem würde es ungefähr so aussehen:
uniform vec2 screenSize;
uniform float time;
void main(void) {
// Scale to UV space coords
vec2 uv = gl_FragCoord.xy / screenSize;
// Transform to [(-1.0, -1.0), (1.0, 1.0)] range
uv = 2.0 * uv - 1.0;
// Have something to vary the radius (can also just be a linear counter (time))
float wave = sin(time);
// Calculate how near to the center (0.0) or edge (1.0) this fragment is
float circle = uv.x * uv.x + uv.y * uv.y;
// Put it all together
gl_FragColor = vec4(vec3(circle + wave),1.0);
}
Natürlich können Sie viele Dinge vereinfachen und viel mehr mit den Variablen und Konstanten herumspielen. Hier ist eine Live-Demo von mir, die genau das tut: https://www.shadertoy.com/view/4sjXWh
Bearbeiten:
Wenn Sie dies mit verschiedenen Farben tun möchten, gibt es zum Glück eine einfache Lösung! Übergeben Sie Ihre Farben als Uniformen (oder codieren Sie sie im eigentlichen Fragment-Shader fest) und ändern Sie die letzte Zeile in folgende:
gl_FragColor = mix(color1, color2, circle + wave);
color1
und color2
sind beide vec4
s. Hier ist das in Aktion: https://www.shadertoy.com/view/XsjSW1