Skip to content

Repository files navigation

CobeKit

CobeKit demo

A pure Swift/Metal port of cobe — the lightweight WebGL globe library by Shu Ding. Renders a beautiful interactive 3D globe with dotted land masses, markers, and arcs, all running on the GPU via Metal shaders.

Credit: This project is a faithful port of cobe's rendering pipeline to Apple's Metal framework. The Fibonacci lattice dot algorithm, rotation math, and world map texture are directly derived from cobe. All credit for the original concept and implementation goes to Shu Ding and the cobe contributors.

Features

  • Metal GPU rendering — Fibonacci lattice dot algorithm ported from cobe's GLSL shaders
  • Cobe's actual world map — the same base64-encoded equirectangular PNG texture
  • Markers — glowing circles at geographic coordinates with back-face culling
  • Arcs — quadratic Bezier curves connecting two points, elevated above the surface
  • Drag to rotate — pan gesture with momentum/inertia and auto-rotation
  • Dark & light modes — matching cobe's dark parameter for both aesthetics
  • SwiftUI native — simple GlobeView(configuration:) API
  • Cross-platform — iOS 16+ and macOS 13+
  • Zero dependencies — pure Swift Package, no external libraries
  • Runtime shader compilation — no .metal files needed, works with SPM out of the box

Quick Start

Swift Package Manager

Add to your Package.swift dependencies:

.package(url:"https://github.com/ohwhen/CobeKit.git", from:"1.0.0")

Or in Xcode: File → Add Package Dependencies → paste the repo URL.

Usage

import SwiftUI
import CobeKit
structContentView:View{@Stateprivatevarconfig=GlobeConfiguration()varbody:someView{GlobeView(configuration: $config).frame(width:400, height:400).onAppear{
config.theta =0.3
config.dark =1.0
config.baseColor =SIMD3(0.3,0.3,0.6)
config.glowColor =SIMD3(0.1,0.1,0.6)}}}

Adding Markers

config.markers =[GlobeMarker(location:SIMD2(40.71,-74.01), size:0.08, color:SIMD3(1,0.5,0.1)), // NYC
GlobeMarker(location:SIMD2(51.51,-0.13), size:0.06, color:SIMD3(1,0.5,0.1)), // London
GlobeMarker(location:SIMD2(35.68,139.69), size:0.07, color:SIMD3(1,0.5,0.1)), // Tokyo
]

Adding Arcs

config.arcs =[GlobeArc(from:SIMD2(40.64,-73.78), to:SIMD2(51.47,-0.46), color:SIMD3(0.3,0.7,1)), // JFK → LHR
GlobeArc(from:SIMD2(51.47,-0.46), to:SIMD2(25.25,55.36), color:SIMD3(0.3,0.7,1)), // LHR → DXB
]

Configuration

PropertyTypeDefaultDescription
phiFloat0Horizontal rotation (radians)
thetaFloat0.3Vertical tilt (radians)
mapSamplesFloat16000Number of dots on the globe
mapBrightnessFloat6.0Dot brightness multiplier
mapBaseBrightnessFloat0.05Minimum dot brightness (ocean visibility)
baseColorSIMD3<Float>(0.3, 0.3, 0.6)Globe surface color
glowColorSIMD3<Float>(0.3, 0.3, 0.8)Atmospheric glow color
markerColorSIMD3<Float>(1.0, 0.5, 0.2)Default marker color
arcColorSIMD3<Float>(0.3, 0.6, 1.0)Default arc color
diffuseFloat1.2Diffuse lighting intensity
darkFloat1.0Dark mode (1.0) vs light mode (0.0)
opacityFloat1.0Globe opacity
scaleFloat1.0Zoom factor
autoRotateSpeedFloat0.005Auto-rotation speed (0 to disable)
dragEnabledBooltrueEnable drag-to-rotate gesture

Examples

The Example/ directory contains a full iOS app with 5 demo tabs:

  1. Dark Globe — classic dark blue cobe aesthetic
  2. Neon — cyberpunk hot pink glow with green base
  3. Markers — 10 city markers with tap-to-rotate
  4. Flights — airport markers with arc connections (SFO → JFK → AMS → DXB → SYD)
  5. Whop — branded landing page hero with animated entrance

Running the Example

cd Example
xcodegen generate # requires xcodegen
open CobeKitExample.xcodeproj

Then select an iPhone simulator and run.

Architecture

Sources/CobeKit/
├── GlobeView.swift # SwiftUI wrapper + drag/inertia coordinator
├── GlobeRenderer.swift # Metal renderer (MTKViewDelegate)
├── GlobeConfiguration.swift # Public config API, markers, arcs
└── ShaderSource.swift # Metal shaders (compiled at runtime)

Rendering Pipeline

Three Metal render passes per frame, matching cobe's WebGL architecture:

  1. Globe pass — full-screen triangle, fragment shader does ray-sphere intersection + Fibonacci lattice dot placement + texture lookup + lighting/glow
  2. Marker pass — instanced quads positioned at geographic coordinates, back-face culled
  3. Arc pass — instanced triangle strips along quadratic Bezier curves

Metal vs WebGL

The main porting challenge was Metal's fragment coordinate system (y=0 at top) vs WebGL's (y=0 at bottom). This affects:

  • The globe's view-space Y direction (inverted in Metal)
  • Marker/arc vertex shaders need to negate Y when converting view-space → clip-space
  • Vertical drag direction is negated to compensate

Acknowledgments

This project would not exist without cobe by Shu Ding. The Fibonacci lattice algorithm, van der Corput bit-reversal sequence, rotation math, lighting model, and world map texture are all faithfully ported from cobe's original GLSL shaders. Thank you for creating such an elegant and beautiful library.

License

MIT

About

A pure Swift/Metal port of cobe — interactive 3D globe with dotted land masses, markers, and arcs for iOS & macOS

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Used by

Contributors

Languages