Skip to content

Scene reference

magmacrunchmedia edited this page Aug 28, 2026 · 2 revisions

Scene reference

Everything a scene can contain. Declared in source/cpu_trace.h; scenes are built in code as designated initialisers, which means anything you leave out is zero, and zero is always the inert choice.

HoloScene scene = {
    .spheres = { { .center = {0, 1, 0}, .radius = 1,
                   .albedo = {0.85f, 0.25f, 0.35f} } },
    .sphere_count = 1,
    .has_floor = 1,
    .sun_dir = { 0, 1, 0 },
    .horizon = { 1, 0.9f, 0.8f },
    .zenith  = { 0.25f, 0.45f, 0.9f },
};

Capacities

HOLO_MAX_SPHERES 8
HOLO_MAX_RECTS 8
HOLO_MAX_DISHES 4
Gratings on the GPU 2 (see Shader constraints)

Counts are explicit: set sphere_count, rect_count, dish_count to the number you filled in. Raising a capacity means editing the #define, the HoloGpuScene struct, and the shader's cbuffer together.

Materials

Three shares that sum to at most 1, with the matte remainder shading as Lambert:

Field
mirror Metallic reflection, tinted by albedo; silver is a colour too.
transmit Glass. Fresnel splits this share between refraction and an untinted dielectric reflection, angle by angle, so a glass surface turns mirror-like at grazing incidence because the physics says so.
remainder 1 − mirror − transmit, shaded as Lambert against sun_dir with hard shadows and an ambient floor (HOLO_AMBIENT, 0.1).

HoloSphere

HoloV3 center;   float radius;
HoloV3 albedo;   float mirror;
float  transmit; float ior;      float disperse;

Glass in a sphere is a volume: rays bend in, bend out, and can be trapped by total internal reflection. ior is quoted at the sodium D line; disperse is Cauchy's B in µm² (0 = achromatic, ~0.0042 = BK7, 0.02–0.03 = dense flint).

HoloRect

HoloV3 corner;   HoloV3 edge_u, edge_v;    /* edge lengths are the size */
HoloV3 albedo;   float  mirror;
float  transmit; float  ior;     float disperse;
int    filter;   float  filter_angle;      float retard;
float  grating_period;  float grating_angle;  float order_w[4];

A parallelogram, not merely a rectangle: the intersection Gram-solves true affine coordinates, so skewed edges behave correctly. Glass in a rect is a thin pane: one Fresnel interface, no net bend. A window, not a prism.

As a filter

Set filter and the rect stops being a surface and becomes an optical element; mirror, transmit and ior are ignored.

filter
HOLO_FILTER_NONE Ordinary surface (default).
HOLO_POLARIZER Ideal linear polarizer along its axis.
HOLO_WAVEPLATE Retards p against s about its axis by retard radians at the D line, scaling as 1/λ the way a zero-order plate does, which is why a thick plate between crossed polarizers shows interference colour.

filter_angle is the axis, in radians from edge_u toward edge_v.

Polarization physics lives in the spectral pipeline. The RGB pipeline has no Stokes vector, so it approximates a polarizer as a flat 50% absorber and a waveplate as clear glass.

As a grating

Set grating_period in micrometres (1.2 is a spectroscopist's 833 lines/mm) and the rect becomes a reflection grating; the glass and filter fields are ignored.

grating_angle Groove direction, radians from edge_u toward edge_v. Grooves at 90° from a horizontal edge_u disperse horizontally.
order_w[4] Efficiency weights for orders m = −1, 0, +1, +2, in that order (holo_grating_m). Hand-set scalars, not computed; see The optics § grating.

Any order can be dropped by weighting it 0. The RGB pipeline, having no wavelength, shows only the zeroth (specular) order.

HoloDish

HoloV3 apex;   HoloV3 axis;    /* unit, out of the bowl */
float  curv_r; float  conic_k; float rim;
HoloV3 albedo; float  mirror;

A cap of a conic of revolution in optical-design parameters. curv_r is the vertex radius of curvature; a paraboloid (conic_k = −1) has focal length curv_r / 2 measured from the apex along axis. See The optics § conic surfaces for the K table.

Dishes are mirror or matte only. Curved refractive surfaces (lenses) are not implemented, and dishes do not currently cast shadows.

The world

Field
has_floor, floor_y An infinite y-up plane.
floor_a, floor_b The two colours of its 1 m checker.
floor_mirror A polished floor reflects a little; 0.12–0.15 reads well.
sun_dir Unit, pointing from the scene toward the sun.
horizon, zenith The sky gradient, mixed by 0.5·(dir.y + 1).
sun_disk_cos Cosine of the sun disk's angular radius (0.9994 ≈ 2°, 0.9962 ≈ 5°).
sun_disk_intensity Radiance inside the disk. 0 turns the disk off (the default).

The sun disk is what makes focusing visible: a mirror that sends your eye ray into the sun shows you the sun, and at a paraboloid's focus every point of the dish does. Use a fat disk (5°) for a walkable flash region, a small one for a surgical one.

Walking

Collision is a separate, simpler world: a capsule against axis-aligned boxes. It does not read the render scene, so a wall you can see and a wall you can walk into are two declarations. That is deliberate (mirror walls are paper-thin surfaces; their colliders are slabs), and it is the one place the engine asks you to repeat yourself.

HoloWalkWorld world = {
    .radius = 0.3f, .height = 1.7f, .gravity = 20.0f, .floor_y = 0.0f,
    .walls = { { .min = {-4.3f, 0, -6.3f}, .max = {-4.0f, 3, 6.3f} } },
    .wall_count = 1,
};
HoloWalker walker = { .pos = hv3(0, 0, 4.5f) };

HOLO_MAX_WALLS is 16. Movement resolves one axis at a time, which is what makes walking into a wall at an angle slide along it rather than stick. Spheres and dishes are not colliders, so you can currently walk through a glass ball.

Clone this wiki locally