# Render Modes

```ts
import { createGlyphPerspectiveCamera, createGlyphScene, createGlyphOrbitControls } from "glyphcss";
import { loadMesh, recenterPolygons } from "@glyphcss/core";

const host = document.getElementById("scene");
const camera = createGlyphPerspectiveCamera({ rotX: 65, rotY: 0, zoom: 0.3, distance: 0, perspective: 32000, stretch: 1 });
const scene = createGlyphScene(host, { camera, autoSize: true, mode: "solid", colorEncoding: "spans" });
scene.output.style.fontSize = "10px";
scene.output.style.lineHeight = "1";
scene.fit();
const { polygons } = await loadMesh("/gallery/glb/Horse.glb", { solidTextureSamples: false });
scene.add(recenterPolygons(polygons));
createGlyphOrbitControls(scene, { drag: true, wheel: true });
```



Switch modes on the same object, then drag to orbit. Code follows the selection. Set scene `mode` through `createGlyphScene`, `GlyphScene`, or `<glyph-scene>`; a mesh can override it with its own layer.

| Mode | Appearance / use |
|---|---|
| `wireframe` | All polygon edges; geometric cages and line art |
| `solid` | Filled surfaces with a shaded glyph ramp; default mode |
| `ink` | Silhouettes and crease outlines; empty interiors |
| `voxel` | Currently uses wireframe rasterization; no dedicated voxel density mapping |

## Character encoding (`charMode`)



```ts
import { createGlyphPerspectiveCamera, createGlyphScene, createGlyphOrbitControls } from "glyphcss";
import { loadMesh, recenterPolygons } from "@glyphcss/core";

const host = document.getElementById("scene");
const camera = createGlyphPerspectiveCamera({ rotX: 65, rotY: 0, zoom: 0.3, distance: 0, perspective: 32000, stretch: 1 });
const scene = createGlyphScene(host, { camera, autoSize: true, mode: "wireframe", charMode: "braille", colorEncoding: "spans" });
scene.output.style.fontSize = "10px";
scene.output.style.lineHeight = "1";
scene.fit();
const { polygons } = await loadMesh("/gallery/glb/Shark.glb", { solidTextureSamples: false });
scene.add(recenterPolygons(polygons));
createGlyphOrbitControls(scene, { drag: true, wheel: true });
```



Braille draws up to eight dots per cell for smoother wireframe edges. ASCII uses the selected glyph palette.



```ts
import { createGlyphPerspectiveCamera, createGlyphScene, createGlyphOrbitControls } from "glyphcss";
import { loadMesh, recenterPolygons } from "@glyphcss/core";

const host = document.getElementById("scene");
const camera = createGlyphPerspectiveCamera({ rotX: 65, rotY: 0, zoom: 0.3, distance: 0, perspective: 32000, stretch: 1 });
const scene = createGlyphScene(host, { camera, autoSize: true, mode: "solid", charMode: "quadrant", colorEncoding: "spans" });
scene.output.style.fontSize = "10px";
scene.output.style.lineHeight = "1";
scene.fit();
const { polygons } = await loadMesh("/gallery/glb/Frog.glb", { solidTextureSamples: false });
scene.add(recenterPolygons(polygons));
createGlyphOrbitControls(scene, { drag: true, wheel: true });
```



| `charMode` | Supported mode | What changes |
|---|---|---|
| `"ascii"` (default) | All | One ramp or edge glyph per cell |
| `"braille"` | Wireframe | 2×4 dot coverage |
| `"halfblock"` | Solid | Two vertically stacked colors per cell |
| `"quadrant"` | Solid | 2×2 coverage with up to two colors per cell |

Unsupported combinations are no-ops. Halfblock and quadrant are also inactive with `transformCells` or active `temporalBlend`. Uncovered subcells keep a transparent background. These encodings require a font with the corresponding Unicode glyphs.

## Box-drawing junctions (`wireframeJunctions`)



```ts
import { createGlyphPerspectiveCamera, createGlyphScene, createGlyphOrbitControls } from "glyphcss";
import { resolveGeometry } from "@glyphcss/core";

const host = document.getElementById("scene");
const camera = createGlyphPerspectiveCamera({ rotX: 0, rotY: 0, zoom: 0.3, distance: 0, perspective: 32000, stretch: 1 });
const scene = createGlyphScene(host, { camera, autoSize: true, mode: "wireframe", wireframeJunctions: true, colorEncoding: "spans" });
scene.output.style.fontSize = "10px";
scene.output.style.lineHeight = "1";
scene.fit();
const polygons = resolveGeometry("cube", { size: 100 });
scene.add(polygons);
createGlyphOrbitControls(scene, { drag: true, wheel: true });
```



Enable junctions for connected corners and crossings (`┌┐└┘├┤┬┴┼─│`). Default: `false`. Applies only to near-axis-aligned ASCII wireframe edges; diagonal strokes keep their usual glyphs. Runtime-only.

## Hidden-line removal (`hiddenLines`)



```ts
import { createGlyphPerspectiveCamera, createGlyphScene, createGlyphOrbitControls } from "glyphcss";
import { resolveGeometry } from "@glyphcss/core";

const host = document.getElementById("scene");
const camera = createGlyphPerspectiveCamera({ rotX: 65, rotY: 0, zoom: 0.3, distance: 0, perspective: 32000, stretch: 1 });
const scene = createGlyphScene(host, { camera, autoSize: true, mode: "wireframe", hiddenLines: "hide", colorEncoding: "spans" });
scene.output.style.fontSize = "10px";
scene.output.style.lineHeight = "1";
scene.fit();
const polygons = resolveGeometry("cuboctahedron", { size: 100 });
scene.add(polygons);
createGlyphOrbitControls(scene, { drag: true, wheel: true });
```



Choose `"hide"` to suppress strokes behind nearer surfaces; default `"show"` keeps them. Works with ASCII/Braille wireframe and ink. Solid already depth-tests its cells. Accepted by `compileScene` and `GlyphSceneStatic` too.

## Solid shading and weights

```ts
scene.setOptions({ smoothShading: true, creaseAngle: 60 });
```

Solid uses flat shading by default. Smooth shading averages vertex normals across creases up to `creaseAngle` degrees. Lighting and palette options are listed in [GlyphScene](/components/glyph-scene/).

```ts
import { calibrateWeightedGlyphRamp } from "@glyphcss/effects";
const { steps } = calibrateWeightedGlyphRamp({
  font: { family: "monospace", size: 32 }, steps: 24, weights: [400, 700],
});
scene.setOptions({ solidWeightRamp: steps.map(({ glyph, weight }) => ({ glyph, weight: Number(weight) })) });
```

`solidWeightRamp` replaces the solid glyph ramp with glyph/weight steps ordered darkest → densest. Default: unset. Inactive outside solid, with halfblock/quadrant, or during temporal blending. Also accepted by `compileScene`; custom elements take it as a JavaScript property.

## Shadows

```tsx
<GlyphScene mode="solid" shadow={{ color: "#000000", opacity: 0.25, lift: 0.05 }}>
  <GlyphMesh geometry="cube" castShadow receiveShadow />
  <GlyphGround />
</GlyphScene>
```

Place this scene inside a camera. Shadows are opt-in; each mesh must enable casting/receiving. `GlyphGround` receives by default. `lift` is a world-unit depth bias; scale it to your scene. `maxExtend` is accepted but has no effect.

Use the geometry selector in [creating shapes](/guides/creating-shapes/) or [load your own mesh](/guides/meshes/).
