Based on my looking at ThreeJS
r115dev source code, while trying to figure out how to
customize the lighting by writing my own shader.
ThreeJS has the following
Material classes :
MeshBasicMaterial, not affected by lights
MeshLambertMaterial: lighting is computed at each vertex, for diffuse lighting, and interpolated in gouraud like fashion
MeshPhongMaterial: lighting is computed at each pixel, for diffuse and specular lighting
MeshToonMaterial: like Phong but with a 2-tone toon effect
MeshStandardMaterial: lighting by a 'Disney PBR' setup
MeshPhysicalMaterial: extends Standard with a clearcoat and additional reflectivity & transparency controls
The following classes allow to provide custom GLSL code :
ShaderMaterial, where user provides shader code and uniforms, that can access the values exposed by three (fog, lights, ...)
RawShaderMaterial, where user is responsible of 100% of the shader uniforms & code
Each of the possible Materials is renderered by a GLSL shader.
Those shaders are defined in
Each shader is defined by its
uniform values and
GLSL source code (for vertex and fragment shaders).
The GLSL source code is mainly composed of
#include directives, that allow to reuse similar 'code chunks' between materials.
The 'code chunks' are stored in a
ShaderChunk object :
- located in
shaderChunk_key are used to 'resolve the includes' used in the materials shaders.
For example, in material shader, the statement
#include <aomap_fragment> will be replaced by the string contained in
It seems that some work is progress to introduce a node based GLSL code generation tool - which lives in examples and is not (yet?) documented. See
I could not find a way that suited me : a simple way to change the behaviour of lights.
The content of
ShaderLib is not documented.
The shader code for materials is quite complex and hard to follow, assembled from dozens of small chunks, dispatched in as many files.
What I saw here and there, people are :
- using regexps to patch shader texts
- replace or add some content in
This feels very fragile, but I'll go this route for now.