{"id":14981167,"url":"https://github.com/farazzshaikh/three-customshadermaterial","last_synced_at":"2025-05-14T01:02:13.597Z","repository":{"id":37315288,"uuid":"288175613","full_name":"FarazzShaikh/THREE-CustomShaderMaterial","owner":"FarazzShaikh","description":"🧩 Extend Three.js standard materials with your own shaders!","archived":false,"fork":false,"pushed_at":"2025-02-23T10:16:53.000Z","size":277285,"stargazers_count":1036,"open_issues_count":0,"forks_count":65,"subscribers_count":14,"default_branch":"main","last_synced_at":"2025-04-03T11:22:01.561Z","etag":null,"topics":["3d","custom","shaders","threejs","webgl"],"latest_commit_sha":null,"homepage":"https://farazzshaikh.github.io/THREE-CustomShaderMaterial/","language":"TypeScript","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/FarazzShaikh.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","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},"funding":{"github":["FarazzShaikh"]}},"created_at":"2020-08-17T12:34:02.000Z","updated_at":"2025-04-02T06:13:46.000Z","dependencies_parsed_at":"2024-01-03T04:06:27.406Z","dependency_job_id":"f025b004-1385-42cb-9623-b7b0df4775bf","html_url":"https://github.com/FarazzShaikh/THREE-CustomShaderMaterial","commit_stats":{"total_commits":322,"total_committers":7,"mean_commits":46.0,"dds":"0.13975155279503104","last_synced_commit":"205eccc6fd2f22787fe996e7ce2973e22243243c"},"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FarazzShaikh%2FTHREE-CustomShaderMaterial","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FarazzShaikh%2FTHREE-CustomShaderMaterial/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FarazzShaikh%2FTHREE-CustomShaderMaterial/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FarazzShaikh%2FTHREE-CustomShaderMaterial/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FarazzShaikh","download_url":"https://codeload.github.com/FarazzShaikh/THREE-CustomShaderMaterial/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248228263,"owners_count":21068652,"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","custom","shaders","threejs","webgl"],"created_at":"2024-09-24T14:03:03.624Z","updated_at":"2025-05-14T01:02:13.574Z","avatar_url":"https://github.com/FarazzShaikh.png","language":"TypeScript","funding_links":["https://github.com/sponsors/FarazzShaikh"],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003eCustom Shader Material\u003c/h1\u003e\r\n\u003ch3 align=\"center\"\u003eExtend Three.js standard materials with your own shaders!\u003c/h3\u003e\r\n\r\n\u003cbr\u003e\r\n\r\n\u003cp align=\"center\"\u003e\r\n  \u003ca href=\"https://farazzshaikh.github.io/THREE-CustomShaderMaterial/#/waves\" target=\"_blank\"\u003e\u003cimg width=\"32.3%\" src=\"https://raw.githubusercontent.com/FarazzShaikh/THREE-CustomShaderMaterial/main/assets/waves-demo.png\" alt=\"Waves\" /\u003e\u003c/a\u003e\r\n   \u003ca href=\"https://farazzshaikh.github.io/THREE-CustomShaderMaterial/#/points\" target=\"_blank\"\u003e\u003cimg width=\"32.3%\" src=\"https://raw.githubusercontent.com/FarazzShaikh/THREE-CustomShaderMaterial/main/assets/points-demo.png\" alt=\"Points\" /\u003e\u003c/a\u003e\r\n  \u003ca href=\"https://farazzshaikh.github.io/THREE-CustomShaderMaterial/#/caustics\" target=\"_blank\"\u003e\u003cimg width=\"32.3%\" src=\"https://raw.githubusercontent.com/FarazzShaikh/THREE-CustomShaderMaterial/main/assets/caustics-demo.png\" alt=\"Caustics\" /\u003e\u003c/a\u003e\r\n\u003c/p\u003e\r\n\u003c/p\u003e\r\n\u003cp align=\"middle\"\u003e\r\n  \u003ci\u003eThese demos are real, you can click them! They contains full code, too.\r\n  \u003ca href=\"https://github.com/FarazzShaikh/THREE-CustomShaderMaterial/tree/main/examples/src/Examples\"\u003eMore demos here! 📦\u003c/a\u003e\r\n  \u003c/i\u003e\r\n\u003c/p\u003e\r\n\u003cbr /\u003e\r\n\u003cp align=\"center\"\u003e\r\n \r\n  \u003ca href=\"https://www.npmjs.com/package/three-custom-shader-material\" target=\"_blank\"\u003e\r\n    \u003cimg src=\"https://img.shields.io/npm/v/three-custom-shader-material.svg?style=for-the-badge\" /\u003e\r\n  \u003c/a\u003e\r\n  \u003ca href=\"https://www.npmjs.com/package/three-custom-shader-material\" target=\"_blank\"\u003e\r\n    \u003cimg src=\"https://img.shields.io/npm/dt/three-custom-shader-material?style=for-the-badge\u0026colorB=red\" /\u003e\r\n  \u003c/a\u003e\r\n  \u003cbr /\u003e\r\n  \u003ca href=\"https://github.com/sponsors/FarazzShaikh\" target=\"_blank\"\u003e\r\n    \u003cimg src=\"https://img.shields.io/badge/sponsor-30363D?style=for-the-badge\u0026logo=GitHub-Sponsors\" /\u003e\r\n  \u003c/a\u003e\r\n  \u003ca href=\"https://twitter.com/CantBeFaraz\" target=\"_blank\"\u003e\r\n    \u003cimg src=\"https://img.shields.io/twitter/follow/CantBeFaraz?style=for-the-badge\u0026logo=x\" alt=\"Chat on Twitter\"\u003e\r\n  \u003c/a\u003e\r\n\u003c/p\u003e\r\n\r\nCustom Shader Material (CSM) lets you extend Three.js' material library with your own Vertex and Fragment shaders. **_It Supports both Vanilla and React!_**\r\n\r\n\u003cdetails\u003e\r\n  \u003csummary\u003eShow Vanilla example\u003c/summary\u003e\r\n\r\n```js\r\nimport CustomShaderMaterial from \"three-custom-shader-material/vanilla\";\r\n\r\nfunction Box() {\r\n  const geometry = new THREE.BoxGeometry();\r\n  const material = new CustomShaderMaterial({\r\n    baseMaterial: THREE.MeshPhysicalMaterial,\r\n    vertexShader: /* glsl */ ` ... `, // Your vertex Shader\r\n    fragmentShader: /* glsl */ ` ... `, // Your fragment Shader\r\n    // Your Uniforms\r\n    uniforms: {\r\n      uTime: { value: 0 },\r\n      ...\r\n    },\r\n    // Base material properties\r\n    flatShading: true,\r\n    color: 0xff00ff,\r\n    ...\r\n  });\r\n\r\n  return new THREE.Mesh(geometry, material);\r\n}\r\n```\r\n\r\n\u003c/details\u003e\r\n\r\n\u003cdetails \u003e\r\n  \u003csummary\u003eShow React example\u003c/summary\u003e\r\n\r\n```jsx\r\nimport CustomShaderMaterial from 'three-custom-shader-material'\r\n\r\nfunction Cube() {\r\n  const materialRef = useRef()\r\n\r\n  useFrame((state) =\u003e {\r\n    if (materialRef.current) {\r\n      materialRef.current.uniforms.uTime.value = state.clock.elapsedTime\r\n    }\r\n  })\r\n\r\n  return (\r\n    \u003cmesh\u003e\r\n      \u003cboxGeometry /\u003e\r\n      \u003cCustomShaderMaterial\r\n        ref={materialRef}\r\n        baseMaterial={THREE.MeshPhysicalMaterial}\r\n        vertexShader={/* glsl */ ` ... `} // Your vertex Shader\r\n        fragmentShader={/* glsl */ ` ... `} // Your fragment Shader\r\n        // Your Uniforms\r\n        uniforms={{\r\n          uTime: { value: 0 },\r\n          ...\r\n        }}\r\n        // Base material properties\r\n        flatShading\r\n        color={0xff00ff}\r\n        ...\r\n      /\u003e\r\n    \u003c/mesh\u003e\r\n  )\r\n}\r\n```\r\n\r\n\u003c/details\u003e\r\n\u003cdetails\u003e\r\n  \u003csummary\u003eShow Vue (Tresjs) example\u003c/summary\u003e\r\n  \r\n  \u003e Moved to [Cientos' Docs](https://cientos.tresjs.org/guide/materials/custom-shader-material.html#trescustomshadermaterial)\r\n\r\n\u003c/details\u003e\r\n\r\n## Installation\r\n\r\n```bash\r\nnpm install three-custom-shader-material\r\nyarn add three-custom-shader-material\r\n```\r\n\r\n## Output Variables\r\n\r\nCSM provides the following output variables, all of them are optional but you MUST use these variables like you would use standard GLSL output variables to see results.\r\n\r\n| Variable                          | Type    | Description                                                | Available In                                    | Notes                                                                                                                                                          |\r\n| --------------------------------- | ------- | ---------------------------------------------------------- | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |\r\n| \u003ch3\u003eVertex Shader\u003c/h3\u003e            | -       | -                                                          | -                                               | -                                                                                                                                                              |\r\n| csm_Position                      | `vec3`  | Custom vertex position.                                    | Vertex Shader                                   | csm_Position will be projected furthur down the line. Thus, no projection is needed here.                                                                      |\r\n| csm_PositionRaw                   | `vec4`  | Direct equivalent of `gl_Position`.                        | Vertex Shader                                   |                                                                                                                                                                |\r\n| csm_Normal                        | `vec3`  | Custom vertex normals.                                     | Vertex Shader                                   |\r\n| csm_PointSize                     | `float` | Direct equivalent of `gl_PointSize`.                       | Vertex Shader                                   | Only available in `PointsMaterial`                                                                                                                             |\r\n| \u003ch3\u003eFragmet Shader\u003c/h3\u003e           | -       | -                                                          | -                                               | -                                                                                                                                                              |\r\n| csm_DiffuseColor                  | `vec4`  | Custom diffuse color.                                      | Fragment Shader                                 | Base material's shading will be applied to this color.                                                                                                         |\r\n| csm_FragColor                     | `vec4`  | Direct equivalent of `gl_FragColor`.                       | Fragment Shader                                 | csm_FragColor will override any shading applied by a base material. To preserve shading and other effects like roughness and metalness, use `csm_DiffuseColor` |\r\n| csm_Roughness                     | `float` | Custom roughness.                                          | Fragment Shader                                 | Only available in materials with an `roughnessMap`.                                                                                                            |\r\n| csm_Metalness                     | `float` | Custom metalness.                                          | Fragment Shader                                 | Only available in materials with an `metalnessMap`.                                                                                                            |\r\n| csm_AO                            | `float` | Custom AO.                                                 | Fragment Shader                                 | Only available in materials with an `aoMap`.                                                                                                                   |\r\n| csm_Bump                          | `vec3`  | Custom bump as perturbation to fragment normals.           | Fragment Shader                                 | Only available in materials with a `bumpMap`.                                                                                                                  |\r\n| csm_Clearcoat                     | `float` | Custom clearcoat factor.                                   | Fragment Shader                                 | Only available in materials with a `clearcoat`.                                                                                                                |\r\n| csm_ClearcoatRoughness            | `float` | Custom clearcoat roughenss factor.                         | Fragment Shader                                 | Only available in materials with a `clearcoat`.                                                                                                                |\r\n| csm_ClearcoatNormal               | `vec3`  | Custom clearcoat normal.                                   | Fragment Shader                                 | Only available in materials with a `clearcoat`.                                                                                                                |\r\n| csm_Transmission                  | `float` | Custom transmission factor.                                | Fragment Shader                                 | Only available in materials with a `transmission`.                                                                                                             |\r\n| csm_Thickness                     | `float` | Custom transmission thickness.                             | Fragment Shader                                 | Only available in materials with a `transmission`.                                                                                                             |\r\n| csm_Iridescence                   | `float` | Custom iridescence factor.                                 | Fragment Shader                                 | Only available in materials with a `iridescence`.                                                                                                              |\r\n| csm_Emissive                      | `vec3`  | Custom emissive color.                                     | Fragment Shader                                 | Only available in materials with a `emissive`.                                                                                                                 |\r\n| csm_FragNormal                    | `float` | Custom fragment normal.                                    | Only available in materials with a `normalMap`. |\r\n| \u003ch3\u003eFragmet Shader (Special)\u003c/h3\u003e | -       | -                                                          | -                                               | -                                                                                                                                                              |\r\n| csm_DepthAlpha                    | `float` | Custom alpha for `MeshDepthMaterial`.                      | Fragment Shader                                 | Useful for controlling `customDepthMaterial` with same shader as the shader material.                                                                          |\r\n| csm_UnlitFac                      | `float` | Custom mix between `csm_DiffuseColor` and `csm_FragColor`. | Fragment Shader                                 | Can be used to mix lit and unlit materials. Set to `1.0` by default if `csm_FragColor` is found in shader string.                                              |\r\n\r\n## Typing\r\n\r\nCSM infers prop types based on the `baseMaterial` prop. However, if this does not work for what ever reason, you can pass your base material type as a generic to `CustomShaderMaterial\u003cT\u003e`.\r\n\r\n```ts\r\n// Vanilla\r\nconst material = new CustomShaderMaterial\u003ctypeof THREE.MeshPhysicalMaterial\u003e({\r\n  baseMaterial: THREE.MeshPhysicalMaterial,\r\n  //...Any props\r\n});\r\n\r\n// React\r\n\u003cCustomShaderMaterial\u003ctypeof THREE.MeshPhysicalMaterial\u003e\r\n  baseMaterial={THREE.MeshPhysicalMaterial}\r\n  //...Any props\r\n```\r\n\r\n## Custom overrides\r\n\r\nYou can define any custom overrides you'd like using the `patchMap` prop. The prop is used as shown below.\r\n\r\n```js\r\nconst material = new CustomShaderMaterial({\r\n   baseMaterial: THREE.MeshPhysicalMaterial,\r\n   vertexShader: ` ... `,\r\n   fragmentShader: ... `,\r\n   uniforms: {...},\r\n   patchMap={{\r\n      \"\u003cKEYWORD\u003e\": {        // The keyword you will assign to in your custom shader\r\n        \"TO_REPLACE\":       // The chunk you'd like to replace.\r\n          \"REPLACED_WITH\"   // The chunk you'd like put in place of `TO_REPLACE`\r\n      }\r\n   }}\r\n})\r\n```\r\n\r\n\u003e Note: If `\u003cKEYWORD\u003e` is not found in shader string, the patch map will not be applied. To ALWAYS apply a patch map, use the special keyword - `*` (star).\r\n\u003e\r\n\u003e ```js\r\n\u003e patchMap={{\r\n\u003e   \"*\": { \"TO_REPLACE\": \"REPLACED_WITH\" }\r\n\u003e }}\r\n\u003e ```\r\n\r\n## Extending already extended materials\r\n\r\nCSM allows you to extend other CSM instances. Values set in the first shader will affect the next.\r\n\r\n\u003e Note: Extending of other materials that use `onBeforeCompile` may or may not work depending on if the default `#includes` are mangled.\r\n\r\n\u003cdetails\u003e\r\n  \u003csummary\u003eShow Vanilla example\u003c/summary\u003e\r\n\r\n```js\r\nimport CustomShaderMaterial from \"three-custom-shader-material/vanilla\";\r\n\r\nfunction Box() {\r\n  const material1 = new CustomShaderMaterial({\r\n    baseMaterial: THREE.MeshPhysicalMaterial,\r\n    //...Any props\r\n  });\r\n  const material2 = new CustomShaderMaterial({\r\n    baseMaterial: material1,\r\n    //...Any props\r\n  });\r\n}\r\n```\r\n\r\n\u003c/details\u003e\r\n\r\n\u003cdetails \u003e\r\n  \u003csummary\u003eShow React example\u003c/summary\u003e\r\n\r\n```jsx\r\nimport CustomShaderMaterial from \"three-custom-shader-material\";\r\nimport CustomShaderMaterialImpl from \"three-custom-shader-material/vanilla\";\r\n\r\nfunction Cube() {\r\n  const [materialRef, setMaterialRef] = useState();\r\n\r\n  return (\r\n    \u003c\u003e\r\n      \u003cCustomShaderMaterial\r\n        ref={setMaterialRef}\r\n        baseMaterial={THREE.MeshPhysicalMaterial}\r\n        //...Any props\r\n      /\u003e\r\n\r\n      {materialRef \u0026\u0026 (\r\n        \u003cCustomShaderMaterial\r\n          baseMaterial={materialRef}\r\n          //...Any props\r\n        /\u003e\r\n      )}\r\n    \u003c/\u003e\r\n  );\r\n}\r\n```\r\n\r\n\u003c/details\u003e\r\n\r\n### Gotchas\r\n\r\n- `csm_Position` **MUST** be a non-projected vector. i.e., no need to multiply `projectionMatrix` or `modelViewPosition` with it. If you require projection, use `csm_PositionRaw`.\r\n- Instancing must be handled manually when using `csm_PositionRaw` by multiplying in `instanceMatrix` into your projection math.\r\n- When extending already extended material, variables, uniforms, attributes, varyings and functions are **NOT** scoped to the material they are defined in. Thus, you **WILL** get redefinition errors if you do not manually scope these identifiers.\r\n- Extending of other materials that use `onBeforeCompile` may or may not work depending on if the default `#includes` are mangled.\r\n- When using an instance of CSM as the baseMaterial, or chining multiple CSM instances, or when extending any material that uses `onBeforeCompile` the injection order is as follows:\r\n\r\n  ```glsl\r\n  void main() {\r\n    // shader A\r\n    // shader B\r\n    // shader C\r\n    // shader D\r\n\r\n    // original shader\r\n  }\r\n  ```\r\n\r\n  Where A was the first in the chain.\r\n\r\n- Cache key calculation takes into account base material's cache key. Useful for propagating changes across multiple chained CSM instances.\r\n- If you find yourself lost in a patchMap, it's often simpler to just make a `ShaderMaterial` with the necessary `#includes`.\r\n\r\n## Performance\r\n\r\nWith v6, CSM's initialization cost is now negligible 🥳 Still, a couple important notes about performance:\r\n\r\n- Changing these props will rebuild the material\r\n  - `baseMaterial`\r\n  - `fragmentShader`\r\n  - `vertexShader`\r\n  - `uniforms`\r\n  - `cacheKey`\r\n- CSM uses ThreeJS's default shader program caching system. Materials with the same cache key, will use the the same shader program.\r\n- `\u003cmeshPhysicalMaterial /\u003e` and `\u003cCSM baseMaterial={meshPhysicalMaterial}\u003e` are the same, and will use the same cached shader program. The default cache key is such:\r\n\r\n  ```js\r\n  (cacheKey?.() || hash((vertexShader || \"\") + (fragmentShader || \"\"))) +\r\n    baseMaterialCacheKey?.();\r\n  ```\r\n\r\n  You can provide your own cache key function via the `cacheKey` prop.\r\n\r\n\u003e Note: CSM will only rebuild if the **reference** to the above props change, for example, in React, doing `uniforms={{...}}` means that the uniforms object is unstable, i.e. it is re-created, with a **new** reference every render. Instead, condsider memoizing the uniforms prop `const uniforms = useMemo(() -\u003e ({...}));`. The uniforms object will then have the same refrence on every render.\r\n\r\n\u003e If the uniforms are memoized, changing their value by doing `uniforms.foo.value = ...` will not cause CSM to rebuild, as the refrence of `uniforms` does not change.\r\n\r\n## License\r\n\r\n```\r\nMIT License\r\n\r\nCopyright (c) 2024 Faraz Shaikh\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n```\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffarazzshaikh%2Fthree-customshadermaterial","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffarazzshaikh%2Fthree-customshadermaterial","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffarazzshaikh%2Fthree-customshadermaterial/lists"}