Understanding WebGL from Scratch: Color Manipulation and Shader Techniques
This tutorial explores color manipulation in WebGL fragment shaders, demonstrating how to apply RGBA values, create gradient effects using coordinate mapping and cubic Bezier curves, and implement HSB color space conversions to achieve dynamic and visually complex rendering results.
This article continues the WebGL tutorial series by focusing on color manipulation within fragment shaders. It begins by explaining how the FragColor output uses RGBA values to render solid colors and coordinate-based gradients on the canvas.
The tutorial demonstrates how to apply distance fields for advanced color styling and introduces the glsl_doodle library, which extends gl_renderer by supporting the #pragma include directive for loading external modules and built-in uniforms prefixed with dd_.
Code example for basic color output:
#version 300 es
precision highp float;
out vec4 FragColor;
uniform vec2 resolution;
void main() {
FragColor.rgb = vec3(1.0, 0, 0);
FragColor.a = 1.0;
}Next, the article explores gradient shaping by controlling the interpolation process with mathematical functions. It provides a practical example using cubic Bezier curves to modulate color transitions between two specified colors, alongside coordinate transformations to polar systems for radial effects.
Code example for gradient shaping with Bezier curves:
#version 300 es
precision highp float;
#pragma include
#pragma include
#pragma include
out vec4 FragColor;
uniform vec2 dd_resolution;
uniform float dd_time;
uniform vec3 fromColor;
uniform vec3 toColor;
uniform vec4 bezierController;
float cubic_bezier(float x, vec4 p) {
return cubic_bezier(x, p.x, p.y, p.z, p.w);
}
float cubic_bezier(float x) {
return cubic_bezier(x, bezierController);
}
void main() {
vec2 st = gl_FragCoord.xy / dd_resolution;
float d = cubic_bezier(st.x);
FragColor.rgb = mix(fromColor, toColor, d);
float d2 = PLOT(cubic_bezier, st, 0.01);
FragColor.rgb += stroke(d2, 0.01, 0.2);
FragColor.a = 1.0;
}The tutorial then introduces the HSB (Hue, Saturation, Brightness) color model as an alternative to RGB, providing the mathematical conversion formulas between the two spaces. By mapping RGB channels to polar coordinates, developers can easily generate continuous hue gradients and construct dynamic color wheels.
Code example for HSB color wheel generation:
#version 300 es
precision highp float;
#define WEBGL2;
#pragma include
#pragma include
#pragma include
uniform vec2 dd_resolution;
uniform float dd_time;
uniform float fromColor;
uniform float toColor;
uniform vec4 bezierController;
void main() {
vec2 st = gl_FragCoord.xy / dd_resolution;
st = polar(st);
FragColor.rgb = hsb2rgb(vec3(0.5 * st.y / PI +0.5,st.x,1.0));
FragColor.a = 1.0;
}The article concludes by encouraging readers to practice these foundational color techniques before advancing to more complex rendering topics in subsequent chapters, and provides references to the gl_render and glsl_doodle repositories along with their module documentation.
ByteFE
Cutting‑edge tech, article sharing, and practical insights from the ByteDance frontend team.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.