Skip to content

TunnelEffect

Source: TunnelEffect.h

TunnelEffect

class TunnelEffect
src/light/effects/TunnelEffect.h:27

Inherits: EffectBase

Effect: a texture-mapped tunnel flying toward a vanishing point.

TunnelEffect card TunnelEffect controls

A texture mapped onto the inside of an infinite tube, so the viewer flies down it forever. Nothing here is 3D: perspective costs one divide.

Prior art: the standard demoscene tunnel, and Inigo Quilez's write-ups of it.

Public Attributes

uint8_t bpm = 20 : How fast the tunnel flies past.

uint8_t depth = 60 : Texture scale along the tunnel, shadowing EffectBase::depth(), which is qualified below.

uint8_t twist = 40 : Rotation per unit depth, so the tunnel corkscrews.

uint8_t segments = 1 : Kaleidoscope the wall, where 1 leaves it plain.

uint8_t octaves = 2 : Wall texture detail, and the cost knob.

bool vignette = true : Darken toward the vanishing point, so it reads as receding.

PolarLut::Controls polar : The polar address: the table, its precision, and how a volumetric fixture maps to angle and radius.

Public Methods

virtual inline const char * tags() const override : Catalog tags: this effect is the power-function showcase.

virtual inline Dim dimensions() const override : Volumetric: the wall recedes through depth.

virtual inline void defineControls() override : Publish the flight, the wall's texture and the polar address.

virtual inline void prepare() override : Build the polar address table for the current geometry.

virtual inline void tick() override : Map the wall per pixel from its angle and the reciprocal of its distance.

More info

Angle and reciprocal are the two texture coordinates

Each pixel's angle around the center becomes one coordinate, and 1/r the other. Since 1/r grows without bound toward the center, the texture compresses to a vanishing point. Adding time to that coordinate then pulls the wall toward the viewer.

This is the polar vocabulary carried to its conclusion, with one reciprocal on top of it. EchoEffect holds the gather primitive instead, reading the grid itself as a texture.

Cost: one divide, one atan and one noise sample a pixel, the divide being the expensive part.