{"id":15286530,"url":"https://github.com/andros21/rustracer","last_synced_at":"2025-04-13T02:32:59.754Z","repository":{"id":37000429,"uuid":"467843613","full_name":"andros21/rustracer","owner":"andros21","description":"rustracer - a multi-threaded raytracer in pure rust","archived":false,"fork":false,"pushed_at":"2025-04-06T07:10:24.000Z","size":29311,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-06T07:31:16.190Z","etag":null,"topics":["cargo","clap","cosign","coverage","cue","rayon","raytracing","rust","slsa","yaml"],"latest_commit_sha":null,"homepage":"https://andros21.github.io/rustracer/docs","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andros21.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2022-03-09T08:40:40.000Z","updated_at":"2025-04-06T07:10:25.000Z","dependencies_parsed_at":"2023-10-14T17:32:24.842Z","dependency_job_id":"72cdd353-a577-477c-9b13-462c205a4283","html_url":"https://github.com/andros21/rustracer","commit_stats":{"total_commits":623,"total_committers":7,"mean_commits":89.0,"dds":0.391653290529695,"last_synced_commit":"9066ab2637261fbca443a83055cc4f857a03ec15"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andros21%2Frustracer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andros21%2Frustracer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andros21%2Frustracer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andros21%2Frustracer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andros21","download_url":"https://codeload.github.com/andros21/rustracer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248657830,"owners_count":21140842,"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":["cargo","clap","cosign","coverage","cue","rayon","raytracing","rust","slsa","yaml"],"created_at":"2024-09-30T15:16:18.378Z","updated_at":"2025-04-13T02:32:58.276Z","avatar_url":"https://github.com/andros21.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- PROJECT LOGO --\u003e\n\u003cbr\u003e\n\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"https://github.com/andros21/rustracer\"\u003e\n    \u003cpicture\u003e\n      \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://user-images.githubusercontent.com/58751603/176992080-d96e1e43-5309-45cd-968e-76c4ea132dde.png\"\u003e\n      \u003cimg src=\"https://user-images.githubusercontent.com/58751603/176992080-d96e1e43-5309-45cd-968e-76c4ea132dde.png\" alt=\"Logo\" width=\"470\"\u003e\n    \u003c/picture\u003e\n  \u003c/a\u003e\n  \u003ch3 style=\"border-bottom: 0px;\"\u003ea multi-threaded raytracer in pure rust\u003c/h3\u003e\n  \u003ca href=\"https://github.com/andros21/rustracer/actions/workflows/ci.yml\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/actions/workflow/status/andros21/rustracer/ci.yml?branch=master\u0026style=flat-square\u0026label=ci\u0026logo=github\" alt=\"CI\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/andros21/rustracer/actions/workflows/ci.yml\"\u003e\n    \u003cimg src=\"https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/andros21/0e20cd331d0800e3299298a3868aab7a/raw/rustracer__master.json\" alt=\"Coverage\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/andros21/rustracer/actions/workflows/cd.yml\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/actions/workflow/status/andros21/rustracer/cd.yml?style=flat-square\u0026label=cd\u0026logo=github\" alt=\"CD\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/andros21/rustracer/actions/workflows/e2e.yml\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/actions/workflow/status/andros21/rustracer/e2e.yml?style=flat-square\u0026label=e2e\u0026logo=github\" alt=\"E2E\"\u003e\u003c/a\u003e\n  \u003cbr\u003e\n  \u003ca href=\"https://github.com/andros21/rustracer/releases\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/v/release/andros21/rustracer?color=orange\u0026\u0026sort=semver\u0026style=flat-square\u0026logo=github\" alt=\"Version\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://slsa.dev\"\u003e\n    \u003cimg src=\"https://slsa.dev/images/gh-badge-level3.svg\" alt=\"slsa3\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://crates.io/crates/rustracer\"\u003e\n    \u003cimg src=\"https://img.shields.io/crates/v/rustracer?color=orange\u0026logo=rust\u0026style=flat-square\" alt=\"Cratesio Version\"\u003e\u003c/a\u003e\n  \u003cbr\u003e\n  \u003ca href=\"https://github.com/andros21/rustracer/blob/master/LICENSE\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/license/andros21/rustracer?color=blue\u0026style=flat-square\u0026logo=gnu\" alt=\"License\"\u003e\n  \u003c/a\u003e\n  \u003cdiv align=\"center\"\u003e\n    \u003ca href=\"#prerequisites\"\u003ePrerequisites\u003c/a\u003e\n    ·\n    \u003ca href=\"#installation\"\u003eInstallation\u003c/a\u003e\n    ·\n    \u003ca href=\"#usage\"\u003eUsage\u003c/a\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n\n## Prerequisites\n\n### Platform requirements\n\n- `x86_64-unknown-linux-gnu` \u003ca href=\"#note1\"\u003e\u003csup\u003e(1)\u003c/sup\u003e\u003c/a\u003e\n- `x86_64-unknown-linux-musl`\n\n\u003cp id=\"note1\"\u003e\u003csub\u003e\u003cstrong\u003e\u003csup\u003e(1)\u003c/sup\u003e note:\u003c/strong\u003e glibc version \u003e= 2.35\u003c/sub\u003e\u003c/p\u003e\n\n### Build requirements\n\n- for **users** install [`cargo`](https://github.com/rust-lang/cargo/) stable latest build system (see [`rust-toolchain.toml`](https://github.com/andros21/rustracer/blob/master/rust-toolchain.toml) for stable version)\n\n- for **devels** install [`rustup`](https://www.rust-lang.org/tools/install) that will automatically provision the correct toolchain\n\n  For unit tests coverage [`cargo-tarpaulin`](https://crates.io/crates/cargo-tarpaulin) is required as additional component\n\n  There is an handy [`makefile`](https://github.com/andros21/rustracer/blob/master/makefile) useful to:\n\n  - preview documentation built with `rustdoc`\n  - preview html code coverage analysis created with `cargo-tarpaulin`\n  - create demo animations\n\n## Installation\n\n### From binary\n\nInstall from binary:\n\n\u003ch4\u003e\n\u003ccode\u003ecurl -sSf https://andros21.github.io/rustracer/install.sh | bash\u003c/code\u003e\u0026nbsp;\u0026nbsp;\u003ca href=\"#note2\"\u003e\u003csup\u003e(2)\u003c/sup\u003e\u003c/a\u003e\n\u003c/h4\u003e\n\n\u003cbr\u003e\n\u003cdetails\u003e\n\u003csummary\u003eclick to show other installation options\u003c/summary\u003e\n\n```bash\n## Install the latest version `gnu` variant in `~/.rustracer/bin`\nexport PREFIX='~/.rustracer/'\ncurl -sSf https://andros21.github.io/rustracer/install.sh | bash -s -- gnu\n\n## Install the `0.4.0` version `musl` variant in `~/.rustracer/bin`\nexport PREFIX='~/.rustracer/'\ncurl -sSf https://andros21.github.io/rustracer/install.sh | bash -s -- musl 0.4.0\n```\n\n\u003c/details\u003e\n\n\u003cp id=\"note2\"\u003e\u003csub\u003e\u003cstrong\u003e\u003csup\u003e(2)\u003c/sup\u003e note:\u003c/strong\u003e will install latest musl release in \u003ccode\u003e~/.local/bin\u003c/code\u003e\u003c/sub\u003e\u003c/p\u003e\n\n### From source\n\nInstall from source code, a template could be:\n\n\u003ch4\u003e\n   \u003ccode\u003e cargo install rustracer\u003c/code\u003e\u0026nbsp;\u0026nbsp;\u003ca href=\"#note3\"\u003e\u003csup\u003e(3)\u003c/sup\u003e\u003c/a\u003e\n\u003c/h4\u003e\n\n\u003cbr\u003e\n\u003cdetails\u003e\n\u003csummary\u003eclick to show other installation options\u003c/summary\u003e\n\n```bash\n## Install the latest version using `Cargo.lock` in `~/.rustracer/bin`\nexport PREFIX='~/.rustracer/'\ncargo install --locked --root $PREFIX rustracer\n\n## Install the `0.4.0` version in `~/.rustracer/bin`\nexport VER='0.4.0'\nexport PREFIX='~/.rustracer/'\ncargo install --root $PREFIX --version $VER rustracer\n```\n\n\u003c/details\u003e\n\n\u003cp id=\"note3\"\u003e\u003csub\u003e\u003cstrong\u003e\u003csup\u003e(3)\u003c/sup\u003e note:\u003c/strong\u003e will install latest release in \u003ccode\u003e~/.cargo/bin\u003c/code\u003e\u003c/sub\u003e\u003c/p\u003e\n\n## Usage\n\n### rustracer\n\n| **subcommands**                                   | **description**                              |\n| :------------------------------------------------ | :------------------------------------------- |\n| [**rustracer-convert**](#rustracer-convert)       | convert an hdr image into ldr image          |\n| [**rustracer-demo**](#rustracer-demo)             | render a simple demo scene (example purpose) |\n| [**rustracer-render**](#rustracer-render)         | render a scene from file (yaml formatted)    |\n| [**rustracer-completion**](#rustracer-completion) | generate shell completion script (hidden)    |\n\n\u003cbr\u003e\n\u003cdetails\u003e\n\u003csummary\u003eclick to show \u003cstrong\u003erustracer -h \u003c/strong\u003e\u003c/summary\u003e\n\n```console\na multi-threaded raytracer in pure rust\n\nUsage: rustracer \u003cCOMMAND\u003e\n\nCommands:\n  convert  Convert HDR (pfm) image to LDR (ff|png) image\n  demo     Render a demo scene (hard-coded in main)\n  render   Render a scene from file (yaml formatted)\n\nOptions:\n  -h, --help     Print help\n  -V, --version  Print version\n\n```\n\n\u003c/details\u003e\n\n\u003cdiv align=\"center\"\u003e \u003chr width=\"30%\"\u003e \u003c/div\u003e\n\n### rustracer-convert\n\nConvert a pfm file to png:\n\n\u003ch5\u003e\n   \u003ccode\u003erustracer convert image.pfm image.png\u003c/code\u003e\n\u003c/h5\u003e\n\n\u003cbr\u003e\n\u003cdetails\u003e\n\u003csummary\u003eclick to show \u003cstrong\u003erustracer-convert -h \u003c/strong\u003e\u003c/summary\u003e\n\n```console\nConvert HDR (pfm) image to LDR (ff|png) image\n\nUsage: rustracer convert [OPTIONS] \u003cHDR\u003e \u003cLDR\u003e\n\nArguments:\n  \u003cHDR\u003e  Input pfm image\n  \u003cLDR\u003e  Output image [possible formats: ff, png]\n\nOptions:\n  -v, --verbose          Print stdout information\n  -f, --factor \u003cFACTOR\u003e  Normalization factor [default: 1.0]\n  -g, --gamma \u003cGAMMA\u003e    Gamma parameter [default: 1.0]\n  -h, --help             Print help (see more with '--help')\n  -V, --version          Print version\n\n```\n\n\u003c/details\u003e\n\n\u003cdiv align=\"center\"\u003e \u003chr width=\"30%\"\u003e \u003c/div\u003e\n\n### rustracer-demo\n\nRendering demo scene:\n\n\u003cdiv align=\"center\"\u003e\n   \u003ch5\u003e\n      \u003ccode\u003erustracer demo --width 1920 --height 1080 --anti-aliasing 3 demo.png\u003c/code\u003e\u0026nbsp;\u0026nbsp;\u003ca href=\"#note4\"\u003e\u003csup\u003e(4)\u003c/sup\u003e\u003c/a\u003e\n   \u003c/h5\u003e\n   \u003cimg src=\"https://github.com/andros21/rustracer/raw/master/examples/demo.png\" width=\"500\" alt=\"rustracer-demo-png\"/\u003e\n   \u003cp\u003e\u003csub\u003e\u003cstrong\u003edemo.png:\u003c/strong\u003e cpu Intel(R) Xeon(R) CPU E5520 @ 2.27GHz | threads 8 | time ~35s\u003c/sub\u003e\u003c/p\u003e\n\u003c/div\u003e\n\n\\\ndemo scene 360 degree (see [`makefile`](https://github.com/andros21/rustracer/blob/master/makefile)):\n\n\u003cdiv align=\"center\"\u003e\n  \u003ch5\u003e\n      \u003ccode\u003emake demo.gif\u003c/code\u003e\u0026nbsp;\u0026nbsp;\u003ca href=\"#note4\"\u003e\u003csup\u003e(4)\u003c/sup\u003e\u003c/a\u003e\n  \u003c/h5\u003e\n  \u003cimg src=\"https://github.com/andros21/rustracer/raw/master/examples/demo.gif\" width=\"500\" alt=\"rustracer-demo-gif\"/\u003e\n  \u003cp\u003e\u003csub\u003e\u003cstrong\u003edemo.gif:\u003c/strong\u003e cpu Intel(R) Xeon(R) CPU E5520 @ 2.27GHz | threads 8 | time ~15m\u003c/sub\u003e\u003c/p\u003e\n\u003c/div\u003e\n\n\u003cbr\u003e\n\u003cdetails\u003e\n\u003csummary\u003eclick to show \u003cstrong\u003erustracer-demo -h \u003c/strong\u003e\u003c/summary\u003e\n\n```console\nRender a demo scene (hard-coded in main)\n\nUsage: rustracer demo [OPTIONS] \u003cOUTPUT\u003e\n\nArguments:\n  \u003cOUTPUT\u003e  Output image [possible formats: ff, png]\n\nOptions:\n  -v, --verbose                        Print stdout information\n      --output-pfm                     Output also hdr image\n      --orthogonal                     Use orthogonal camera instead of perspective camera\n      --width \u003cWIDTH\u003e                  Image width [default: 640]\n      --height \u003cHEIGHT\u003e                Image height [default: 480]\n      --angle-deg \u003cANGLE_DEG\u003e          View angle (in degrees) [default: 0.0]\n  -f, --factor \u003cFACTOR\u003e                Normalization factor [default: 1.0]\n  -g, --gamma \u003cGAMMA\u003e                  Gamma parameter [default: 1.0]\n  -a, --algorithm \u003cALGORITHM\u003e          Rendering algorithm [default: pathtracer] [possible values: onoff, flat, pathtracer]\n  -n, --num-of-rays \u003cNUM_OF_RAYS\u003e      Number of rays [default: 10]\n  -m, --max-depth \u003cMAX_DEPTH\u003e          Maximum depth [default: 3]\n      --init-state \u003cINIT_STATE\u003e        Initial random seed (positive number) [default: 42]\n      --init-seq \u003cINIT_SEQ\u003e            Identifier of the random sequence (positive number) [default: 54]\n      --anti-aliasing \u003cANTI_ALIASING\u003e  Anti-aliasing level [default: 1]\n  -h, --help                           Print help (see more with '--help')\n  -V, --version                        Print version\n\n```\n\n\u003c/details\u003e\n\n\u003cp id=\"note4\"\u003e\u003csub\u003e\u003cstrong\u003e\u003csup\u003e(4)\u003c/sup\u003e note:\u003c/strong\u003e all available threads are used, set \u003ccode\u003eRAYON_NUM_THREADS\u003c/code\u003e to override\u003c/sub\u003e\u003c/p\u003e\n\n\u003cdiv align=\"center\"\u003e \u003chr width=\"30%\"\u003e \u003c/div\u003e\n\n### rustracer-render\n\nRendering demo scene from scene file [`examples/demo.yml`](https://github.com/andros21/rustracer/blob/master/examples/demo.yml):\n\n\u003ch5\u003e\n   \u003ccode\u003erustracer render --anti-aliasing 3 examples/demo.yml demo.png\u003c/code\u003e\u0026nbsp;\u0026nbsp;\u003ca href=\"#note5\"\u003e\u003csup\u003e(5)\u003c/sup\u003e\u003c/a\u003e\n\u003c/h5\u003e\n\nyou can use this example scene to learn how to write your custom scene, ready to be rendered!\n\nBut let's unleash the power of a scene encoded in data-serialization language such as yaml\\\nWell repetitive scenes could be nightmare to be written, but for these (and more) there is [`cue`](https://github.com/cue-lang/cue)\n\nLet's try to render a 3D fractal, a [sphere-flake](https://en.wikipedia.org/wiki/Koch_snowflake), but without manually write a yaml scene file\\\nwe can automatic generate it from [`examples/flake.cue`](https://github.com/andros21/rustracer/blob/master/examples/flake.cue)\n\n```bash\ncue eval flake.cue -e \"flake\" -f flake.cue.yml   # generate yml from cue\ncat flake.cue.yml | sed \"s/'//g\" \u003e flake.yml     # little tweaks\nwc -l flake.cue flake.yml                        # compare lines number\n   92 flake.cue                                  # .\n 2750 flake.yml                                  # .\n```\n\nso with this trick we've been able to condense a scene info from 2750 to 92 lines, x30 shrink! 😎\\\nand the generated `flake.yml` can be simple parsed\n\n\u003cdiv align=\"center\"\u003e\n   \u003ch5\u003e\n   \u003ccode\u003erustracer render --width 1280 --height 720 --anti-aliasing 3 flake.yml flake.png\u003c/code\u003e\u0026nbsp;\u0026nbsp;\u003ca href=\"#note5\"\u003e\u003csup\u003e(5)\u003c/sup\u003e\u003c/a\u003e\n   \u003c/h5\u003e\n  \u003cimg src=\"https://github.com/andros21/rustracer/raw/master/examples/flake.png\" width=\"500\" alt=\"rustracer-flake\"/\u003e\n  \u003cp\u003e\u003csub\u003e\u003cstrong\u003eflake.png:\u003c/strong\u003e cpu Intel(R) Xeon(R) CPU E5520 @ 2.27GHz | threads 8 | time ~7h\u003c/sub\u003e\u003c/p\u003e\n\u003c/div\u003e\n\n\u003cbr\u003e\n\u003cdetails\u003e\n\u003csummary\u003eclick to show \u003cstrong\u003erustracer-render -h \u003c/strong\u003e\u003c/summary\u003e\n\n```console\nRender a scene from file (yaml formatted)\n\nUsage: rustracer render [OPTIONS] \u003cINPUT\u003e \u003cOUTPUT\u003e\n\nArguments:\n  \u003cINPUT\u003e   Input scene file\n  \u003cOUTPUT\u003e  Output image [possible formats: ff, png]\n\nOptions:\n  -v, --verbose                        Print stdout information\n      --output-pfm                     Output also hdr image\n      --width \u003cWIDTH\u003e                  Image width [default: 640]\n      --height \u003cHEIGHT\u003e                Image height [default: 480]\n      --angle-deg \u003cANGLE_DEG\u003e          View angle (in degrees) [default: 0.0]\n  -f, --factor \u003cFACTOR\u003e                Normalization factor [default: 1.0]\n  -g, --gamma \u003cGAMMA\u003e                  Gamma parameter [default: 1.0]\n  -a, --algorithm \u003cALGORITHM\u003e          Rendering algorithm [default: pathtracer] [possible values: onoff, flat, pathtracer]\n  -n, --num-of-rays \u003cNUM_OF_RAYS\u003e      Number of rays [default: 10]\n  -m, --max-depth \u003cMAX_DEPTH\u003e          Maximum depth [default: 3]\n      --init-state \u003cINIT_STATE\u003e        Initial random seed (positive number) [default: 42]\n      --init-seq \u003cINIT_SEQ\u003e            Identifier of the random sequence (positive number) [default: 54]\n      --anti-aliasing \u003cANTI_ALIASING\u003e  Anti-aliasing level [default: 1]\n  -h, --help                           Print help (see more with '--help')\n  -V, --version                        Print version\n\n```\n\n\u003c/details\u003e\n\n\u003cp id=\"note5\"\u003e\u003csub\u003e\u003cstrong\u003e\u003csup\u003e(5)\u003c/sup\u003e note:\u003c/strong\u003e all available threads are used, set \u003ccode\u003eRAYON_NUM_THREADS\u003c/code\u003e to override\u003c/sub\u003e\u003c/p\u003e\n\n\u003cdiv align=\"center\"\u003e \u003chr width=\"30%\"\u003e \u003c/div\u003e\n\n### rustracer-completion\n\nSimple generate completion script for `bash` shell (same for `fish` and `zsh`):\n\n\u003cdiv align=\"center\"\u003e\n   \u003ch5\u003e\n      \u003ccode\u003erustracer completion bash\u003c/code\u003e \u003ca href=\"#note6\"\u003e\u003csup\u003e(6)\u003c/sup\u003e\u003c/a\u003e\n   \u003c/h5\u003e\n   \u003ca href=\"https://asciinema.org/a/1lqL4683WLvXPfOo5W608je6V?autoplay=1\u0026speed=2\" target=\"_blank\"\u003e\u003cimg src=\"https://asciinema.org/a/1lqL4683WLvXPfOo5W608je6V.svg\" width=\"500\" /\u003e\u003c/a\u003e\n   \u003cp\u003e\u003csub\u003e\u003cstrong\u003enote:\u003c/strong\u003e close-open your shell, and here we go, tab completions now available!\u003c/sub\u003e\u003c/p\u003e\n\u003c/div\u003e\n\n\u003cbr\u003e\n\u003cdetails\u003e\n\u003csummary\u003eclick to show \u003cstrong\u003erustracer-completion -h \u003c/strong\u003e\u003c/summary\u003e\n\n```console\nGenerate shell completion script\n\nUsage: rustracer completion [OPTIONS] \u003cSHELL\u003e\n\nArguments:\n  \u003cSHELL\u003e  Shell to generate script for [possible values: bash, fish, zsh]\n\nOptions:\n  -o, --output \u003cOUTPUT\u003e  Specify output script file\n  -h, --help             Print help (see more with '--help')\n  -V, --version          Print version\n\n```\n\n\u003c/details\u003e\n\n\u003cp id=\"note6\"\u003e\u003csub\u003e\u003cstrong\u003e\u003csup\u003e(6)\u003c/sup\u003e note:\u003c/strong\u003e \u003ccode\u003ebash\u003e4.1\u003c/code\u003e and \u003ccode\u003ebash-complete\u003e2.9\u003c/code\u003e\u003c/sub\u003e\u003c/p\u003e\n\n\u003cdiv align=\"center\"\u003e \u003chr width=\"30%\"\u003e \u003c/div\u003e\n\n## Acknowledgements\n\n- [pytracer](https://github.com/ziotom78/pytracer) - a simple raytracer in pure Python\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandros21%2Frustracer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandros21%2Frustracer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandros21%2Frustracer/lists"}