Custom shaders and GLSL syntax highlighting

I wanted to share the process by which I define custom shaders in my code. This process allows re-use of existing three.js shader chunks to be included in my shader, but in a way that also allows syntax highlighting within VSCode.

There is a VSCode extension called glsl-literal that provides syntax highlighting for string template literals that are tagged with glsl:

Screen Shot 2022-06-17 at 3.05.23 PM

The glsl function that I wrote doesn’t actually do very much:

export default (literals: TemplateStringsArray, ...exprs: string[]): string => {
  let result: string[] = [];
  literals.forEach((str, i) => {
    result.push(str);
    result.push(exprs[i] || '');
  });
  return result.join('');
};

This is essentially the same as what would happen if the template literal was untagged, i.e. just a back-quoted string. However, the VSCode extension sees the letters glsl and knows that the string is shader code, not JavaScript, and so applies the syntax highlighting appropriately.

Since it’s a template literal, we can also inject blocks of other shader code into our shader using the ${expr} syntax. Here we are importing chunks of shader code from three.js:

import { ShaderChunk } from 'three';

The template string can then be assigned directly to the material’s fragmentShader or vertexShader property. Since the string is inlined within JavaScript, there’s no need to dynamically load it or search for a <script> tag.

2 Likes