Macro-Based Shader Lighting?

I don’t know if there’s a more standard name for this, but this is a feature that would be very useful for what I’m trying to do, and I wanted to get some feedback to see if other people would find a need for this or if this sounds too niche.

The Problem

Say you’re trying to make a slightly modified lighting effect, like this toon shader by @dave

To do this, you have to write your own shader. But that means you have to give up or rewrite a lot of functionality that PlayCanvas’ built in shaders handle for you, such as setting up all the light sources and passing them to the shader.

In the example project above,the light source is grabbed by name in toon.js and passed to the shader. Adding more lights, or different kinds of lights, would involve rewriting a lot more functionality from the PlayCanvas standard material.

The Solution

What if there was an option to pass a shader chunk/snippet to be included at the end of any material’s final shader? That way you could keep all the functionality already there, but only tweak/override what you need.


A robust implementation might be similar to Unity’s surface shader idea, where you define custom lighting functions and it generates the full vertex/frag shader with your function embedded in.


After digging around a bit, this looks like pretty much exactly what I need:

Their basic example is:

#pragma glslify: noise = require(glsl-noise/simplex/2d)

void main() {
  float brightness = noise(gl_FragCoord.xy);

  gl_FragColor = vec4(vec3(brightness), 1.);

Now I just have to look into how easy it would be to integrate with PlayCanvas.


It looks like what I was trying to reach for here is something that does exist today! You can pass a chunks object to a StandardMaterial to override any default shader chunks:

This project has an example using it: Warp a Sprite with GLSL | Learn PlayCanvas

This is exactly what I was looking for and it means you could do such a toon lighting as I describe in the top post here, without having to write a complete custom shader, and it’ll automatically work for any number of lights/with any other supported light effects like fog etc.