Skip to content

New: Add WebGL renderer - #109

Merged
AlexIchenskiy merged 10 commits into
release/1.0.0from
new/add-webgl-renderer
Jul 16, 2026
Merged

New: Add WebGL renderer#109
AlexIchenskiy merged 10 commits into
release/1.0.0from
new/add-webgl-renderer

Conversation

@AlexIchenskiy

Copy link
Copy Markdown
Collaborator

This PR introduces an alternative WebGL renderer alongside the existing Canvas renderer, plus a refactor of the layout/simulator engine to support it. The Canvas renderer remains the default, WebGL is fully optional.

The goal is better rendering performance on larger graphs by offloading node/edge/label drawing to the GPU via custom GLSL shaders, and optionally running force-directed layout on the GPU as well.

What's included

  • WebGL renderer (RendererType.WEBGL) — selectable per view, drawn with custom GLSL shaders for nodes, edges, and labels (src/renderer/webgl/).
  • Node images & labels on the GPU — image atlas (image-atlas.ts) and label cache (label-cache.ts) so textures/text can be batched.
  • Improved node/shape geometry options for the WebGL path.
  • GPU force layout engine (gpu-force-layout-engine.ts) — runs the force simulation in WebGL2 with a quadtree/Barnes-Hut approximation. Automatically falls back to the CPU force engine if WebGL2 is unavailable.
  • Layout engine refactor — the old d3-simulator-engine is replaced by a set of pluggable engines (force, circular, grid, hierarchical) behind a factory.

Documentation

Documentation for the WebGL renderer and the new layout engines is still lacking - the APIs may still change while this stabilizes, so docs will be filled in once everything is done and confirmed.

Usage

Opt into the WebGL renderer when creating a view:

const orb = new Orb.OrbView(container, {
  render: { type: 'webgl' },
});

Opt into GPU layout:

const orb = new Orb.OrbView(container, {
  render: { type: 'webgl' },
  layout: { type: 'force', options: { useGPU: true } },
});

Note on stability

This adds a WebGL rendering path, which should be considered experimental and potentially fragile. It depends on GPU/driver behavior and WebGL2 support, so rendering may differ across browsers, GPUs, parameters, and device pixel ratios, and can fail, look different or require cherry-picking for stable results where the Canvas renderer would not. The Canvas renderer remains the stable default and is unchanged in behavior.

@AlexIchenskiy AlexIchenskiy self-assigned this Jun 16, 2026
@AlexIchenskiy
AlexIchenskiy changed the base branch from main to release/1.0.0 June 16, 2026 09:17

@tonilastre tonilastre left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really cool! Great job! Btw add yourself to package.json contributors :D

I've added some comments, but mostly nitpicking.

I was playing with the large number of nodes and edges :D Btw if you have some html examples, feel free to add them to server.

Image

Comment thread src/utils/program.utils.ts Outdated

const program = gl.createProgram();
if (!program) {
throw new OrbError('Failed to create program.');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
throw new OrbError('Failed to create program.');
throw new OrbError('Failed to create GL program.');

Having only program seems too generic. Same for the error below.

Comment thread src/renderer/webgl/utils/image-atlas.ts Outdated
Comment on lines +33 to +34
private _dirty = false;
private _textureAllocated = false;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpicking, but do want these to start with _is...

Comment thread src/renderer/webgl/utils/color.utils.ts Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw do you need this file because it is empty?

Comment thread src/renderer/webgl/utils/label-cache.ts Outdated
Comment on lines +8 to +17
export interface LabelAtlasEntry {
u0: number;
v0: number;
u1: number;
v1: number;
pxWidth: number;
pxHeight: number;
}

interface Shelf {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I

Comment thread src/renderer/webgl/utils/label-cache.ts Outdated
Comment on lines +30 to +31
private _dirty = false;
private _textureAllocated = false;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar comment as with previous class about boolean vars

super.terminate();

const gl = this._gl;
if (gl) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe an early return here.

@AlexIchenskiy
AlexIchenskiy merged commit 617ba93 into release/1.0.0 Jul 16, 2026
2 checks passed
@AlexIchenskiy
AlexIchenskiy deleted the new/add-webgl-renderer branch July 16, 2026 08:28
tonilastre added a commit that referenced this pull request Jul 28, 2026
… tooling

* Fix: Fix multiple maps issue (#33)

* Chore: Update package.json version

* New: Change the API to handle OrbView and OrbMapView (#34)

* New: Change the API to handle OrbView and OrbMapView

* New: Change the API for select/hover strategies

* Chore: Release/1.0.0

* New: Add support to get selected/hovered nodes and edges (#61)

* New: Added support to get selected nodes and edges

* New: Added support to get hovered nodes and edges

---------

Co-authored-by: Abhinav Singh Parmar <abhinavparmar147@gmail.com>

* New: Add support for enabling and disabling dragging of nodes (fixes #62) (#69)

* New: Add feature to enable/disable node dragging (fixes #62)

* New: Added support to modify interaction from setSettings

* New: Updated documentation for interaction property

* New: Add feature to enable/disable zoom (fixes #62)

* NEW: Updated documentation for interaction property

* NEW: Updated documentation to include isDragEnabled

* New: Add support for custom edge line style (#77)

* New Added support for custom edges

* Refactor: Streamline edge rendering code and optimize line style handling

* New: Add support for handling device pixel ratio (#45)

* Chore: Move container and canvas creation from the view to the renderer

* New: Add devicePixelRatio render property and handler

* Fix: Add default DPR for older browsers

* Chore: Remove useless check for automatic DPR

* New: Add new simulator (#56) (#57)

* New: Add new simulator (#56)

* New: Add simulator scenarios for manual testing
* New: Refactor simulator (WIP)
* New: Add progress overlay, Update descriptions
* Fix: Introduce new simulator event, Fix main-thread behavior
* Fix: Rearrange class methods based on visibility
* Fix: Improve naming
* Chore(release): 0.2.0
* Fix: Tweak simulator, adjust API slightly
* Fix: Temporarily patch some physics behavior
* Fix: Adjust re-heating parameters
* Fix: tweak physics behavior -> immediately stop sim when disabling
* Chore: Remove the beta from release branches

---------

Co-authored-by: dlozic <davidlozic@gmail.com>

* New: Add zoom and recenter functions (#74)

* New: Add zoom and recenter functions

* Fix: Reduce excessive recentering (#75)

* Fix: Remove excessive recenterings
* Fix: Remove unused code

* Fix: New simulator (#92)

* Chore: Refactor naming

* New: Add new events

* Chore: Refactor code styling

* Docs: Remove unused flags

* Chore: Remove unused simulation functions

* Chore: Refactor view render function calls

* Chore: Add missing tests

* New: Add removal functions (#96)

* New: Add removal functions

* Fix: Add missing callback data

* Chore: Refactor remove return values

* Chore: Refactor remove function type usage

* Fix: Default settings for node placement (#98)

* New: Add properties setters and getters (#93)

* New: Add node properties setters

* New: Add edge properties setters

* New: Add properties getters

* New: Add patch for nodes and edges

* Fix: Make getters return copies

* Fix: Edge factory listeners copying

* Fix: Jest outdated tests

* Fix: Github actions node version

* Chore: Refactor observer interface

* Chore: Refactor node/edge constructor settings

* Chore: Refactor node/edge function grouping

* Chore: Refactor node/edge function grouping

* Fix: Listeners behaviour

* Chore: Refactor property copying

* Chore: Refactor subject implementation

* Fix: Set position behaviour on node drag

* Chore: Upgrade node version

* Chore: Refactor function type check

* Fix: Remove listener behaviour

* Chore: Refactor util naming

* Chore: Remove unused type assertion

* Chore: Refactor position setter options

* Chore: Refactor property patch function

* Fix: Set map node position behaviour

* Chore: Refactor simulator data patching

* Chore: Change observers to callbacks

* New: Add state setters with options (#95)

* New: Add state setters with options

* Chore: Remove leftover comments

* Chore: Refactor state setter logic

* Chore: Refactor state types

* Fix: Rename merged function usage

* Fix: Merged variable naming

* Chore: Fix tests

---------

Co-authored-by: dlozic <davidlozic@gmail.com>
Co-authored-by: Oleksandr Ichenskyi <55350107+AlexIchenskiy@users.noreply.github.com>
Co-authored-by: AlexIchenskiy <aichenskiy@gmail.com>

* New: Add zoom in and out functions (#100)

* Fix: Skip unnecessary listener notify on set style

* Fix: remove unnecessary rerender on state change

* Chore: Update documentation

* Fix: Node/edge getter performance issue

* Chore: Add data change docs example

* Fix: Docs typos

* Fix: Disable source map generation (#105)

* New: Add tree layout (#107)

* New: Add new layouts

* New: Add layout options

* Chore: Make layout dynamically changeable

* Chore: Update docs

* Fix: Naming typo

* Chore: Refactor layouts

* New: Enable layout node add/remove

* Chore: Improve behavior for recurrent nodes

* Chore: Move some simulator settings to layout

* Chore: Refactor code quality and performance

* Fix: Layout behavior on change

* Chore: Add recenter on layout change

* Fix: Layout change behavior

* Fix: Simulation behavior on data deletion

* Chore: Add recenter on layout change

* Fix: Change layout engine logic (#108)

* Fix: Change layout engine logic

* New: Add simulation cancellation logic

* Chore: Remove leftover code

* Fix: Hierarchical layout recenter logic

* Chore: Refactor package versions and code logic

* Fix: Refactor function types

* New: Add multiselect (#110)

* New: Add multiselect

* Chore: Simplify logic

* Chore: Update package.json

* New: Add SVG export (#111)

* New: Add SVG export

* Chore: Refactor code quality

* New: Add WebGL renderer (#109)

* New: Add WebGL renderer

* New: Add naive WebGL force layout computation

* New: Add WebGL improved node/shape geometry options

* New: Add labels and node images

* Fix: GPU drag behavior

* Chore: Remove leftover comments

* Fix: WebGL renderer style invalidating

* Chore: Refactor code quality

* Chore: Add WebGL example and docs

* New: Add docs page (#112)

* New: Add docs page

* New: Add more docs examples

* Update .github/workflows/docs.yml

---------

Co-authored-by: Toni <toni.lastre@memgraph.io>

* Chore: Finish up the release process

* Chore: Fix sync between package.json files

* Chore: Add new package-lock.json

---------

Co-authored-by: David <davidlozic@gmail.com>
Co-authored-by: Abhinv Singh Parmar <abhi171b010@gmail.com>
Co-authored-by: Abhinav Singh Parmar <abhinavparmar147@gmail.com>
Co-authored-by: Abhinv Singh Parmar <abhinav.parmar@infosys.com>
Co-authored-by: Oleksandr Ichenskyi <55350107+AlexIchenskiy@users.noreply.github.com>
Co-authored-by: AlexIchenskiy <aichenskiy@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants