What I did to start making ShaderMaterial
s based on existing materials is something like follows. In the following example, in order to extend the MeshLambertMaterial
, for example, I used the relevant pieces (shader chunks) that it is made of, essentially re-making the lambert shader, plus added my own parts:
new ShaderMaterial({
vertexShader: `
...
${THREE.ShaderChunk.common}
... etc, all the same parts that MeshLambertMaterial has ...
${THREE.ShaderChunk. envmap_pars_vertex}
...
main() {
${THREE.ShaderChunk.lights_lambert_vertex}
... etc ...
${THREE.ShaderChunk.fog_vertex}
gl_Position = ....;
}
`
fragmentShader: `... similar here as with vertex shader, add the needed parts plus yours ...`
uniforms: THREE.UniformsUtils.merge([ THREE.ShaderLib.lambert.uniforms, {
/* ... custom uniforms here additional to the lambert ones ... */
// see https://github.com/mrdoob/three.js/blob/dev/src/renderers/shaders/UniformsLib.js
// and https://github.com/mrdoob/three.js/blob/dev/src/renderers/shaders/ShaderLib.js
}])
})
And then to get an idea of what ${ShaderChunk.<name>}
chunks to put in your shaders, take a look at for example the shaders for MeshLambertMaterial: vertex, fragment.
In your shader string, instead of putting #include <common>
you’d put ${ShaderChunk.common}
, etc.
Basically, you can recreate any of the existing shaders this way, then you can tweak them by adding your own code to them. Once you get enough experience with that, you can start from scratch using only the chunks you need.
It will be lots of trial and error: you’ll get errors in the console, and will have to piece together what’s missing. None of the answers I could find online were definitive, and I could only complete my goal of making custom shaders by just trying it out like above, and seeing what errors WebGL gave, then figuring out what was missing, etc.
Node-based shaders are a new way to make shaders, and much more robust, allowing programmatic combination of multiple shaders. An intro to those by @donmccurdy is here: Three.js NodeMaterial introduction (donmccurdy.com)