CommunityImagegithub.com

richard-evans/scientific-visualisation

Build scientific/technical diagrams and concept icons with POV-Ray - atoms, bonds, crystal/molecular structures, vector-field arrows, oscillating "wave" connectors, glowing/energetic effects, metallic finishes, and clean transparent-background renders for dropping into papers, presentations, posters and grant figures. Use this whenever the user wants a diagram of a molecule, crystal lattice, particle/atom arrangement, or a small conceptual icon representing a physical process (light/laser pulses, current/particle flow, heat/thermal disorder, an abstract force or interaction between objects, a vector field) - even if they don't say "POV-Ray" or "3D render" explicitly, e.g. "can you make a little icon for X", "I need a schematic showing Y", "render this crystal structure", "something to represent Z happening between these atoms". Also use it to review or extend an existing POV-Ray scene, or to debug a POV-Ray render that isn't behaving (blank/opaque background, clipped geometry...

What is scientific-visualisation?

scientific-visualisation is a Claude Code agent skill that build scientific/technical diagrams and concept icons with POV-Ray - atoms, bonds, crystal/molecular structures, vector-field arrows, oscillating "wave" connectors, glowing/energetic effects, metallic finishes, and clean transparent-background renders for dropping into papers, presentations, posters and grant figures. Use this whenever the user wants a diagram of a molecule, crystal lattice, particle/atom arrangement, or a small conceptual icon representing a physical process (light/laser pulses, current/particle flow, heat/thermal disorder, an abstract force or interaction between objects, a vector field) - even if they don't say "POV-Ray" or "3D render" explicitly, e.g. "can you make a little icon for X", "I need a schematic showing Y", "render this crystal structure", "something to represent Z happening between these atoms". Also use it to review or extend an existing POV-Ray scene, or to debug a POV-Ray render that isn't behaving (blank/opaque background, clipped geometry...

Works with~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/richard-evans/research-skills/tree/HEAD/scientific-visualisation

Installed? Explore more Image skills: steipete/songsee, affaan-m/frontend-design, mattpocock/improve-codebase-architecture · View all 6 →

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation

Scientific visualisation with POV-Ray

This skill packages a set of POV-Ray building blocks and conventions developed for a real hero figure (four magnetic ground-state renders plus five concept-icon widgets for a grant proposal), refined over several rounds of visual review. Reach for it any time the deliverable is a standalone diagram or icon meant to sit in a document someone else will read - not a UI, not a web page, a rendered image.

Why POV-Ray, and what this buys you

POV-Ray scenes are plain text, which means: they're easy to parameterise (loop over N atoms, generate a lattice, sweep a parameter), easy to compose from reusable macros, and easy to re-render at a different resolution without redoing any work. The output is a flat, precisely-controlled raster image (not an interactive 3D scene) - exactly the format papers, slides, and grant PDFs actually want.

Quick start

  1. #include "common.inc" first - sets up the camera, a soft 3-point light rig, background/transparency, and shared finish presets. Look at it once; the comments explain the why behind each choice (matters if you need to deviate from it).
  2. Pull in whichever of these you need:
    • molecule.inc - atoms (sv_atom), bonds (sv_bond), vector arrows (sv_arrow)
    • wave.inc - oscillating tubes: propagating waves and fuzzy "abstract interaction" connectors are the same macro (sv_wave_tube) with different parameters
    • glow.inc - the layered-halo trick for anything that should read as glowing/hot/energetic (sv_glow_sphere)
    • orientation_color.inc - map a direction/angle to a perceptually distinct colour (sv_orientation_colour / sv_colour_wheel), for when direction itself is the data (spin angle, flow direction, phase)
  3. Render with scripts/render.sh <scene.pov> [W] [H] [out.png] rather than calling povray directly - it sets +UA (real alpha channel), sensible antialiasing, points POV-Ray at this skill's assets/ so your #includes resolve without copying files around, and it will warn you if the alpha channel came out wrong (see the gotcha below - this has bitten a real session before, silently).
  4. Look at the result before calling it done. Read the PNG back (Read tool) and actually look - POV-Ray will happily render something subtly wrong (clipped by the camera frame, wrong colour, arrows overlapping) with zero errors.

The five widget templates

assets/widgets/ has five ready-to-adapt scenes, each a worked example of the building blocks above:

FileWhat it showsBuilt from
laser.povA propagating oscillating wave + direction arrow (light, sound, any signal)sv_wave_tube (open, no taper)
particle_current.povA row of N particles each carrying a vector property, drifting in a flow directionsv_atom + sv_arrow + a flow arrow
thermal_grid.povAn NxN lattice with small positional jitter, glowing hot-to-cool by distance from centresv_glow_sphere + a jittered grid loop
interaction_triangle.povN objects joined by fuzzy, glowing, non-rigid "interaction" lines (distinct from a physical bond)sv_atom + sv_wave_tube (tapered, jittered, glowing)

Copy the one closest to what you need and change the declared parameters at the top (colours, counts, spacing, amplitude) before touching the geometry itself - all four are written so the "knobs" are up top.

For a real molecule/crystal structure (not a concept icon), skip the widgets and go straight to molecule.inc: loop over your atom coordinates calling sv_atom and sv_bond, using sv_arrow for any per-atom vector (spin, dipole, displacement) and sv_orientation_colour if that vector's direction is itself meaningful data worth colour-coding.

Design conventions worth keeping

These aren't arbitrary - each came out of a real visual-review round:

  • White background, real alpha channel (+UA). Renders drop straight onto a slide/page/figure without a visible box, and compose cleanly next to other panels regardless of what's behind them.
  • The 3-point light rig in common.inc, not a single point light. One hard light reads as a rendered 3D object ("clip art"); the soft key+fill+fill rig reads as a polished, matte, printed illustration. Keep the same rig across every panel of a multi-panel figure so they read as one family - a panel lit differently from its neighbours looks like a mismatched sticker even when the geometry style matches.
  • Bonds/rigid connectors get a small away-from-camera z-offset (sv_bond's ZOffset param) whenever a bond and an arrow might run near-parallel through the same region - otherwise they z-fight, or the bond visibly slices into an arrowhead. Small enough (0.15-0.25 units on a typical scene scale) that no one will consciously notice it's there.
  • Arrows are 10-20% shorter than "touching." If two vector arrows meet at a shared point, shrink Scale until their tips clear each other - touching tips read as a rendering glitch, not as data.
  • Abstract vs. physical connections get different visual language. A real bond (sv_bond): rigid, crisp, matte. An abstract coupling/force/correlation (sv_wave_tube with Glow=true): wavy, soft-edged, glowing. Don't draw an interaction you can't point to a literal atom-atom orbital overlap for as if it were a physical rod.
  • Slightly distort "generic" arrangements. A perfect equilateral triangle or perfectly regular grid reads as clip art. A small, deliberate irregularity (see interaction_triangle.pov's triangle, or thermal_grid.pov's jitter) reads as "a real system," even in a schematic icon that isn't simulation output.

When you're rendering real simulation data, not an icon

If atom positions/vectors come from an actual simulation (DFT, molecular dynamics, micromagnetics, whatever), the icon-widget conventions above still apply, but you're populating sv_atom/sv_bond/sv_arrow calls from real coordinate data rather than hand-picking values. Practical notes:

  • Generate bonds by a distance cutoff between atom pairs, not by hand.
  • If you want to show a real, physically periodic tiled patch (a bigger region than one simulation cell) without re-running an expensive simulation, and the property tiles uniformly (true for most simple ordered ground states), it's often valid to replicate the already- converged small-cell result geometrically rather than resimulating a larger system - just verify first that the property genuinely doesn't vary from cell to cell in your case.
  • Crop to a physically meaningful boundary (e.g. one full coordination shell/unit motif), not an arbitrary rectangle - the crop itself should say something true about the structure.

Troubleshooting

Read references/troubleshooting.md before spending time debugging a POV-Ray parse error or a render that looks wrong - it lists the specific gotchas already hit while building this skill (reserved SDL words that look like ordinary variable names, the silent-alpha-transparency bug, POV-Ray's camera handedness, sphere_sweep/array scoping quirks). Most POV-Ray error messages are honest about the syntax problem but unhelpful about why it looks that way from a normal-programmer's expectations; that file exists so you don't have to rediscover the same handful of traps.

For fuller worked explanations of each macro's parameters and design rationale (with more example calls than fit here), see references/techniques.md.

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Related Skills