Skip to content

changkun/polyred

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

481 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

polyred Go Reference polyred

3D graphics in Go.

import "poly.red"

Warning: under experiment, expect to break at anytime.

GPU compute and rendering, in Go

poly.red/gpu is a backend-agnostic GPU abstraction, a WebGPU-style Device/Queue/Buffer/Pipeline/CommandEncoder API for running compute and rendering pipelines, with a driver (Metal today) underneath. It is cgo-free: the Metal/Objective-C runtime is reached through ebitengine/purego, so it builds with CGO_ENABLED=0.

Shaders are written in Go and compiled to the backend's shading language by poly.red/gpu/shader: compute, vertex, and fragment kernels, with varyings, uniforms, vector math, and control flow.

dev, _ := gpu.Open()                 // Metal on darwin
defer dev.Close()

// Shaders authored in Go, compiled to MSL.
ks, _ := shader.Compile(`
package kernels
type Vec4 struct{ X, Y, Z, W float32 }
type VOut struct {
    Pos   Vec4 ` + "`gpu:\"position\"`" + `
    Color Vec4
}
//gpu:vertex
func VMain(vid uint, pos []float32, col []float32) VOut {
    return VOut{Vec4{pos[vid*2], pos[vid*2+1], 0, 1}, Vec4{col[vid*3], col[vid*3+1], col[vid*3+2], 1}}
}
//gpu:fragment
func FMain(in VOut) Vec4 { return in.Color }
`)
// ... build a render pipeline, render to a texture, read pixels back.

See the runnable end-to-end example:

go run ./cmd/gpudemo -o triangle.png    # Go shaders -> Metal -> PNG, cgo-free

The design, decisions, and roadmap live in docs/gpu-abstraction.md; implementation specs are in specs/.

Status

Capability State
Device API (buffers, bind groups, compute + render pipelines, passes, textures, samplers) working
Metal backend (compute + render), cgo-free via purego working
Go→shader compiler (compute + vertex/fragment, varyings, uniforms, vector + matrix math, swizzle, texture sampling, trig, control flow) working
Renderer deferred pass fully offloaded to the GPU (render.GPU(dev)): point + directional lights, multi-material, shadow maps (one and many casting lights), ambient occlusion, gamma working, CPU-parity verified
OpenGL ES + Vulkan backends (cgo-free, via purego): compute through the Device API verified in CI on Mesa (llvmpipe / lavapipe, software, headless); GL also does render-to-texture working
DirectX 12 backend, on-screen windowed present planned, gated on Windows / a display, not design

The renderer offloads its full deferred shading pass to the GPU when a device is supplied:

dev, _ := gpu.Open()
img := render.NewRenderer(
    render.Camera(cam), render.Size(w, h), render.Scene(s),
    render.ShadowMap(true),
    render.GPU(dev), // deferred shading (lights, materials, shadows, AO) runs on the GPU
).Render()

cgo-free build/test of the Metal GPU stack on darwin:

CGO_ENABLED=0 go test ./gpu ./gpu/mtl ./gpu/shader ./gpu/tests

CI runs build + vet + tests on macOS, Linux, and Windows; all three are green. Windows window present was ported to the modern textured-quad GLES blit so it builds again; displaying a window there is not yet runtime-verified (see specs/README.md, Known issues).

About

📺 3D Graphics in Go.

Topics

Resources

License

Stars

45 stars

Watchers

3 watching

Forks

Sponsor this project

 

Contributors

Languages