Cell shading not working

I wanted to write a high contrast shader, but for no apparent reason I keep getting faulty results. I then tried copying the following tutorial: link. Which, based on the way it is phrased, was originally written by the author of Babylonjs? Regardless of that being so it fails to render properly. The issue appears to be that the dot product always returns zero in the fragment shader.

The issue is not browser support. Babylon is using webgl 2. Code, copied almost 1:1 from the above tutorial for testing purposes, below:

function startGame() {
    if (BABYLON.Engine.isSupported()) {
        var canvas = document.getElementById("renderCanvas");
        var engine = new BABYLON.Engine(canvas, false);
        var scene = new BABYLON.Scene(engine);
        var camera = new BABYLON.ArcRotateCamera("Camera", 0, Math.PI / 2, 10, BABYLON.Vector3.Zero(), scene);
        camera.attachControl(canvas);
 
        // Creating sphere
        var sphere = BABYLON.Mesh.CreateSphere("Sphere", 16, 5, scene);
        var amigaMaterial = new BABYLON.ShaderMaterial("amiga", scene, "../HighContrast",
        {
            attributes: ["position", "uv"],
            uniforms: ["worldViewProjection"]
        });
        amigaMaterial.setTexture("textureSampler", new BABYLON.Texture("../hdkitty.png", scene));
        sphere.material = amigaMaterial;
        engine.runRenderLoop(function () {
            sphere.rotation.y += 0.05;
            scene.render();
        });
    }
};

document.addEventListener("DOMContentLoaded", startGame, false);

Fragment shader:

precision highp float;

// Lights
varying vec3 vPositionW;
varying vec3 vNormalW;
varying vec2 vUV;
 
// Refs
uniform sampler2D textureSampler;
 
void main(void) {
    float ToonThresholds[4];
    ToonThresholds[0] = 0.95;
    ToonThresholds[1] = 0.5;
    ToonThresholds[2] = 0.2;
    ToonThresholds[3] = 0.03;
 
    float ToonBrightnessLevels[5];
    ToonBrightnessLevels[0] = 1.0;
    ToonBrightnessLevels[1] = 0.8;
    ToonBrightnessLevels[2] = 0.6;
    ToonBrightnessLevels[3] = 0.35;
    ToonBrightnessLevels[4] = .1;
 
    vec3 vLightPosition = vec3(0, 30, 20);
    // Light
    vec3 lightVectorW = normalize(vLightPosition - vPositionW);

    // diffuse
    float ndl = max(0., dot(vNormalW, lightVectorW));
    vec3 color = texture2D(textureSampler, vUV).rgb;
 
    if (ndl > ToonThresholds[0])
    {
        color *= ToonBrightnessLevels[0];
    }
    else if (ndl > ToonThresholds[1])
    {
        color *= ToonBrightnessLevels[1];
    }
    else if (ndl > ToonThresholds[2])
    {
        color *= ToonBrightnessLevels[2];
    }
    else if (ndl > ToonThresholds[3])
    {
        color *= ToonBrightnessLevels[3];
    }
    else
    {
        color *= ToonBrightnessLevels[4];
    }
    if(ndl == .0){
        color *= 0.;
    }
 
    gl_FragColor = vec4(color, 1.);
 
}

In the above code it always takes the branch for the condition ndl == 0. I tried moving the light source as well the object, but to no avail.

Vertex shader:

precision highp float;
 
// Attributes
attribute vec3 position;
attribute vec3 normal;
attribute vec2 uv;
 
// Uniforms
uniform mat4 world;
uniform mat4 worldViewProjection;
 
// Varying
varying vec3 vPositionW;
varying vec3 vNormalW;
varying vec2 vUV;
 
void main(void) {
    vec4 outPosition = worldViewProjection * vec4(position, 1.0);
    gl_Position = outPosition;
 
    vPositionW = vec3(world * vec4(position, 1.0));
    vNormalW = normalize(vec3(world * vec4(normal, 0.0)));
    vUV = uv;
}

Any help is appreciated.

Bump. Added info: it does work in CYOS, but fails to render properly when using Live server.

Fixed it. It was a dumb error on my behalf.

1 Like