Spherical-harmonic orbital surfaces in the 3Dmol viewer
Since 16.1. The radial functions are no longer hydrogenic. Every element uses its free-atom Hartree–Fock valence orbitals, fitted by a few Slater terms (the same table as the orbital layer and the π maps; see Radial functions: an experiment). Surfaces are drawn at a fixed |ψ| in atomic units instead of a fraction of each orbital's maximum, because a realistic s function peaks at the nucleus. Amber is ψ > 0 and teal ψ < 0. The sections below describe how the method developed.
Version 15 reconnects the local molecular viewer to the mathematics of the original spherical-harmonic code.
Local basis
Each rendered local orbital is represented by the coefficient vector
already produced by the geometry/hybridization model. The browser evaluates
The real-harmonic convention is therefore
This is the Cartesian real form of the \(\ell=0,1\) spherical-harmonic subspace. Consequently sp, sp2 and sp3 hybrids are true linear combinations inside the same harmonic space; the browser no longer invents their lobe geometry with ellipsoids when harmonic mode is selected.
Radial function
The first implementation uses the normalized hydrogenic radial function with an effective nuclear charge \(Z_{\mathrm eff}\):
where
The browser evaluates the generalized Laguerre polynomial directly.
The angular mathematics is exact for the declared convention. The radial model is not an ab-initio multi-electron atomic orbital: the effective charges are Slater-like display parameters. This distinction is exposed in /api/model as the per-atom radial_model metadata.
Surface extraction (16.3.1)
For each local orbital:
- Find how far |ψ| still reaches the isovalue τ. This is checked along ± the orbital's direction and in both directions across it, out to the radial extent of the element.
- Sample ψ on a cube that just holds that lobe, at a fixed spacing (see below).
- Extract ψ = +τ and ψ = −τ (τ in atomic units, the same for every orbital) with marching tetrahedra (Doi & Koide 1991). Each grid cell is cut into six tetrahedra around its main diagonal (Kuhn's triangulation), so neighbouring cells cut their shared face along the same diagonal and the surface has no cracks.
- Wind every triangle so that its normal points away from the corners inside the lobe, i.e. out of the lobe.
- Weld the corners that triangles share into single vertices. Each vertex gets the area-weighted mean normal of its triangles.
Steps 4 and 5 were added in 16.3.1, after a Mol* screenshot showed shards. Before, each triangle's winding followed the order of the tetrahedron corners, so about half of the triangles faced into the lobe (measured on a p orbital: 54% and 46% outward). Each triangle also carried its own flat normal.
- 3Dmol lit the inward half from behind: patchy, banded shading.
- Mol* (like Blender and MeshLab) does not draw back faces, so it dropped that half: shells of scattered shards.
Now every surface is closed and simple (Euler characteristic V − E + F = 2), every triangle faces out, and the vertex normals follow the surface. node tests/test_mesh.js checks this on a sphere, on both signs of a p orbital and on a real π HOMO. The code is static/js/qo-mesh.js. The π fields use the same mesher on their own grids, one per π system.
Faster surfaces for whole protein sites (16.4)
/sites can draw every orbital of a 384-atom zinc finger: 752 orbitals. Two steps dominated there.
- Welding. Vertices were welded by hashing their coordinates as strings. Since 16.4 each vertex is created once per grid edge. Kuhn's triangulation only uses edges from a grid point in a non-negative direction (x, y, z, three face diagonals, the cell diagonal), so (grid point, direction) names an edge uniquely across cells, and the mesh comes out welded.
- Radial functions. The radial sums were evaluated with exp() and pow() at every grid point. Now
qo-orbitals.jstabulates each element's R_s and R_p once, on a grid uniform in √r. That is 0.4 mÅ apart near the nucleus and 5 mÅ at 7 Å, and agrees with the sums to 5·10⁻⁶ bohr⁻³ᐟ².
All 752 orbitals plus the π density now take 1.9 s at low and 3.4 s at medium quality in Chromium, instead of 4.4 and 8.7 s. The orbital code is shared by /molviewer and /sites (static/js/qo-orbitals.js; node tests/test_orbitals.js).
Positive and negative wavefunction phase are rendered separately. Lone-pair orbitals no longer receive a different phase color in harmonic mode; "lone pair" is a semantic occupancy/localization label, whereas phase is a property of the wavefunction.
Quality levels
Grid spacing:
| quality | orbitals | π fields |
|---|---|---|
| low | 0.35 Å | 0.24 Å |
| medium | 0.25 Å | 0.16 Å |
| high | 0.15 Å | 0.11 Å |
For 4-nitrophenol with every layer on, in a desktop browser:
- low: 66k triangles in 0.26 s;
- medium: 128k triangles in 0.43 s;
- high: 349k triangles in 1.7 s.
Before 16.3.1, each orbital had a fixed 13³ samples across ±2–3.5 Å, a spacing of about 0.4–0.6 Å.
The work scales linearly with the number of displayed orbitals and as (reach/spacing)³ per orbital. Since 16.4 harmonic mode allows 1500 orbitals at once (it was 120); at low quality ~750 orbitals take about 2 s (see above).
Relationship to the original MATLAB harmonic code
The original code provided the angular object \(Y_\ell^m\) (and optionally a solid-harmonic factor). Version 15 now evaluates the corresponding real \(\ell=0,1\) angular basis inside the molecule viewer and supplies an explicit radial \(R_{n\ell}\).
The remaining gap to a quantitatively predictive molecular-orbital renderer is not WebGL. It is the physics that determines radial basis functions and molecular coefficients: Hartree-Fock, DFT, semiempirical, tight-binding, or imported quantum-chemistry orbital coefficients.
Next mathematical extension
The mesh engine is no longer restricted conceptually to s/p hybrids. A natural next step is to extend the coefficient tensor to
and add real \(d\)-harmonics (\(\ell=2\)). The same marching-tetrahedra code can then render d-orbital and transition-metal local fields without changing the 3Dmol integration.
v15.1 radial phase correction
The normalized hydrogenic radial function has an arbitrary overall basis phase. With the standard associated-Laguerre polynomial convention, its outermost radial sign is
For example, the standard polynomial convention gives opposite outer-lobe signs for \(2s\) and \(2p\). That is harmless for isolated atomic orbitals, because \(\phi\) and \(-\phi\) describe the same orbital, but it matters once the local hybrid coefficients are interpreted as a fixed relative combination
Version 15.1 therefore uses the explicit basis convention
so the outermost radial lobe is positive for every basis function. The local hybrid coefficients and radial basis then use the same relative phase convention.
This correction changes neither the density of an isolated basis function,
nor any physical observable by itself. It corrects the relative phase used when \(s\) and \(p\) functions are superposed into the displayed hybrid.
For a correctly directed sigma hybrid, constructive \(s/p\) interference now occurs toward the geometry-derived bond/domain direction rather than being systematically reversed by the hydrogenic polynomial sign convention.
v15.2 charge-sensitive radial display
The optional charge-sensitive mode modifies only the visualization radial parameter using a bounded Gasteiger/formal-charge heuristic. It does not alter the geometry-derived hybrid coefficients and does not identify wavefunction phase with electrical charge.