{"id":13402937,"url":"https://github.com/wagerfield/flat-surface-shader","last_synced_at":"2025-05-15T20:04:16.986Z","repository":{"id":7532089,"uuid":"8883822","full_name":"wagerfield/flat-surface-shader","owner":"wagerfield","description":"Flat Surface Shader for rendering illuminated triangles","archived":false,"fork":false,"pushed_at":"2016-01-07T06:05:22.000Z","size":1264,"stargazers_count":2467,"open_issues_count":16,"forks_count":275,"subscribers_count":110,"default_branch":"master","last_synced_at":"2025-05-08T03:13:03.519Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://wagerfield.github.io/flat-surface-shader/","language":"JavaScript","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/wagerfield.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-03-19T16:53:21.000Z","updated_at":"2025-04-29T14:11:07.000Z","dependencies_parsed_at":"2022-08-25T06:00:21.220Z","dependency_job_id":null,"html_url":"https://github.com/wagerfield/flat-surface-shader","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wagerfield%2Fflat-surface-shader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wagerfield%2Fflat-surface-shader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wagerfield%2Fflat-surface-shader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wagerfield%2Fflat-surface-shader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wagerfield","download_url":"https://codeload.github.com/wagerfield/flat-surface-shader/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254414498,"owners_count":22067272,"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":[],"created_at":"2024-07-30T19:01:23.125Z","updated_at":"2025-05-15T20:04:10.776Z","avatar_url":"https://github.com/wagerfield.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","📦 Legacy \u0026 Inactive Projects"],"sub_categories":[],"readme":"# Flat Surface Shader [FSS]\n\nSimple, lightweight **Flat Surface Shader** written in **JavaScript** for rendering lit **Triangles** to a number of contexts. Currently there is support for **WebGL**, **Canvas 2D** and **SVG**. Check out this [demo][demo] to see it in action.\n\n## Understanding Lighting\n\nSimply put, **FSS** uses the [Lambertian Reflectance][lambert] model to calculate the color of a **Triangle** based on an array of **Light** sources within a **Scene**.\n\n### Light\n\nA **Light** is composed of a 3D position **Vector** and 2 **Color** objects defining its **ambient** \u0026 **diffuse** emissions. These color channels interact with the **Material** of a **Mesh** to calculate the color of a **Triangle**.\n\n### Triangle\n\nA **Triangle** is constructed from **3 Vertices** which each define the **x, y** and **z** coordinates of a corner. Based on these **3 Vertices**, a forth **3D Vector** is automatically derived at the center of the **Triangle** – this is known as its [**Centroid**][centroid]. Alongside the **Centroid**, a fifth [unit][unit] **Vector** is automatically calculated which defines the surface [**Normal**][normal]. The **Normal** describes the direction that the **Triangle** is facing.\n\n### Geometry\n\n**Geometry** is simply a collection of triangles – nothing more.\n\n### Material\n\nA **Material** is composed of 2 **Color** objects which define the **ambient** \u0026 **diffuse** properties of a *surface*.\n\n### Mesh\n\nA **Mesh** is constructed from a **Geometry** object and a **Material** object. All the **Triangles** within the **Geometry** are rendered using the properties of the **Material**.\n\n### Scene\n\nA **Scene** sits at the very top of the stack. It simply manages arrays of **Mesh** \u0026 **Light** objects.\n\n### Renderer\n\nThe **Renderer** takes all the information in a **Scene** and renders it to a context. Currently **FSS** supports **WebGL**, **Canvas 2D** and **SVG**.\n\n### Calculation\n\nFor every **Triangle** in a **Scene** the following calculation is performed:\n\n1. A **Vector** between the Triangle's **Centroid** and the Light's **Position** is calculated and [normalised][normalise]. This can be considered as a single **Ray** travelling from the **Light** to the center of the **Triangle**.\n2. The angle beween this **Ray** and the **Normal** of the **Triangle** is then calculated using the [dot product][dotproduct]. This angle is simply a number ranging from -1 to 1. When the **Ray** and the **Normal** are coincident, this value is 0, and when they are perpendicular to one another, this value is 1. This value goes into the negative range when the **Light** is behind the **Triangle**.\n3. Firstly, the **diffuse** color of the **Light** is multiplied by the **diffuse** color of the **Material** associated with the **Triangle**. This color is then multiplied by the coincidence angle described above. For example, if the **diffuse** color of the **Light** is **#FFFFFF** `{ R:1, G:1, B:1 }` and the **diffuse** color of the **Material** is **#FF0000** `{ R:1, G:0, B:0 }`, the combined color would be #FF0000 `{ R:1*1=1, G:1*0=0, B:1*0=0 }`. If the coincidence angle was 0.5, the final color of the Triangle would be **#800000** `{ R:1*0.5=0.5, G:0*0.5=0, B:0*0.5=0 }`.\n4. In much the same way as above, the **ambient** color of the **Light** is multipled by the **ambient** color of the **Material**. Since **ambient** light is a uniform dissipation of scattered light, it is not modified any further.\n5. The final color of the **Triangle** is simply calculated by adding the **diffuse** \u0026 **ambient** colors together. Simples.\n\n## Example\n\n**NOTE:** All objects exist within the **FSS** namespace.\n\n```javascript\n// 1) Create a Renderer for the context you would like to render to.\n//    You can use either the WebGLRenderer, CanvasRenderer or SVGRenderer.\nvar renderer = new FSS.CanvasRenderer();\n\n// 2) Add the Renderer's element to the DOM:\nvar container = document.getElementById('container');\ncontainer.appendChild(renderer.element);\n\n// 3) Create a Scene:\nvar scene = new FSS.Scene();\n\n// 4) Create some Geometry \u0026 a Material, pass them to a Mesh constructor, and add the Mesh to the Scene:\nvar geometry = new FSS.Plane(200, 100, 4, 2);\nvar material = new FSS.Material('#444444', '#FFFFFF');\nvar mesh = new FSS.Mesh(geometry, material);\nscene.add(mesh);\n\n// 5) Create and add a Light to the Scene:\nvar light = new FSS.Light('#FF0000', '#0000FF');\nscene.add(light);\n\n// 6) Finally, render the Scene:\nrenderer.render(scene);\n```\n\n## Building\n\nInstall Dependancies:\n\n    npm install uglify-js@2.2.5\n\nBuild:\n\n    node build.js\n\n## Inspiration\n\nPlease also checkout the [case study on Behance][behance] created by my dear friend [Tobias van Schneider][vanschneider] – [@schneidertobias][schneidertobias].\n\n## Acknowledgments\n\nThe architecture of this project was heavily influenced by [three.js][three] and the implementation of the Vector calculations was taken from [glMatrix][glmatrix].\n\n## Author\n\nMatthew Wagerfield: [@mwagerfield][mwagerfield]\n\n## License\n\nLicensed under [MIT][mit]. Enjoy.\n\n[demo]: http://wagerfield.github.com/flat-surface-shader/\n[lambert]: http://en.wikipedia.org/wiki/Lambertian_reflectance\n[diffuse]: http://en.wikipedia.org/wiki/Diffuse_reflection\n[unit]: http://en.wikipedia.org/wiki/Unit_vector\n[centroid]: http://en.wikipedia.org/wiki/Centroid\n[normal]: http://en.wikipedia.org/wiki/Normal_(geometry)\n[normalise]: http://www.fundza.com/vectors/normalize/index.html\n[dotproduct]: http://www.mathsisfun.com/algebra/vectors-dot-product.html\n[behance]: http://www.behance.net/gallery/Flat-Surface-Shader/7826469\n[three]: https://github.com/mrdoob/three.js/\n[glmatrix]: https://github.com/toji/gl-matrix\n[mwagerfield]: http://twitter.com/mwagerfield\n[vanschneider]: http://www.vanschneider.com/\n[schneidertobias]: http://twitter.com/schneidertobias\n[mit]: http://www.opensource.org/licenses/mit-license.php\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwagerfield%2Fflat-surface-shader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwagerfield%2Fflat-surface-shader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwagerfield%2Fflat-surface-shader/lists"}