
Shader Optimization TechniquesAdvanced
Practical tips for faster fragment and vertex shaders
ShadersPerformanceGLSLOptimization
Published on October 28, 2024
Shader performance can make or break a 3D experience. Here are battle-tested techniques for optimizing your GLSL shaders.
Branch Elimination
GPUs execute shaders in parallel, and branches can cause divergence:
// Bad: Branch causes divergence
if (condition) {
color = texture(tex1, uv);
} else {
color = texture(tex2, uv);
}
// Good: Both textures sampled, result selected
vec4 c1 = texture(tex1, uv);
vec4 c2 = texture(tex2, uv);
color = mix(c1, c2, float(condition));
Precision Qualifiers
Use the minimum precision needed:
// Full precision only when needed
highp float worldPosition;
mediump vec3 normal;
lowp vec4 color;
Precompute Constants
Move calculations out of loops and into uniforms when possible:
// Bad: Computed every fragment
float radius = sqrt(resolution.x * resolution.x + resolution.y * resolution.y);
// Good: Precomputed on CPU, passed as uniform
uniform float uDiagonalLength;
Texture Atlasing
Reduce texture switches by combining textures:
- Pack multiple images into one atlas
- Use channels efficiently (roughness in alpha, etc.)
- Consider array textures for similar-sized images
Measuring Performance
Use browser dev tools’ GPU profiler and:
- Test on target hardware
- Profile both vertex and fragment stages
- Watch for texture bandwidth bottlenecks