Visual Renderables & Trails
Once a SceneGraphNode is positioned in space, its Renderable block determines how it appears visually. Below are the most common renderable types used in custom show assets.
3D Models (RenderableModel)
OpenSpace supports .obj, .fbx, .gltf, .glb, and .dae meshes via Assimp.
Renderable = {
Type = "RenderableModel",
GeometryFile = asset.localResource("spacecraft.glb"),
ModelScale = 1.0, -- Adjust if exported in cm/km instead of meters
EnableFaceCulling = true,
LightSources = {
{
Identifier = "Sun",
Type = "SceneGraphLightSource",
Node = "Sun",
Intensity = 1.0
}
}
}
Fixing Dark or Invisible Models
If a custom 3D model loads completely black, verify two things: (1) a LightSources block referencing "Sun" (or a CameraLightSource) is included, and (2) the model's scale isn't microscopic (0.001) or inverted inside-out (EnableFaceCulling = false helps diagnose flipped normals).
Image Planes & Billboards
Use image planes for mission patches, deep-sky astrophotography, or surface callout markers:
RenderablePlaneImageLocal: Renders a flat textured quad oriented in 3D space (ideal for deep-sky plates aligned to celestial coordinates).- Camera-Facing Billboards: Set
Billboard = true(or useRenderableScreenSpaceImageLocalfor HUD overlays) so labels and icons always face the viewer regardless of camera orbit angle.
Renderable = {
Type = "RenderablePlaneImageLocal",
Size = 50000, -- Width/Height in meters
Texture = asset.localResource("nebula_plate.png"),
BlendMode = "Additive", -- "Normal" for opaque, "Additive" for glowing astronomical imagery
Billboard = false
}
Orbital Trails (RenderableTrailTrajectory vs. RenderableTrailOrbit)
OpenSpace distinguishes between fixed-window trajectories (spacecraft missions with a start and end date) and closed/periodic orbits (planets, moons, and satellites):
Draws a path between explicit StartTime and EndTime bounds—required for SpiceTranslation spacecraft:
Renderable = {
Type = "RenderableTrailTrajectory",
Translation = {
Type = "SpiceTranslation",
Target = "JUNO",
Observer = "JUPITER BARYCENTER"
},
Color = { 0.95, 0.55, 0.15 },
StartTime = "2016 JUL 05 00:00:00",
EndTime = "2025 SEP 15 00:00:00",
SampleInterval = 3600, -- Resolution in seconds (smaller = smoother curves)
LineWidth = 2.5
}
Draws a continuous closed-loop trail with a fading tail behind an orbiting body:
Renderable = {
Type = "RenderableTrailOrbit",
Translation = {
Type = "GPTranslation",
TLEFile = asset.localResource("iss.tle")
},
Color = { 0.2, 0.8, 1.0 },
Period = 5560, -- Full orbital period in seconds (~92.6 min for ISS)
Resolution = 200, -- Number of vertices along the orbit
LineFade = 0.75 -- 0.0 = solid ring, 1.0 = full gradient fade
}
Screenshot Placeholder: trail-renderables-comparison.png
- Crop: Capture a side-by-side or annotated viewport comparison showing a
RenderableTrailOrbitwithLineFadeactive versus a multi-yearRenderableTrailTrajectorycurve. - Callouts: (1) Active spacecraft position node, (2)
SampleIntervalcurve smoothness, (3)LineFadegradient tail.
Labels (RenderableLabel)
Attach floating text labels as child nodes of planets, landmarks, or spacecraft so their visibility can be toggled independently in the Scene tree:
local LabelNode = {
Identifier = "DemoLandmark_Label",
Parent = "DemoLandmark",
Renderable = {
Type = "RenderableLabel",
Text = "Adler Planetarium",
FontSize = 32,
Color = { 1.0, 1.0, 1.0 },
MinMaxSize = { 8, 48 } -- Clamps screen-space pixel size across zoom levels
}
}