Skip to content

Commit cb28a23

Browse files
committed
add post
1 parent cbdeeb8 commit cb28a23

File tree

3 files changed

+119
-2
lines changed

3 files changed

+119
-2
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
BSD 2-Clause License
22

3-
Copyright (c) 2024-2025, pygfx
3+
Copyright (c) 2024-2026, pygfx
44

55
Redistribution and use in source and binary forms, with or without
66
modification, are permitted provided that the following conditions are met:

posts/report003.md

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# Looking back at 2025, and forward to 2026
2+
3+
<!-- DATE: 2026-02-12 -->
4+
<!-- AUTHOR: Almar -->
5+
6+
In this post I look back at what we achieved in 2025, and where we want to go in 2026.
7+
8+
9+
<!-- END_SUMMARY -->
10+
11+
12+
## Overview of 2025
13+
14+
### PyGfx
15+
16+
We started the year with a big effor to refactor the rendering pipeline. This touched caching, scene traversal, managing 'scene environment', and a lot more. This work was spread over multiple pull requests, and was needed to allow more flexibility, such as having different blend modes for different materials.
17+
18+
This laid the foundations to refactor the blending mechanics, a big PR that took 4 months to finish, with several follow-up PRs to iron out the details.
19+
In short, with these changes we acknowledge that blending is a hard problem for which there is no single best solution.
20+
Instead of trying to solve it (badly) for the user, we give the user tools to handle blending in various ways. This inclused more control over blending order, transparency, and depth handling. But also provide alternative blending options like weighed blending and dithering.
21+
22+
Further notable improvements:
23+
24+
* A succession of optimisations to the transform systems.
25+
* The text rendering underwent a refactor, to improve the performance and support multi-text labels, e.g. making the ruler object more efficient.
26+
* The geometry object was made simpler, to just be an object that holds data, which simplifies the API and allowed for some performance improvements.
27+
* The camera's ability to 'snap' on a scene was improved (`.show_object(... match_aspect=True)`), and some issues related to depth were fixed.
28+
* Lines now support loops and infinite lines.
29+
* Points can have per-vertex markers.
30+
* There has been a lot of work (thanks to Pan) on support for gltf and physical rendering.
31+
* We added post-processing effects, including two post-processing anti-aliasing filters
32+
(fxaa and our own ddaa), and the resolve pass when doing ssaa was improved. Overall
33+
this results in much crisper/cleaner images.
34+
35+
36+
### wgpu-py
37+
38+
For wgpu-py we implemented improved support for type hints, making it easier to
39+
write code using wgpu using IDE's that use static or dynamic introspection.
40+
41+
And of course we kept up with new versions of the WebGPU spec and wgpu-native.
42+
43+
44+
### rendercanvas
45+
46+
The most notable improvements in rendercanvas are:
47+
48+
* Improved support for type hints.
49+
* Higher-precision timers (to avoid lower FPS than expected on Windows).
50+
* Improved scheduling, e.g. making sure that size-events are up-to-date.
51+
* Similarly, events are processed as close as possible before rendering the next frame, which reduces any perceived lag for remote backends.
52+
* Support for Pyodide; you can run rendercanvas in the browser! Thanks Jan!
53+
54+
55+
### The road to async
56+
57+
Quite a lot of effort was put into improving the support for async. This work
58+
was pretty hard, because it involves the (changing) API of wgpu-native to deal with asynchronous calls,
59+
different async frameworks (e.g. asyncio, trio, rendercanvas' async adapter), and threading.
60+
61+
One notable advantage of async we were looking forward to was the improved performance of rendercanvas backends that need the rendered image as a bitmap, which is downloaded via `GPUBuffer.map_async()`.
62+
63+
To kick this work of, the context classes that were first implemented as part of `wgpu-py` were moved to `rendercanvas`. This made it possible in `rendercanvas` to implement more advanced contexts, and let wgpu-py focus on being a GPU API.
64+
65+
Then we applied several changes in rendercanvas and wgpu-py to allow them to interoperate in an async setting.
66+
67+
In rendercanvas:
68+
69+
* Provides `loop.call_soon_threadsafe()`.
70+
* Loops have a much better defined lifecycle.
71+
* Uses `sys.set_asyncgen_hooks` where appopriate (replacing the use of `sniffio`).
72+
73+
In wgpu-py:
74+
75+
* Runs a per-device thread to poll wgpu-core. This is lightweight while allowing to respond as quickly as possible when wgpu-core finishes an async call.
76+
* Has a new `GPUPromise` class to handle the async mechanics, which exposes `.then()`.
77+
* Uses 'sys.get_asyncgen_hooks' to detect the loop.
78+
* Calls `loop.call_soon_threadsafe` from the polling thread to wake the main thread.
79+
80+
With these changes, it became possible to implement *async bitmap present*; the rendered image
81+
can be downloaded from the GPU without actually waiting for it; the CPU (and GPU) can do other things while this happens. This results in a major increase in framerate.
82+
83+
This directly benefits the Jupyter backend and future remote backends, but also makes it viable to make
84+
bitmap-present the default for Qt, which solves many issues our users were facing.
85+
86+
87+
## What we did not get to
88+
89+
There were also features that we planned to do in 2025, but that we did not mange to do in 2025.
90+
91+
* The 'update propagation' work, including a new `View` class in PyGfx (although some of the scheduling improvements in rendercanvas relate to this).
92+
* Log plots and map projections.
93+
94+
95+
## Outlook for 2026
96+
97+
More or less in order of urgency:
98+
99+
* An `Anywidget` backend in `rendercanvas`, allowing remote rendering in a wide range of applications (e.g. Jupyter, VSCode, Marimo notebooks, and more).
100+
* Finish the `View` class and other work related to 'update propagation'.
101+
* Log plots and map projections.
102+
* Enabling and promoting using wgpu compute for scientific applications.
103+
* Pyodide support for wgpu-py and PyGfx.
104+
* We want to look into a more reliable backend for wgpu-py, either by giving wgpu-native a boost, hooking into wgpu-core directly, or switching to Dawn.
105+
* Support for native widgets in `rendercanvas`, so it does not depend on an any external library to provide a window.
106+
* Improvements to streaming in remote rendering (with `Anywidget`); we want to look into mpeg encoding and shaders that encode/decode jpeg.
107+
108+
## Funding
109+
110+
In 2025 we received generous funding from the Flatiron Institute and from Ramona Optics. Together with some buildup runway in 2025 this helped us through 2025. We are very grateful for these funds; without these, PyGfx, wgpu-py and rendercanvas would probably be abandonware.
111+
112+
For 2026, both current sponsors continue to support PyGfx, although with smaller amounts. We also applied for a European grant, for which we passed the first round, and hope to hear the verdict soon.
113+
114+
Almar, Kushal, and Caitlin are also working on a proprietary project that uses PyGfx. Some of the work mentioned in the outlook will be done as part of that project.
115+
116+
If your company or research group is able to financially support this project, that would be awesome! We need funding to keep going. It looks like 2026 will be fine, but there have been times when I did not know how things would work out. So please reach out if you can!
117+

template.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
<hr />
2828

29-
<div class='footer'>© Copyright 2024-2025, Pygfx team -
29+
<div class='footer'>© Copyright 2024-2026, Pygfx team -
3030
<a href='https://creativecommons.org/licenses/by/4.0/'>CC BY 4.0</a>
3131
</div>
3232

0 commit comments

Comments
 (0)