# How to Calculate Sun Elevation in CesiumJS: Astronomical Implementation Guide

> Learn to calculate sun elevation in CesiumJS using astronomical formulas. Master solar declination, hour angle, and elevation calculations with this precise guide.

- Repository: [Bilawal Sidhu/gods-eye-view](https://github.com/bilawalsidhu/gods-eye-view)
- Tags: how-to-guide
- Published: 2026-08-30

---

**To calculate sun elevation in CesiumJS, compute the solar declination from the day-of-year, derive the hour angle from local solar time, and solve the classical elevation formula using `Cesium.Math.toRadians` and `Cesium.Math.toDegrees` for precision unit conversions.**

The *God’s Eye View* repository demonstrates how to calculate sun elevation in CesiumJS using a self-contained astronomical model that requires no external libraries. The implementation resides in [`src/hud.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/hud.js), where the `_estimateSunElevation` function processes observer coordinates and UTC time to return a signed degree value indicating the sun's altitude above the horizon.

## The Solar Elevation Formula

The algorithm implements the standard astronomical formula for solar elevation:

```

sin(elevation) = sin(φ) × sin(δ) + cos(φ) × cos(δ) × cos(H)

```

Where:

- **φ** represents the observer's latitude in radians
- **δ** represents the solar declination angle (approximated from the calendar date)
- **H** represents the hour angle derived from local solar time

## Implementation in src/hud.js

The `_estimateSunElevation` function in [`src/hud.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/hud.js) executes a five-step calculation to determine the sun's position.

### 1. Determine Local Solar Time

The function converts UTC to local solar time by applying the longitude correction (15 degrees per hour).

### 2. Calculate Hour Angle

The hour angle `H` equals `(localSolarTime - 12) × 15°`, representing the sun's angular distance from solar noon.

### 3. Approximate Solar Declination

The declination uses a sinusoidal approximation with 23.45° amplitude:

```javascript
const declination = 23.45 *
    Math.sin(Cesium.Math.toRadians(
        (360 / 365) *
        (now.getUTCDate() + 30 * now.getUTCMonth() - 81)
    ));

```

### 4. Solve the Elevation Equation

Using `Cesium.Math.toRadians`, the function converts latitude, declination, and hour angle to radians before computing the sine of elevation.

### 5. Clamp and Convert to Degrees

The result is clamped to `[-1, 1]` to prevent floating-point drift before applying `Math.asin`, with final conversion via `Cesium.Math.toDegrees`.

## Working Code Example

The following implementation from [`src/hud.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/hud.js) calculates sun elevation for any latitude and longitude:

```javascript
// Import Cesium if not already in scope
import * as Cesium from 'cesium';

// Example: compute sun elevation for New York City (40.7128 N, -74.0060 W)
function sunElevationNYC() {
  const lat = 40.7128;
  const lon = -74.0060;
  const elevationDeg = _estimateSunElevation(lat, lon);
  console.log(`Sun elevation in NYC: ${elevationDeg.toFixed(1)}°`);
}

// The core routine (excerpted from src/hud.js)
function _estimateSunElevation(lat, lon) {
  const now = new Date();
  const hours = now.getUTCHours() + now.getUTCMinutes() / 60 + lon / 15;
  const hourAngle = (hours - 12) * 15;
  const declination = 23.45 *
    Math.sin(Cesium.Math.toRadians(
      (360 / 365) *
      (now.getUTCDate() + 30 * now.getUTCMonth() - 81)
    ));
  const latRad = Cesium.Math.toRadians(lat);
  const decRad = Cesium.Math.toRadians(declination);
  const haRad = Cesium.Math.toRadians(hourAngle);
  const sinEl = Math.sin(latRad) * Math.sin(decRad) +
               Math.cos(latRad) * Math.cos(decRad) * Math.cos(haRad);
  // Clamp to avoid NaN from rounding errors
  const clamped = Math.max(-1, Math.min(1, sinEl));
  return Cesium.Math.toDegrees(Math.asin(clamped));
}

// Run the example
sunElevationNYC();

```

## Alternative: Using Cesium's Built-in Sun Position

For applications requiring higher astronomical precision, Cesium provides native solar position calculations. This approach uses `Cesium.Sun.getPositionInWorldSpace` to determine the sun's location in world coordinates, then calculates elevation from the direction vector:

```javascript
function sunElevationCesium(viewer, lat, lon) {
  const now = Cesium.JulianDate.now();
  const sunPos = Cesium.Sun.getPositionInWorldSpace(viewer.scene, now);
  const observer = Cesium.Cartesian3.fromDegrees(lon, lat);
  const direction = Cesium.Cartesian3.normalize(
    Cesium.Cartesian3.subtract(sunPos, observer, new Cesium.Cartesian3()),
    new Cesium.Cartesian3()
  );
  // Elevation = arcsin(z component) because Cesium's world frame Z points up
  const elevationRad = Math.asin(direction.z);
  return Cesium.Math.toDegrees(elevationRad);
}

```

**Comparison of approaches:**

- **Astronomical model** ([`src/hud.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/hud.js)): Zero dependencies, extremely fast, sufficient for UI-level visual cues and HUD displays
- **Native Cesium.Sun**: Higher accuracy using planetary ephemeris data, ideal for scientific visualization but requires access to the Cesium viewer instance

## Related Files in God's Eye View

The repository organizes solar calculations across several modules:

- **[`src/hud.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/hud.js)**: Contains the `_estimateSunElevation` function powering the HUD's sun-elevation readout
- **[`src/celestialRing.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/celestialRing.js)**: Handles visual sun/moon markers using Cesium's planetary position utilities for accurate screen placement
- **[`src/cockpitCloudEffects.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/cockpitCloudEffects.js)**: Derives the `sunDirection` vector for lighting cloud shaders based on solar position

## Summary

- **Calculate sun elevation in CesiumJS** using the classical formula `sin(el) = sin(φ)sin(δ) + cos(φ)cos(δ)cos(H)` implemented in [`src/hud.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/hud.js)
- **Compute solar declination** with a sinusoidal approximation using day-of-year calculations and `Cesium.Math.toRadians`
- **Prevent floating-point errors** by clamping the sine of elevation to `[-1, 1]` before calling `Math.asin`
- **Convert results** to degrees using `Cesium.Math.toDegrees` to obtain signed elevation values (negative indicates sun below horizon)
- **Choose between** the lightweight astronomical model for HUD elements or `Cesium.Sun.getPositionInWorldSpace` for research-grade accuracy

## Frequently Asked Questions

### What file contains the sun elevation calculation in God's Eye View?

The primary implementation lives in **[`src/hud.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/hud.js)** within the `_estimateSunElevation` function. This module computes the solar angle every frame to update the cockpit HUD's "SUN" readout display.

### Why clamp the sine of elevation to [-1, 1]?

Floating-point arithmetic in JavaScript can produce values slightly outside the valid domain of `[-1, 1]` due to rounding errors in trigonometric calculations. Clamping prevents `Math.asin` from returning `NaN` and ensures stable elevation readings near solar noon or horizon transitions.

### How accurate is the declination approximation?

The sinusoidal model approximates Earth's 23.45° axial tilt with a maximum error of approximately ±0.5 degrees compared to precise astronomical algorithms. This accuracy proves sufficient for visualization purposes in CesiumJS applications while maintaining calculation speeds suitable for real-time rendering.

### Can I use Cesium's built-in Sun class instead of the astronomical formula?

Yes. The `Cesium.Sun` class provides `getPositionInWorldSpace` for high-precision solar positioning based on planetary ephemeris data. This approach requires an active Cesium viewer instance and incurs higher computational cost than the [`src/hud.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/hud.js) implementation, but delivers research-grade accuracy for scientific applications.