{"id":15493518,"url":"https://github.com/sinclairzx81/black","last_synced_at":"2025-09-11T08:33:59.927Z","repository":{"id":66034978,"uuid":"212876980","full_name":"sinclairzx81/black","owner":"sinclairzx81","description":"A Software Rasterizer written in Rust","archived":false,"fork":false,"pushed_at":"2022-10-10T04:00:05.000Z","size":661,"stargazers_count":25,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-22T20:11:38.524Z","etag":null,"topics":["experiment","graphics","rasterizer","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sinclairzx81.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"license","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-10-04T18:16:37.000Z","updated_at":"2025-01-05T11:06:31.000Z","dependencies_parsed_at":null,"dependency_job_id":"8f9dd2b2-6c0c-4615-9a2f-facc60f38b49","html_url":"https://github.com/sinclairzx81/black","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sinclairzx81/black","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sinclairzx81%2Fblack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sinclairzx81%2Fblack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sinclairzx81%2Fblack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sinclairzx81%2Fblack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sinclairzx81","download_url":"https://codeload.github.com/sinclairzx81/black/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sinclairzx81%2Fblack/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274602178,"owners_count":25315199,"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","status":"online","status_checked_at":"2025-09-11T02:00:13.660Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["experiment","graphics","rasterizer","rust"],"created_at":"2024-10-02T08:07:42.318Z","updated_at":"2025-09-11T08:33:59.909Z","avatar_url":"https://github.com/sinclairzx81.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n\u003cdiv align=\"center\"\u003e\n  \u003ch1\u003eBlack\u003c/h1\u003e\n  \u003cp\u003eA software rasterizer for Rust\u003c/p\u003e\n  \u003cimg src=\"./models/cube.png\"\u003e\n\u003c/div\u003e\n\n## Overview\n\nBlack is a small software rasterizer for Rust. It allows one to create simple 3D visualizations that are run entirely on the CPU. It provides a fairly low level graphics API specifically geared towards triangle rasterization and allows for custom vertex and fragment shaders to be implemented with Rust traits.\n\nThis project was primarily written as an exercise in Rust. It is offered to anyone who finds it of use.\n\n## Building\n\nThis project was built against `rustc 1.39.0-nightly (6ef275e6c 2019-09-24)`. The crate being used to present the window is the `mini-fb` crate. If building on Windows, you will need `Windows C++ build tools`. Once installed, just run the following from the project root to start the example project.\n\n```bash\n$ cargo run --release\n```\n\n## Example\n\nThe following code renders single RGB triangle. Note that the `Varying` type must implement `Interpolate` which performs perspective correct per fragment interpolation across the triangle.\n\nNote the implementation of `TargetBuffer` which is used to receive fragment shader output. If this code was output to a window, or other output device, this code will result in the image below. \n\n\u003e Refer to the example project in this repository for an implementation of `TargetBuffer`. It is leveraging the most excellent [mini_fb](https://github.com/emoon/rust_minifb) crate. This should work on Windows, Mac and Linux.\n\n\u003cimg src=\"./models/triangle.png\"\u003e\n\n\n```rust\n#[macro_use] extern crate black;\n\nuse black::{ TargetBuffer, DepthBuffer, Raster, Interpolate, VertexProgram, FragmentProgram };\nuse black::{ Vec4, Vec3, Mat4 };\n\n// ----------------------------------------------\n// Uniform, Vertex and Varying types\n// ----------------------------------------------\n\nstruct Uniform {\n    projection: Mat4,\n    matrix:     Mat4,\n    view:       Mat4\n}\nstruct Vertex {\n    position: Vec4,\n    color:    Vec3\n}\n#[derive(Interpolate)]\nstruct Varying {\n    position: Vec4,\n    color:    Vec3\n}\n\n// ----------------------------------------------\n// VertexProgram\n// ----------------------------------------------\n\nstruct VertexShader; \nimpl VertexProgram for VertexShader {\n    type Uniform = Uniform;\n    type Varying = Varying;\n    type Vertex  = Vertex;\n\n    fn main(\u0026self, uniform: \u0026Uniform, vertex: \u0026Vertex, varying: \u0026mut Varying) -\u003e Vec4 {\n        // assign varying to be interpolated across this primitive.\n        varying.position = vertex.position;\n        varying.color    = vertex.color\n        \n        // transform the vertex (analogous to gl_Position transform)\n        input.position * (uniform.matrix * (uniform.view * uniform.projection))\n    }\n}\n\n// -----------------------------------------\n// FragmentProgram\n// -----------------------------------------\n\nstruct FragmentShader; \nimpl FragmentProgram for FragmentShader {\n    type Uniform = Uniform;\n    type Varying = Varying;\n\n    fn main(\u0026self, uniform: \u0026Uniform, varying: \u0026Varying) -\u003e Vec4 {\n        Vec4::new(\n            varying.color.x, \n            varying.color.y, \n            varying.color.z, \n            1.0)\n    }\n}\n\n// -----------------------------------------\n// TargetBuffer\n// -----------------------------------------\n\nstruct ColorBuffer; \nimpl TargetBuffer for ColorBuffer {\n    fn width (\u0026self) -\u003e usize { 256 }\n    fn height(\u0026self) -\u003e usize { 256 }\n    fn set(\u0026mut self, x: usize, y: usize, color: Vec4) {\n        // Invoked per fragment. Take vec4 output from fragment\n        // shader and write to output device or other buffer.\n    }\n}\n\nfn main() {\n    \n    // Color and Depth buffers.\n    let mut color_buffer = ColorBuffer;\n    let mut depth_buffer = DepthBuffer::new(256, 256);\n\n    // Sets up the uniforms for this draw. Works\n    // in a similar fashion to GLSL uniforms.\n    let uniform = Uniform {\n        projection: Mat4::perspective_fov(90.0, 1.0, 0.1, 1000.0),\n        matrix:     Mat4::identity(),\n        view:       Mat4::look_at(\n            \u0026Vec3::new(0.0, 0.0, 3.0),\n            \u0026Vec3::new(0.0, 0.0, 0.0),\n            \u0026Vec3::new(0.0, 1.0, 0.0),\n        ),\n    }\n\n    // Rasterizes this triangle into the given\n    // OutputBuffer. Depth values stored in the\n    // given depth_buffer.\n    Raster::triangle(\n        \u0026VertexShader,\n        \u0026FragmentShader,\n        \u0026mut depth_buffer,\n        \u0026mut color_buffer,\n        \u0026uniform,\n        \u0026Vertex { \n            position: Vec4::new(0.0, 1.0, 0.0, 1.0),\n            color:    Vec3::new(1.0, 0.0, 0.0),\n        },\n        \u0026Vertex {\n            position: Vec4::new(-1.0, -1.0, 0.0, 1.0),\n            color:    Vec3::new(0.0, 1.0, 0.0),\n        },\n        \u0026Vertex { \n            position: Vec4::new(1.0, -1.0, 0.0, 1.0),\n            color:    Vec3::new(0.0, 0.0, 1.0),\n        } \n    );\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsinclairzx81%2Fblack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsinclairzx81%2Fblack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsinclairzx81%2Fblack/lists"}