Skip to content

Instantly share code, notes, and snippets.

@rotoglup
Last active March 13, 2020 08:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rotoglup/d4656564300d4c8b2272fd30cd409d08 to your computer and use it in GitHub Desktop.
Save rotoglup/d4656564300d4c8b2272fd30cd409d08 to your computer and use it in GitHub Desktop.

Based on my looking at ThreeJS r115dev source code, while trying to figure out how to customize the lighting by writing my own shader.

Materials

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

Shaders overview

Each of the possible Materials is renderered by a GLSL shader.

Those shaders are defined in ShaderLib module.

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 src/renderers/shaders/ShaderChunk.js
  • stores shaderChunk_key/glsl_code_string pairs

The 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 ShaderChunk['aomap_fragment'].

Shaders customization

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 examples/webgl_materials_nodes.html

I could not find a way that suited me : a simple way to change the behaviour of lights.

The content of ShaderChunk and 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 ShaderChunk

This feels very fragile, but I'll go this route for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment