Rafx is a C graphics abstraction library designed around modern graphics workflows.
It is based on the NVIDIA Render Interface (NRI).
- Fully bindless rendering approach (no CPU bindgroups, descriptor sets, ...)
- Automatic tracking of resource states, barrier placement and transitions
- Full parity between Vulkan, D3D12 and Metal (through MoltenVK/KosmicKrisp)
- Support for Enhanced Barriers on DirectX 12 Ultimate
- Built-in windowing (using RGFW, GLFW or SDL3), fully cross-platform
- Built-in support for NRD denoisers (ReBLUR, ReLAX, Sigma)
rfxCmdDenoise - Native integration with the Slang shader language
- Graphics, compute, raytracing and mesh shaders
- Support for hardware RT and opacity micromaps
- Support for common upscalers (NVIDIA DLSS, AMD FSR, Intel XeSS, NVIDIA DLSS Ray Reconstruction, NIS)
printfinside shaders, toggleable hot-reloadingrfxWatchShader- Suitable for tile-based rendering architectures
- Tight integration with AMD's Virtual Memory Allocator (VMA) for Vulkan and D3D12 for optimal memory reuse
- Async compute (parallel execution of graphics and compute workloads)
- Variable rate shading (VRS) support
- MSAA, anisotropic filtering, mipmapping and BCn texture compression with a simple toggle
- Multidraw
- Occlusion queries
- Low latency support (aka NVIDIA Reflex)
- GPU profiler, timeline annotations (GAPI, Nsight, PIX), resource naming
- ImGui extension
rfxCmdDrawImGui - Shader cache / precompilation
- Honored user-provided memory allocator
- Lots of examples to get you started
![]() |
![]() |
![]() |
|---|---|---|
| async compute | bloom | compute boids |
![]() |
![]() |
![]() |
| compute triangle | compute voronoi | cube |
![]() |
![]() |
![]() |
| denoise | hot reloading | low latency |
![]() |
![]() |
![]() |
| mesh triangle | rt boxes | rt triangle |
![]() |
![]() |
![]() |
| shadow mapping | texcube | triangle |
![]() |
||
| upscaler |
A triangle:
#include <rafx.h>
// minified for readme sake
const char* src = "struct V { float3 p:POSITION; float4 c:COLOR; }; "
"struct O { float4 p:SV_Position; float4 c:COLOR; }; "
"[shader(\"vertex\")] O vs(V i) { O o; o.p=float4(i.p,1); o.c=i.c; return o; } "
"[shader(\"fragment\")] float4 ps(O i):SV_Target { return i.c; }";
struct Vertex {
float x, y, z, r, g, b, a;
};
int main() {
rfxOpenWindow("Rafx", 1280, 720);
struct Vertex data[] = { { 0, .5, 0, 1, 0, 0, 1 }, { .5, -.5, 0, 0, 1, 0, 1 }, { -.5, -.5, 0, 0, 0, 1, 1 } };
RfxBuffer vb = rfxCreateBuffer(sizeof(data), sizeof(data[0]), RFX_USAGE_VERTEX_BUFFER, RFX_MEM_GPU_ONLY, data);
RfxShader s = rfxCompileShaderMem(src, NULL, 0, NULL, 0);
RfxVertexLayoutElement layout[] = { { 0, RFX_FORMAT_RGB32_FLOAT, 0, "POSITION" }, { 1, RFX_FORMAT_RGBA32_FLOAT, 12, "COLOR" } };
RfxPipeline pip = rfxCreatePipeline(&(RfxPipelineDesc){
.shader = s,
.vertexLayout = layout,
.vertexLayoutCount = 2,
.colorFormat = rfxGetSwapChainFormat(),
.vertexStride = sizeof(struct Vertex),
});
while (!rfxWindowShouldClose()) {
rfxBeginFrame();
RfxCommandList cmd = rfxGetCommandList();
rfxCmdBeginSwapchainRenderPass(cmd, RFX_FORMAT_UNKNOWN, RFX_COLOR(20, 20, 20, 255));
rfxCmdBindPipeline(cmd, pip);
rfxCmdBindVertexBuffer(cmd, vb);
rfxCmdDraw(cmd, 3, 1);
rfxCmdEndRenderPass(cmd);
rfxEndFrame();
}
rfxDestroyPipeline(pip);
rfxDestroyShader(s);
rfxDestroyBuffer(vb);
return 0;
}














