fragmentcolor 0.10.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +9 -0
- package/README.md +208 -0
- package/fragmentcolor.d.ts +111 -0
- package/fragmentcolor.js +1969 -0
- package/fragmentcolor_bg.wasm +0 -0
- package/package.json +33 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright © 2025 Vista Tech & Art GmbH <beckel@vista.art>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# FragmentColor
|
|
2
|
+
|
|
3
|
+
[FragmentColor](https://fragmentcolor.org) is a cross-platform GPU programming library implemented in Rust and [wgpu](https://wgpu.rs).
|
|
4
|
+
|
|
5
|
+
It has bindings for **Javascript**, **Python**, **Swift**, and **Kotlin**
|
|
6
|
+
and targets each platform's native graphics API: **Vulkan**, **Metal**, **DirectX**, **OpenGL**, **WebGL**, or **WebGPU**.\
|
|
7
|
+
See [Platform Support](#platform-support) for details.
|
|
8
|
+
|
|
9
|
+
The API encourages a simple shader composition workflow. You can use **WGSL** or **GLSL** shaders
|
|
10
|
+
for visual consistency across platforms, while avoiding the verbosity of modern GPU APIs.
|
|
11
|
+
|
|
12
|
+
**We strive to remove the complexity without sacrificing control**. Because of the composition primitives, you can
|
|
13
|
+
build a highly customized render graph with multiple render passes.
|
|
14
|
+
|
|
15
|
+
Check the [Documentation](/welcome) and the [API Reference](/api) for more information.
|
|
16
|
+
|
|
17
|
+
> ⚠️ **This library is its early days of development**
|
|
18
|
+
>
|
|
19
|
+
> The API is subject to frequent changes in minor versions. Documentation is not always in sync.
|
|
20
|
+
>
|
|
21
|
+
> Check the [Roadmap](/ROADMAP.md) and [Changelog](/CHANGELOG.md) on [GitHub](https://github.com/vista-art/fragmentcolor) to stay tuned on the latest updates.
|
|
22
|
+
|
|
23
|
+
## Example
|
|
24
|
+
|
|
25
|
+
From a given shader source, our library will:
|
|
26
|
+
|
|
27
|
+
- parse the shader
|
|
28
|
+
- compile/reload it at runtime
|
|
29
|
+
- create the Uniform bindings in your platform's native graphics API
|
|
30
|
+
- expose them with the dot notation.
|
|
31
|
+
|
|
32
|
+
### Example usage (Python)
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pip install fragmentcolor glfw rendercanvas
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
from fragmentcolor import FragmentColor as fc, Renderer, Shader, Pass, Frame
|
|
40
|
+
from rendercanvas.auto import RenderCanvas, loop
|
|
41
|
+
|
|
42
|
+
# Initializes a renderer and a target compatible with the given canvas
|
|
43
|
+
canvas = RenderCanvas(size=(800, 600))
|
|
44
|
+
renderer = Renderer()
|
|
45
|
+
target = renderer.create_target(canvas)
|
|
46
|
+
|
|
47
|
+
# You can pass the shader as a source string, file path, or URL:
|
|
48
|
+
circle = Shader("./path/to/circle.wgsl")
|
|
49
|
+
triangle = Shader("https://fragmentcolor.org/shaders/triangle.wgsl")
|
|
50
|
+
my_shader = Shader("""
|
|
51
|
+
struct VertexOutput {
|
|
52
|
+
@builtin(position) coords: vec4<f32>,
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
struct MyStruct {
|
|
56
|
+
my_field: vec3<f32>,
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@group(0) @binding(0)
|
|
60
|
+
var<uniform> my_struct: MyStruct;
|
|
61
|
+
|
|
62
|
+
@group(0) @binding(1)
|
|
63
|
+
var<uniform> my_vec2: vec2<f32>;
|
|
64
|
+
|
|
65
|
+
@vertex
|
|
66
|
+
fn vs_main(@builtin(vertex_index) in_vertex_index: u32) -> VertexOutput {
|
|
67
|
+
const vertices = array(
|
|
68
|
+
vec2( -1., -1.),
|
|
69
|
+
vec2( 3., -1.),
|
|
70
|
+
vec2( -1., 3.)
|
|
71
|
+
);
|
|
72
|
+
return VertexOutput(vec4<f32>(vertices[in_vertex_index], 0.0, 1.0));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
@fragment
|
|
76
|
+
fn fs_main() -> @location(0) vec4<f32> {
|
|
77
|
+
return vec4<f32>(my_struct.my_field, 1.0);
|
|
78
|
+
}
|
|
79
|
+
""")
|
|
80
|
+
|
|
81
|
+
# The library binds and updates the uniforms automatically
|
|
82
|
+
my_shader.set("my_struct.my_field", [0.1, 0.8, 0.9])
|
|
83
|
+
my_shader.set("my_vec2", [1.0, 1.0])
|
|
84
|
+
|
|
85
|
+
# One shader is all you need to render
|
|
86
|
+
renderer.render(shader, target)
|
|
87
|
+
|
|
88
|
+
# But you can also combine multiple shaders in a render Pass
|
|
89
|
+
rpass = Pass("single pass")
|
|
90
|
+
rpass.add_shader(circle)
|
|
91
|
+
rpass.add_shader(triangle)
|
|
92
|
+
rpass.add_shader(my_shader)
|
|
93
|
+
renderer.render(rpass, target)
|
|
94
|
+
|
|
95
|
+
# Finally, you can combine multiple passes in a Frame
|
|
96
|
+
frame = Frame()
|
|
97
|
+
frame.add_pass(rpass)
|
|
98
|
+
frame.add_pass(Pass("GUI pass"))
|
|
99
|
+
renderer.render(frame, target)
|
|
100
|
+
|
|
101
|
+
# To animate, simply update the uniforms in a loop
|
|
102
|
+
@canvas.request_draw
|
|
103
|
+
def animate():
|
|
104
|
+
circle.set("position", [0.0, 0.0])
|
|
105
|
+
renderer.render(frame, target)
|
|
106
|
+
|
|
107
|
+
loop.run()
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Example usage (Javascript)
|
|
111
|
+
|
|
112
|
+
```javascript
|
|
113
|
+
import { Shader, Renderer } from "fragmentcolor";
|
|
114
|
+
|
|
115
|
+
const canvas = document.getElementById("my-canvas");
|
|
116
|
+
const renderer = new Renderer();
|
|
117
|
+
const target = renderer.init(canvas);
|
|
118
|
+
|
|
119
|
+
const shader = new Shader("https://fragmentcolor.org/shaders/circle.wgsl");
|
|
120
|
+
shader.set("resolution", [canvas.width, canvas.heigth]);
|
|
121
|
+
shader.set("circle.radius", 0.05);
|
|
122
|
+
shader.set("circle.color", [1.0, 0.0, 0.0, 0.8]);
|
|
123
|
+
|
|
124
|
+
const renderer = new Renderer();
|
|
125
|
+
|
|
126
|
+
function animate() {
|
|
127
|
+
shader.set("circle.position", [mouseX, mouseY]);
|
|
128
|
+
renderer.render(shader, target);
|
|
129
|
+
|
|
130
|
+
requestAnimationFrame(animate);
|
|
131
|
+
}
|
|
132
|
+
animate();
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Limitations
|
|
136
|
+
|
|
137
|
+
- The current version of this library **always use a fullscreen triangle for every shader**. Support for custom geometries and instanced rendering is planned.
|
|
138
|
+
|
|
139
|
+
- In Python, we depend on [rendercanvas](https://github.com/pygfx/rendercanvas) adapter to support multiple window libraries. Direct support for other libraries is planned.
|
|
140
|
+
|
|
141
|
+
- Textures and Samplers are currently not supported, but are also planned.
|
|
142
|
+
|
|
143
|
+
- Javascript, Swift, and Kotlin are currently WIP.
|
|
144
|
+
|
|
145
|
+
## Running this project
|
|
146
|
+
|
|
147
|
+
### Target: Desktop (Rust library)
|
|
148
|
+
|
|
149
|
+
For Rust, check the examples folder and run them with:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
cargo run --example circle
|
|
153
|
+
cargo run --example triangle
|
|
154
|
+
cargo run --example multiobject
|
|
155
|
+
cargo run --example multipass
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Target: Desktop (Python module)
|
|
159
|
+
|
|
160
|
+
**NOTE:** Pip Package currently only available for MacOS (Apple Silicon)
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
pip install fragmentcolor glfw rendercanvas
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Alternativaly, You can build it locally with [maturin](https://www.maturin.rs/installation.html):
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
pipx install maturin
|
|
170
|
+
maturin develop
|
|
171
|
+
pip install glfw rendercanvas
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
The built library is located in `platforms/python/fragmentcolor`
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
cd platforms/python/fragmentcolor
|
|
178
|
+
python3 main.py
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Target: Web browser (WASM module)
|
|
182
|
+
|
|
183
|
+
- TBD
|
|
184
|
+
|
|
185
|
+
### Target: iOS (Swift library)
|
|
186
|
+
|
|
187
|
+
- TBD
|
|
188
|
+
|
|
189
|
+
### Target: Android (Kotlin library)
|
|
190
|
+
|
|
191
|
+
- TBD
|
|
192
|
+
|
|
193
|
+
## Platform support
|
|
194
|
+
|
|
195
|
+
Platform support is the same as upstream [wgpu](https://github.com/gfx-rs/wgpu):
|
|
196
|
+
|
|
197
|
+
| API | Windows | Linux/Android | macOS/iOS | Web (wasm) |
|
|
198
|
+
| ------ | ------------ | --------------- | --------- | ----------- |
|
|
199
|
+
| Vulkan | ✅ | ✅ | 🌋 | |
|
|
200
|
+
| Metal | | | ✅ | |
|
|
201
|
+
| DX12 | ✅ | | | |
|
|
202
|
+
| OpenGL | 🆗 (GL 3.3+) | 🆗 (GL ES 3.0+) | 📐 | 🆗 (WebGL2) |
|
|
203
|
+
| WebGPU | | | | ✅ |
|
|
204
|
+
|
|
205
|
+
✅ = First Class Support
|
|
206
|
+
🆗 = Downlevel/Best Effort Support
|
|
207
|
+
📐 = Requires the [ANGLE](http://angleproject.org/) translation layer (GL ES 3.0 only)
|
|
208
|
+
🌋 = Requires the [MoltenVK](https://vulkan.lunarg.com/sdk/home#mac) translation layer
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
export class CanvasTarget {
|
|
4
|
+
private constructor();
|
|
5
|
+
free(): void;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Can be specified as 0xRRGGBBAA
|
|
9
|
+
*/
|
|
10
|
+
export class Color {
|
|
11
|
+
private constructor();
|
|
12
|
+
free(): void;
|
|
13
|
+
0: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* A Frame represents a graph of Passes that are executed in sequence.
|
|
17
|
+
*/
|
|
18
|
+
export class Frame {
|
|
19
|
+
private constructor();
|
|
20
|
+
free(): void;
|
|
21
|
+
}
|
|
22
|
+
export class PassInput {
|
|
23
|
+
private constructor();
|
|
24
|
+
free(): void;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* A region in 2D space designed to handle viewport and texture regions
|
|
28
|
+
*/
|
|
29
|
+
export class Region {
|
|
30
|
+
private constructor();
|
|
31
|
+
free(): void;
|
|
32
|
+
min_x: number;
|
|
33
|
+
min_y: number;
|
|
34
|
+
max_x: number;
|
|
35
|
+
max_y: number;
|
|
36
|
+
}
|
|
37
|
+
export class Renderer {
|
|
38
|
+
free(): void;
|
|
39
|
+
/**
|
|
40
|
+
* Creates a new Renderer
|
|
41
|
+
*/
|
|
42
|
+
constructor();
|
|
43
|
+
create_target(canvas: any): Promise<CanvasTarget>;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The Shader in FragmentColor is the blueprint of a Render Pipeline.
|
|
47
|
+
*
|
|
48
|
+
* It automatically parses a WGSL shader and extracts its uniforms, buffers, and textures.
|
|
49
|
+
*
|
|
50
|
+
* The user can set values for the uniforms and buffers, and then render the shader.
|
|
51
|
+
*/
|
|
52
|
+
export class Shader {
|
|
53
|
+
private constructor();
|
|
54
|
+
free(): void;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
|
58
|
+
|
|
59
|
+
export interface InitOutput {
|
|
60
|
+
readonly memory: WebAssembly.Memory;
|
|
61
|
+
readonly __wbg_renderer_free: (a: number, b: number) => void;
|
|
62
|
+
readonly __wbg_passinput_free: (a: number, b: number) => void;
|
|
63
|
+
readonly __wbg_region_free: (a: number, b: number) => void;
|
|
64
|
+
readonly __wbg_get_region_min_x: (a: number) => number;
|
|
65
|
+
readonly __wbg_set_region_min_x: (a: number, b: number) => void;
|
|
66
|
+
readonly __wbg_get_region_min_y: (a: number) => number;
|
|
67
|
+
readonly __wbg_set_region_min_y: (a: number, b: number) => void;
|
|
68
|
+
readonly __wbg_get_region_max_x: (a: number) => number;
|
|
69
|
+
readonly __wbg_set_region_max_x: (a: number, b: number) => void;
|
|
70
|
+
readonly __wbg_get_region_max_y: (a: number) => number;
|
|
71
|
+
readonly __wbg_set_region_max_y: (a: number, b: number) => void;
|
|
72
|
+
readonly __wbg_canvastarget_free: (a: number, b: number) => void;
|
|
73
|
+
readonly __wbg_color_free: (a: number, b: number) => void;
|
|
74
|
+
readonly __wbg_get_color_0: (a: number) => number;
|
|
75
|
+
readonly __wbg_set_color_0: (a: number, b: number) => void;
|
|
76
|
+
readonly renderer_new_js: () => number;
|
|
77
|
+
readonly renderer_create_target: (a: number, b: any) => any;
|
|
78
|
+
readonly __wbg_shader_free: (a: number, b: number) => void;
|
|
79
|
+
readonly __wbg_frame_free: (a: number, b: number) => void;
|
|
80
|
+
readonly __wbindgen_exn_store: (a: number) => void;
|
|
81
|
+
readonly __externref_table_alloc: () => number;
|
|
82
|
+
readonly __wbindgen_export_2: WebAssembly.Table;
|
|
83
|
+
readonly __wbindgen_malloc: (a: number, b: number) => number;
|
|
84
|
+
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
|
85
|
+
readonly __wbindgen_export_5: WebAssembly.Table;
|
|
86
|
+
readonly closure109_externref_shim: (a: number, b: number, c: any) => void;
|
|
87
|
+
readonly closure785_externref_shim: (a: number, b: number, c: any) => void;
|
|
88
|
+
readonly closure807_externref_shim: (a: number, b: number, c: any, d: any) => void;
|
|
89
|
+
readonly __wbindgen_start: () => void;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export type SyncInitInput = BufferSource | WebAssembly.Module;
|
|
93
|
+
/**
|
|
94
|
+
* Instantiates the given `module`, which can either be bytes or
|
|
95
|
+
* a precompiled `WebAssembly.Module`.
|
|
96
|
+
*
|
|
97
|
+
* @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated.
|
|
98
|
+
*
|
|
99
|
+
* @returns {InitOutput}
|
|
100
|
+
*/
|
|
101
|
+
export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
|
105
|
+
* for everything else, calls `WebAssembly.instantiate` directly.
|
|
106
|
+
*
|
|
107
|
+
* @param {{ module_or_path: InitInput | Promise<InitInput> }} module_or_path - Passing `InitInput` directly is deprecated.
|
|
108
|
+
*
|
|
109
|
+
* @returns {Promise<InitOutput>}
|
|
110
|
+
*/
|
|
111
|
+
export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise<InitInput> } | InitInput | Promise<InitInput>): Promise<InitOutput>;
|