How to get Three.js Shader Source Code at Runtime

Three.js builds its shaders with a tricky system of string concatenation based on data in your scene, like the current number of lights.

Under the hood, at least as of r100, Three.js builds shaders using a function called initMaterial, which happens only at render time, if the material is new or needsUpdate is set.

To get the Three.js running shader code without having to do a render, you can force shader "compilation" with a utility method in Three.js called #compile:

.compile ( scene : Scene, camera : Camera ) : null

Compiles all materials in the scene with the camera. This is useful to precompile shaders before the first rendering.

Then you can get the running shader code using the GL context Three.js creates. Here's the general code:

const material = new THREE.MeshPhongMaterial({ color: 0xff0000 });

const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);  
const scene = new THREE.Scene();  
const renderer = new THREE.WebGLRenderer();

// ... your scene setup code ...
// ... you MUST add the material to an object in the scene! ...

// Force shaders to be built
renderer.compile(scene, camera);

// Get the GL context:
const gl = renderer.getContext();

// Print the shader source!
console.log(  
  gl.getShaderSource(material.program.fragmentShader)
);

Happy hacking. If this blog post helped you consider following me on Twitter.

comments powered by Disqus