Skip to content

Welcome to FragmentColor

Easy GPU Programming for Rust, Javascript, Python, Swift, and Kotlin.
Terminal window
pip install fragmentcolor rendercanvas glfw
from fragmentcolor import FragmentColor as fc, Shader, Pass, Frame
from rendercanvas.auto import RenderCanvas, loop
# Initializes a renderer and a target compatible with the given canvas
canvas = RenderCanvas(size=(800, 600))
renderer, target = fc.init(canvas)
# You can pass the shader as a source string, file path, or URL:
circle = Shader("./path/to/circle.wgsl")
triangle = Shader("https://fragmentcolor.org/shaders/triangle.wgsl")
my_shader = Shader("""
struct VertexOutput {
@builtin(position) coords: vec4<f32>,
}
struct MyStruct {
my_field: vec3<f32>,
}
@group(0) @binding(0)
var<uniform> my_struct: MyStruct;
@group(0) @binding(1)
var<uniform> my_vec2: vec2<f32>;
@vertex
fn vs_main(@builtin(vertex_index) in_vertex_index: u32) -> VertexOutput {
const vertices = array(
vec2( -1., -1.),
vec2( 3., -1.),
vec2( -1., 3.)
);
return VertexOutput(vec4<f32>(vertices[in_vertex_index], 0.0, 1.0));
}
@fragment
fn fs_main() -> @location(0) vec4<f32> {
return vec4<f32>(my_struct.my_field, 1.0);
}
""")
# The library binds and updates the uniforms automatically
my_shader.set("my_struct.my_field", [0.1, 0.8, 0.9])
my_shader.set("my_vec2", [1.0, 1.0])
# One shader is all you need to render
renderer.render(shader, target)
# But you can also combine multiple shaders in a render Pass
rpass = Pass("single pass")
rpass.add_shader(circle)
rpass.add_shader(triangle)
rpass.add_shader(my_shader)
renderer.render(rpass, target)
# Finally, you can combine multiple passes in a Frame
frame = Frame()
frame.add_pass(rpass)
frame.add_pass(Pass("GUI pass"))
renderer.render(frame, target)
# To animate, simply update the uniforms in a loop
@canvas.request_draw
def animate():
circle.set("position", [0.0, 0.0])
renderer.render(frame, target)
loop.run()