Baike.dev
All toolsOnline toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
T

THREE-CustomShaderMaterial

> 编程语言
Open source

Extend Three.js standard materials with your own shaders!

1.3K stars0 likes1 views
WebsiteGitHub

About

Extend Three.js standard materials with your own shaders!

Custom Shader Material

Extend Three.js standard materials with your own shaders!

These demos are real, you can click them! They contains full code, too. More demos here!

Custom Shader Material (CSM) lets you extend Three.js' material library with your own Vertex and Fragment shaders. It Supports both Vanilla and React!

Show Vanilla example

javascript
import CustomShaderMaterial from "three-custom-shader-material/vanilla";

function Box() {
  const geometry = new THREE.BoxGeometry();
  const material = new CustomShaderMaterial({
    baseMaterial: THREE.MeshPhysicalMaterial,
    vertexShader: /* glsl */ ` ... `, // Your vertex Shader
    fragmentShader: /* glsl */ ` ... `, // Your fragment Shader
    // Your Uniforms
    uniforms: {
      uTime: { value: 0 },
      ...
    },
    // Base material properties
    flatShading: true,
    color: 0xff00ff,
    ...
  });

  return new THREE.Mesh(geometry, material);
}

Show React example

javascript
import CustomShaderMaterial from 'three-custom-shader-material'

function Cube() {
  const materialRef = useRef()

  useFrame((state) => {
    if (materialRef.current) {
      materialRef.current.uniforms.uTime.value = state.clock.elapsedTime
    }
  })

  return (
    
      
      
    
  )
}

Show Vue (Tresjs) example

Moved to Cientos' Docs

Installation

bash
npm install three-custom-shader-material
yarn add three-custom-shader-material

Output Variables

CSM 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.

Variable Type Description Available In Notes
Vertex Shader
        | -       | -                                                          | -                                               | -                                                                                                                                                              |

| csm_Position | vec3 | Custom vertex position. | Vertex Shader | csm_Position will be projected furthur down the line. Thus, no projection is needed here. | | csm_PositionRaw | vec4 | Direct equivalent of gl_Position. | Vertex Shader | | | csm_Normal | vec3 | Custom vertex normals. | Vertex Shader | | csm_PointSize | float | Direct equivalent of gl_PointSize. | Vertex Shader | Only available in PointsMaterial | | Fragmet Shader | - | - | - | - | | csm_DiffuseColor | vec4 | Custom diffuse color. | Fragment Shader | Base material's shading will be applied to this color. | | 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 | | csm_Roughness | float | Custom roughness. | Fragment Shader | Only available in materials with an roughnessMap. | | csm_Metalness | float | Custom metalness. | Fragment Shader | Only available in materials with an metalnessMap. | | csm_AO | float | Custom AO. | Fragment Shader | Only available in materials with an aoMap. | | csm_Clearcoat | float | Custom clearcoat factor. | Fragment Shader | Only available in materials with a clearcoat. | | csm_ClearcoatRoughness | float | Custom clearcoat roughenss factor. | Fragment Shader | Only available in materials with a clearcoat. | | csm_ClearcoatNormal | vec3 | Custom clearcoat normal. | Fragment Shader | Only available in materials with a clearcoat. | | csm_Transmission | float | Custom transmission factor. | Fragment Shader | Only available in materials with a transmission. | | csm_Thickness | float | Custom transmission thickness. | Fragment Shader | Only available in materials with a transmission. | | csm_Iridescence | float | Custom iridescence factor. | Fragment Shader | Only available in materials with a iridescence. | | csm_Emissive | vec3 | Custom emissive color. | Fragment Shader | Only available in materials with a emissive. | | csm_FragNormal | float | Custom fragment normal. | Only available in materials with a normalMap. | |

Fragmet Shader (Special) | - | - | - | - | | csm_DepthAlpha | float | Custom alpha for MeshDepthMaterial. | Fragment Shader | Useful for controlling customDepthMaterial with same shader as the shader material. | | 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. |

Bump mapping

Bump mapping was removed in v6.4.0. This is becasue it cannot be implimented with a singular clean output variable. You can still impliment bump mapping by using csm_FragNormal output variable. See the Bump example for a full working example.

Typing

CSM 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.

typescript
// Vanilla
const material = new CustomShaderMaterial({
  baseMaterial: THREE.MeshPhysicalMaterial,
  //...Any props
});

// React

  baseMaterial={THREE.MeshPhysicalMaterial}
  //...Any props

Typing React Refs

You can type the ref of CustomShaderMaterial as follows:

typescript
// NOTE: import from /vanilla module
import CSM from "three-custom-shader-material/vanilla";
import { MeshPhysicalMaterial } from "three";

const ref = useRef>(null!);

Custom overrides

You can define any custom overrides you'd like using the patchMap prop. The prop is used as shown below.

javascript
const material = new CustomShaderMaterial({
   baseMaterial: THREE.MeshPhysicalMaterial,
   vertexShader: ` ... `,
   fragmentShader: ... `,
   uniforms: {...},
   patchMap={{
      "": {        // The keyword you will assign to in your custom shader
        "TO_REPLACE":       // The chunk you'd like to replace.
          "REPLACED_WITH"   // The chunk you'd like put in place of `TO_REPLACE`
      }
   }}
})

Note: If `` is not found in shader string, the patch map will not be applied. To ALWAYS apply a patch map, use the special keyword - * (star).

javascript
patchMap={{
  "*": { "TO_REPLACE": "REPLACED_WITH" }
}}

Extending already extended materials

CSM allows you to extend other CSM instances. Values set in the first shader will affect the next.

Note: Extending of other materials that use onBeforeCompile may or may not work depending on if the default #includes are mangled.

Show Vanilla example

javascript
import CustomShaderMaterial from "three-custom-shader-material/vanilla";

function Box() {
  const material1 = new CustomShaderMaterial({
    baseMaterial: THREE.MeshPhysicalMaterial,
    //...Any props
  });
  const material2 = new CustomShaderMaterial({
    baseMaterial: material1,
    //...Any props
  });
}

Show React example

javascript
import CustomShaderMaterial from "three-custom-shader-material";
import CustomShaderMaterialImpl from "three-custom-shader-material/vanilla";

function Cube() {
  const [materialRef, setMaterialRef] = useState();

  return (
    <>
      

      {materialRef && (
        
      )}
    
  );
}

Gotchas

  • csm_Position MUST be a non-projected vector. i.e., no need to multiply projectionMatrix or modelViewPosition with

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

TypeScript3dcustomshadersthreejs

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言