{"id":13732496,"url":"https://github.com/Hi-Rez/Satin","last_synced_at":"2025-05-08T07:30:55.856Z","repository":{"id":35085249,"uuid":"200550855","full_name":"Hi-Rez/Satin","owner":"Hi-Rez","description":"A 3D Graphics Framework built on Apple's Metal","archived":true,"fork":false,"pushed_at":"2025-04-15T23:40:40.000Z","size":73249,"stargazers_count":801,"open_issues_count":0,"forks_count":54,"subscribers_count":27,"default_branch":"main","last_synced_at":"2025-05-04T05:16:57.341Z","etag":null,"topics":["3d","3d-graphics-framework","apple-metal","augmented-reality","gfx","graphics","metal","metalapi","metalkit","satin","shaders","swift","xcode"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Hi-Rez.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},"funding":{"github":["hi-rez"]}},"created_at":"2019-08-04T23:14:53.000Z","updated_at":"2025-04-27T17:03:19.000Z","dependencies_parsed_at":"2023-02-14T11:46:14.678Z","dependency_job_id":"9dc70e52-66b4-489c-8143-ad5165b3f690","html_url":"https://github.com/Hi-Rez/Satin","commit_stats":{"total_commits":581,"total_committers":9,"mean_commits":64.55555555555556,"dds":"0.12048192771084343","last_synced_commit":"fdccfe421550e148958bf38d4990057bda637c9e"},"previous_names":[],"tags_count":125,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hi-Rez%2FSatin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hi-Rez%2FSatin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hi-Rez%2FSatin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hi-Rez%2FSatin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Hi-Rez","download_url":"https://codeload.github.com/Hi-Rez/Satin/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253020702,"owners_count":21841625,"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","3d-graphics-framework","apple-metal","augmented-reality","gfx","graphics","metal","metalapi","metalkit","satin","shaders","swift","xcode"],"created_at":"2024-08-03T02:01:59.477Z","updated_at":"2025-05-08T07:30:55.804Z","avatar_url":"https://github.com/Hi-Rez.png","language":"Swift","funding_links":["https://github.com/sponsors/hi-rez"],"categories":["Swift","OOM-Leaks-Crash","Frameworks"],"sub_categories":["Graphs Processing And Rendering"],"readme":"# Satin - A 3D Graphics Framework built on Apple's Metal\n\n![build status](https://github.com/Hi-Rez/SatinPro/actions/workflows/build.yml/badge.svg)\n\u003cimg src=\"https://img.shields.io/badge/SPM-5.9-blue.svg?style=flat\"\n     alt=\"Swift Package Manager (SPM) compatible\" /\u003e\n\n# About :wave:\n\nSatin is a 3D graphics framework (inspired by threejs) that helps designers and developers work with Apple's Metal API. Satin provides helpful classes for creating meshes, materials, buffers, uniforms, geometries, pipelines (shaders), compute kernels, and more.\n\nSatin makes simple graphics tasks fun and easy to accomplish quickly and complex graphics tasks easier to accomplish without having to write tons of boilerplate code. It does this by providing structure, opinions, and tons of helpful abstractions on Metal to help you get up and rendering / coding in a few minutes. \n\nSatin is mostly Swift based, however when performing expensive CPU operations, Satin uses SatinCore, which is written in C (for tasks like geometry generation, triangulation, bounds \u0026 computational geometry calculations, and more) to make sure things are as fast as possible.\n\n# Supported Platforms\n\n- macOS 14.0+\n- iOS 17.0+\n- visionOS 2.0+\n\n# Installation\n\n### Swift Package Manager\n\n[Swift Package Manager](https://swift.org/package-manager/) is a tool for automating the distribution of Swift code and is integrated into the `Swift` compiler. Once you have your Swift package set up, adding `Satin` as a dependency is as easy as adding it to the `dependencies` value of your `Package.swift`.\n\n```swift\n  dependencies: [\n      .package(url: \"https://github.com/Hi-Rez/Satin.git\", .branch(\"main\"))\n  ]\n```\n\n# Features :clipboard:\n\n- [x] Tons of examples that show how to use the API (2D, 3D, Raycasting, Compute, Exporting, Live Coding, AR, etc).\n- [x] Object, Mesh, InstancedMesh, TessellationMesh, Material, Shader, Geometry, Camera and Renderer classes.\n- [x] PBR Standard \u0026 Physical Materials (Based on Disney's PBR Implementation)\n- [x] You can live code shaders :fire:.\n- [x] A couple builtin Materials (BasicColor, BasicTexture, BasicDiffuse, Normal, UV Color, Skybox, MatCap, PBR Standard, PBR Physical, and more).\n- [x] Tons of Geometries (Box, Sphere, IcoSphere, Circle, Cone, Quad, Plane, Capsule, RoundedRect, Text, and more).\n- [x] Cameras (Orthographic, Perspective) \u0026 Camera Controllers.\n- [x] SDF Text Rendering\n- [x] Flexible Vertex Structure\n- [x] Run-time \u0026 Dynamic Struct creation via Parameters for Buffers and Uniforms.\n- [x] Metal Shader Compiler (useful when live coding, using #include during runtime)\n- [x] Metal Pipeline Caches (Render \u0026 Compute)\n- [x] Buffer \u0026 Texture Compute Systems make running compute kernels a breeze.\n- [x] Generators for BRDF LUT, Image Based Lighting (HDR -\u003e Specular \u0026 Diffuse IBL Textures)\n- [x] Fast raycasting via Bounding Volume Hierachies (very helpful to see what you clicked or tapped on).\n- [x] Hooks for custom Metal rendering via Mesh's preDraw, Material's onBind, Buffer \u0026 Texture Computes' preCompute, etc\n- [x] Hooks for custom rendering via the Renderable protocol\n- [x] FileWatcher for checking if a resource or shader file has changed.\n- [x] Tons of examples to show how to use the API.\n- [x] Examples that show how to use Satin \u0026 ARKit\n- [x] Basic Directional Shadows\n\n# Usage :rocket:\n\nSatin helps to draw things with Metal. To get up and running quickly without tons of boilerplate code and worrying about triple buffering or event (setup, update, resize, key, mouse, touch) callbacks, The example below shows how to use Satin to render a color changing box that looks at a moving point in the scene.\n\n### Simple Example:\n\n```swift\nimport SwiftUI\nimport Satin\n\n// Subclass Satin's Renderer to get triple buffered rendering and\n// callbacks for Setup, Update, Draw, Resize and Events\nfinal class SimpleRenderer: MetalViewRenderer {\n    // A Satin Renderer handles setting the Content on all the objects in the scene graph\n    // and drawing the scene either to a texture or on screen\n\n    // Create a Satin Renderer by passing in a context, scene and camera\n    lazy var renderer = Renderer(context: defaultContext)\n\n    // A PerspectiveCamera is used to render the scene using perspective projection\n    // All Satin Cameras inherit from Object, so it has\n    let camera = {\n        let camera = PerspectiveCamera(\n            position: [3.0, 3.0, 3.0],\n            near: 0.01,\n            far: 100.0,\n            fov: 45\n        )\n        camera.lookAt(.zero)\n        return camera\n    }()\n\n    // An Object is just an empty node in Satin's Scene Graph, it can have children and a parent\n    // Objects have a position, orientation, scale and label\n    lazy var scene = Object(label: \"Scene\", [boxMesh])\n\n    // Meshes inherit from Object, so they have all the properties an object has.\n    // A Mesh has unique properties like geometry, material and rendering properties\n    // To create renderable object aka a Mesh, you passing it a Geometry and Material like so\n    let boxMesh = Mesh(\n        label: \"Box\",\n        geometry: BoxGeometry(size: 1.0),\n        material: BasicDiffuseMaterial(0.75)\n    )\n\n    // Create a time variable so we can change things in our scene over time\n    var time: Float = 0.0\n\n    // Satin calls setup once after it has a valid MTKView (mtkView)\n    override func setup() {\n        renderer.setClearColor(.one)\n    }\n\n    // Satin calls update whenever a new frame is ready to be updated, make scene changes here\n    override func update() {\n        // We increment our time variable so we can procedurally set the box mesh's orientation and material color\n        time += 0.05\n        let sx = sin(time)\n        let sy = cos(time)\n\n        // Setting a material property done by using the set function, this modifies the material's uniforms\n        boxMesh.material?.set(\"Color\", [abs(sx), abs(sy), abs(sx + sy), 1.0])\n\n        // You can manually an object's position, orientation, scale, and localMatrix. Here I'm using a\n        // convenience lookAt function to orient the box to face the point passed from its current position\n        boxMesh.lookAt([sx, sy, 2.0])\n    }\n\n    // Satin calls draw when a new frame is ready to be encoded for drawing\n    override func draw(renderPassDescriptor: MTLRenderPassDescriptor, commandBuffer: MTLCommandBuffer) {\n        // To render a scene into a render pass, just call draw and pass in the render pass descriptor\n        // You can also specify a render target and render to a texture instead\n        renderer.draw(\n            renderPassDescriptor: renderPassDescriptor,\n            commandBuffer: commandBuffer,\n            scene: scene,\n            camera: camera\n        )\n    }\n\n    // Satin calls resize whenever the view is resized\n    override func resize(size: (width: Float, height: Float), scaleFactor: Float) {\n        // our camera's aspect ratio is set\n        camera.aspect = size.width / size.height\n\n        // our renderer's viewport \u0026 texture sizes are set\n        renderer.resize(size)\n        // if you need to render to a custom viewport, you can specify that after the resize call:\n        // renderer.viewport = MTLViewport(...)\n    }\n}\n\nstruct ContentView: View {\n    var body: some View {\n        SatinMetalView(renderer:  SimpleRenderer())\n    }\n}\n```\n\n# Credits :sweat_smile:\n\nSatin was created by [Reza Ali](https://www.syedrezaali.com) with contributions \u0026 feedback from [Haris Ali](https://syedharisali.com/) and [Taylor Holliday](https://taylorholliday.com/). \n\n# License :mortar_board:\n\nSatin is released under the MIT license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FHi-Rez%2FSatin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FHi-Rez%2FSatin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FHi-Rez%2FSatin/lists"}