Black Hole Shader

September 2024
  • WebGL
  • Typescript

Overview

This is a live, interactive vertex and fragment shader which deforms and colors a simple icosahedron sphere using various noise and smoothstep functions. The main noises I used were a standard FBM noise composed of gradient/Perlin layers at different frequencies, plus Worley noise. Additionally, GUI controls adjust noise parameters to make the scene more interactive.

Black Hole Mode (mode = 0)

VERTEX SHADER: The base structure is simply a bias displacement along the XZ plane, scaled by the "rad" control. On top of that, a simple noise adds variation. To get that vortex look, the x and z positions are offset via polar coordinates, a strength parameter, and time. A final layer of time-offset FBM noise adds details. This final noise is also passed into the fragment shader for coloring.

FRAGMENT SHADER: The fragment shader uses iterative lerp calls with the distance from the origin and a fresnel effect to color the center of the black hole while preserving the outer ring. The outer color comes from a procedural cosine-based color palette (thanks to IQ), plus additional camera falloff for the center. The “t” value in this palette is the noise passed from the vertex shader, giving a swirling color pattern.

Black Hole - First View
Black Hole deformation
Black Hole - Second View
Black Hole angle

White Hole Mode (mode = 1)

VERTEX SHADER: Mostly similar to the black hole mode except the base xz displacement vector is altered with a lerp using the cross product between the surface normal and the view vector. This creates a “weird warping” effect that spirals outward, controlled by time. A triangle wave displacement is added for extra detail around the edges.

FRAGMENT SHADER: Similar to the black hole mode but reversed inside/out. The center color palette is inverted, giving a white center and colored edges.

White Hole - First View
White Hole color variation
White Hole - Second View
White Hole deformation

Background

The background is a large cube surrounding the scene. The vertex shader remains static. In the fragment shader, a step function with Worley noise isolates small points of light for a starry background. Some additional procedural color noise is layered to enhance the effect.