{"id":13995365,"url":"https://github.com/zesterer/euc","last_synced_at":"2025-05-14T23:06:59.044Z","repository":{"id":52195752,"uuid":"165903025","full_name":"zesterer/euc","owner":"zesterer","description":"A software rendering crate that lets you write shaders with Rust","archived":false,"fork":false,"pushed_at":"2024-12-31T12:10:09.000Z","size":697,"stargazers_count":316,"open_issues_count":7,"forks_count":20,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-04-13T20:39:13.843Z","etag":null,"topics":["3d","graphics","rendering","rust","software-rendering"],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zesterer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-01-15T18:33:32.000Z","updated_at":"2025-03-12T10:26:07.000Z","dependencies_parsed_at":"2024-01-20T18:04:16.723Z","dependency_job_id":"1f30b562-5362-4920-96a2-f829de095318","html_url":"https://github.com/zesterer/euc","commit_stats":{"total_commits":105,"total_committers":10,"mean_commits":10.5,"dds":"0.24761904761904763","last_synced_commit":"5fe97f3c97db0e61dd3665af2b10265ed0792360"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zesterer%2Feuc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zesterer%2Feuc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zesterer%2Feuc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zesterer%2Feuc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zesterer","download_url":"https://codeload.github.com/zesterer/euc/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254243362,"owners_count":22038046,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["3d","graphics","rendering","rust","software-rendering"],"created_at":"2024-08-09T14:03:22.104Z","updated_at":"2025-05-14T23:06:54.005Z","avatar_url":"https://github.com/zesterer.png","language":"Rust","readme":"# \u003cimg src=\"misc/banner.png\" alt=\"Euc\" width=\"100%\" margin-left=auto margin-right=auto/\u003e\n\n[![crates.io](https://img.shields.io/crates/v/euc.svg)](https://crates.io/crates/euc)\n[![crates.io](https://docs.rs/euc/badge.svg)](https://docs.rs/euc)\n[![License](https://img.shields.io/badge/license-MIT%2FApache--2.0-blue.svg)](https://github.com/zesterer/euc)\n![actions-badge](https://github.com/zesterer/euc/workflows/Rust/badge.svg?branch=master)\n\n# \u003cimg src=\"misc/example.png\" alt=\"Utah teapot, rendered with shadow-mapping and phong shading at 60 fps\"/\u003e\n\n## Example\n\n```rust\n// A type that specifies a rendering pipeline.\n// You can add fields to this type, like uniforms in traditional GPU shader programs.\nstruct Triangle;\n\nimpl\u003c'r\u003e Pipeline\u003c'r\u003e for Triangle {\n    type Vertex = [f32; 2]; // Each vertex has an x and y component\n    type VertexData = Unit; // No data is passed from the vertex shader to the fragment shader\n    type Primitives = TriangleList; // Our vertices come in the form of a list of triangles\n    type Fragment = [u8; 3]; // Each fragment is 3 bytes: red, green, and blue\n    type Pixel = [u8; 3]; // Color buffer pixels have the same format as fragments.\n\n    // Vertex shader (determines the screen-space position of each vertex)\n    fn vertex(\u0026self, pos: \u0026Self::Vertex\u003c'_\u003e) -\u003e ([f32; 4], Self::VertexData) {\n        ([pos[0], pos[1], 0.0, 1.0], Unit)\n    }\n\n    // Fragment shader (determines the colour of each triangle fragment)\n    fn fragment(\u0026self, _: Self::VertexData) -\u003e Self::Fragment {\n        [255, 0, 0] // Paint the triangle red\n    }\n\n    // Blend shader (determines how to blend new fragments into the existing colour buffer)\n    fn blend(\u0026self, _: Self::Pixel, col: Self::Fragment) -\u003e Self::Pixel {\n        col // Just replace the color buffer's previous pixel\n    }\n}\n\n// Create a new color buffer to render to\nlet mut color = Buffer2d::new([640, 480], [0; 3]);\n\nTriangle.render(\n    // Specify the coordinates of the triangle's corners\n    \u0026[[-1.0, -1.0], [1.0, -1.0], [0.0, 1.0]],\n    // Specify the color buffer to render to\n    \u0026mut color,\n    // We have no need for a depth buffer, so use `Empty` as a substitute\n    \u0026mut Empty::default(),\n);\n```\n\n## What is `euc`?\n\n`euc` is a [software-rendering](https://en.wikipedia.org/wiki/Software_rendering)\ncrate for rendering 3D scenes on the CPU. The API is designed to be clean,\npowerful, and heavily leans on Rust's type system to ensure correct usage.\n\n`euc` is fast enough to render simple scenes in real-time and supports\nthread-based parallelism to accelerate rendering.\n\n## Features\n\n- Write shaders in Rust (vertex, geometry, fragment and blend shaders)\n- Multithreading support for parallel rendering acceleration\n- Many supported primitives and vertex formats (triangle lists, line pairs, etc.)\n- N-dimensional textures and samplers (including support for filtering, clamping, tiling, mirroring, etc.)\n- Customisable coordinate space (choose compatibility with OpenGL, Vulkan, DirectX, or Metal)\n- Built-in support for index buffers\n- MSAA (Multi-Sample Anti-Aliasing)\n\n## Why?\n\nBelow are a few circumstances in which you might want to use `euc`.\n\n### Learning and experimentation\n\nModern graphics APIs are complex, verbose beasts. The code required to set them\nup properly requires a lot of bureaucratic mumbo jumbo. This problem has only\nbecome worse with the latest iteration of graphics APIs. Vulkan's canonical\n['Hello Triangle' example](https://vulkan-tutorial.com/code/16_swap_chain_recreation.cpp)\nis, when shader code is included, 994 lines of code. Compare that to `euc`'s 34.\nThis is obviously not without tradeoff: Vulkan is a powerful modern graphics API\nthat's designed for high-performance GPGPU on a vast array of hardware while\n`euc` is simply a humble software-renderer.\n\nHowever, for someone new to 3D rendering that wants to explore new techniques\nwithout all of the bureaucratic cruft, `euc` might well serve a useful purpose.\n\n### Static images, pre-renders, and UI\n\n`euc` may not be well-suited to high-performance real-time graphics, but there\nare many applications that don't require this. For example,\n[Veloren](https://veloren.net/) currently uses `euc` to pre-render 3D item\nmodels as icons to be displayed in-game later.\n\n`euc` is also more than fast enough for soft real-time applications such as UI\nrendering, particularly for state-driven UIs that only update when events occur.\nIn addition, tricky rendering problems like font rasterization become much\nsimpler to solve on the CPU.\n\n### Embedded\n\n`euc` doesn't require `std` to run. Are you writing a toy OS? Do you want a\npretty UI with a 3D graphics API but you don't want to write your own GPU\ndrivers? `euc` has you covered, even for simple real-time graphics.\n\n### Testing\n\n`euc` doesn't need a GPU to run. Most servers and CI machines don't have access\nto one either. If you want to check the consistency of some rendered output,\n`euc` is perfect for the job.\n\n### Unconventional environments\n\nAccess to render surfaces for most modern graphics APIs is done through a window\nmanager or similar such component that manages access to framebuffers. Don't\nhave access to that because you're writing a 3D command-line game? `euc` might\nbe what you're looking for. In addition, `euc` uses Rust's type system to allow\nrendering to unconventional framebuffer formats. Now you can render to a `char`\nbuffer!\n\n### Relaxed data access patterns\n\nGPUs are brilliantly fast, but there's a reason that we don't use them for\neverything: they're also *heavily* optimised around very specific kinds of data\nmanipulation. CPUs are more general-purpose and as a result, `euc` allows much\nmore dynamic access to rendering resources.\n\n## Coordinate System\n\nBy default, `euc` uses a left-handed coordinate system with 0-1 z clipping (like\nVulkan). However, both of these properties can be changed independently and\n`euc` provides coordinate system constants that correspond to those of common\ngraphics APIs such as:\n\n- `CoordinateMode::VULKAN`\n- `CoordinateMode::OPENGL`\n- `CoordinateMode::METAL`\n- `CoordinateMode::DIRECTX`\n\nNote that using these constants do not change the coordinates of things like\ntexture samplers, yet.\n\n## Release Mode\n\nCargo, by default, compiles Rust code in debug mode. In this mode, very few\noptimisations are made upon the code, and as a result the performance of\nsoftware rendering tends to suffer. To experience this project with good\nperformance, make sure to compile with the `--release` flag.\n\n## `no_std`\n\n`euc` can be compiled on platforms that lack standard library support. This\nmakes it ideal for rendering 3D graphics on embedded devices. You can enable\n`no_std` support by disabling the default features and enabling the `libm`\nfeature in your `Cargo.toml` file like so:\n\n```toml\n[dependencies]\neuc = { version = \"x.y.z\", default-features = false, features = [\"libm\"] }\n```\n\n## Goals\n\n- Support programmable shaders written in Rust.\n\n- Support common pipeline features such as texture samplers, multiple rendering\n  passes, uniform data, etc.\n\n- Simple, elegant API that scales well and doesn't get in the way.\n\n- Correctness, where doing so doesn't significantly compromise performance.\n\n## Non-Goals\n\n- Extreme optimisation (although obvious low-hanging fruit will be picked).\n\n- Compliance/compatibility with an existing API (i.e: OpenGL).\n\n## License\n\n`euc` is distributed under either of:\n\n- Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)\n\n- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)\n\nat the discretion of the user.\n","funding_links":[],"categories":["Rust"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzesterer%2Feuc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzesterer%2Feuc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzesterer%2Feuc/lists"}