[bug] failed to compile vertex shader.in real time lighting

when typed n, it says “failed to compile vertex shader

// night-mode.mjs

import { Color, Entity, Script } from 'playcanvas';

const gsplatVS = /* glsl */`
#include "gsplatCommonVS"

varying mediump vec2 gaussianUV;
varying mediump vec4 gaussianColor;

#ifndef DITHER_NONE
    varying float id;
#endif

mediump vec4 discardVec = vec4(0.0, 0.0, 2.0, 1.0);

#ifdef PREPASS_PASS
    varying float vLinearDepth;
#endif

uniform vec3 spherePositions[10];
uniform vec3 sphereColors[10];
uniform float nightFade;
uniform vec3 nightAmbient;

// linear/gamma
vec3 l2g(vec3 c) { return pow(c, vec3(1.0 / 2.2)); }
vec3 g2l(vec3 c) { return pow(c, vec3(2.2)); }

vec3 applyNightMode(vec3 clrIn, vec3 modelPos) {
    if (nightFade == 0.0) {
        return clrIn;
    }

    vec4 worldPos = matrix_model * vec4(modelPos, 1.0);
    worldPos /= worldPos.w;

    vec3 sum = vec3(0.0);

    for (int i = 0; i < 10; ++i) {
        vec3 pos = spherePositions[i];
        vec3 clr = sphereColors[i];
        sum += g2l(clr) * 1.1 / pow(length(pos - worldPos.xyz), 2.0);
    }

    // blend in linear space
    return l2g(g2l(clrIn) * mix(vec3(1.0), g2l(nightAmbient) + sum, nightFade));
}

void main(void) {
    // SENTINEL_2026_05_17_v3

    // read gaussian details
    SplatSource source;
    if (!initSource(source)) {
        gl_Position = discardVec;
        return;
    }

    vec3 modelCenter = getCenter();

    SplatCenter center;
    if (!initCenter(modelCenter, center)) {
        gl_Position = discardVec;
        return;
    }

    // project center to screen space
    SplatCorner corner;
    if (!initCorner(source, center, corner)) {
        gl_Position = discardVec;
        return;
    }

    // read color
    vec4 clr = getColor();

    #if GSPLAT_AA
        // apply AA compensation
        clr.a *= corner.aaFactor;
    #endif

    // evaluate spherical harmonics
    #if SH_BANDS > 0
        // calculate the model-space view direction
        vec3 dir = normalize(center.view * mat3(center.modelView));

        // read sh coefficients
        vec3 sh[SH_COEFFS];
        float scale;
        readSHData(sh, scale);

        // evaluate
        clr.xyz += evalSH(sh, dir) * scale;
    #endif

    // apply night mode
    clr.xyz = applyNightMode(clr.xyz, modelCenter);

    clipCorner(corner, clr.w);

    // write output
    gl_Position = center.proj + vec4(corner.offset, 0.0);
    gaussianUV = corner.uv;
    gaussianColor = vec4(prepareOutputFromGamma(max(clr.xyz, 0.0), -center.view.z), clr.w);

    #ifndef DITHER_NONE
        id = float(source.id);
    #endif

    #ifdef PREPASS_PASS
        vLinearDepth = -center.view.z;
    #endif
}
`;

const lerp = (a, b, t) => a * (1 - t) + b * t;
const damp = (damping, dt) => 1 - Math.pow(damping, dt * 1000);

export class NightMode extends Script {
    static scriptName = "nightMode";

    /**
     * @attribute
     * @type Entity
     */
    light;

    /**
     * @attribute
     * @type Entity
     */
    camera;

    /**
     * @attribute
     * @type Entity
     */
    splat;

    /**
     * @attribute
     * @type Color
     */
    nightAmbient = new Color(0);

    /**
     * @attribute
     */
    emissiveIntensity = 10;

    /**
     * @attribute
     */
    lightingIntensity = 1.23;

    /**
     * @attribute
     */
    emissiveBloom = 0.05;

    initialize() {
        this.nightMode = false;
        this.nightFade = 0;

        this.app.on('toggle:night', () => {
            this.nightMode = !this.nightMode;
            const material = this.splat.gsplat.material;
            material.shaderChunks.glsl.set('gsplatVS', gsplatVS);
            material.shaderChunksVersion = '2.18';
            material.update();
        });
    }

    update(dt) {
        const material = this.splat?.gsplat?.material;
        if (!material) {
            return false;
        }

        // update night fade
        const target = this.nightMode ? 1 : 0;
        if (Math.abs(this.nightFade - target) < 1e-06) {
            this.nightFade = target;
        } else {
            this.nightFade = lerp(this.nightFade, target, damp(0.98, dt));
        }

        // get sphere positions
        const spheres = this.app.root.findByTag('sphere');

        this.light.light.intensity = 1 - this.nightFade;
        this.camera.script.cameraEffects.bloom.intensity = lerp(0, this.emissiveBloom, this.nightFade);

        const eintensity = this.emissiveIntensity;
        const lintensity = this.lightingIntensity;

        const positions = [];
        const colors = [];
        for (let i = 0; i < 10; ++i) {
            const sphere = spheres[i];

            if (!sphere) {
                positions.push(0, 0, 0);
                colors.push(0, 0, 0);
            } else {
                const pos = sphere.getPosition();
                const { material } = sphere.render.meshInstances[0];
                const { diffuse } = material;

                positions.push(pos.x, pos.y, pos.z);
                colors.push(diffuse.r * lintensity, diffuse.g * lintensity, diffuse.b * lintensity);

                material.emissive.set(diffuse.r, diffuse.g, diffuse.b);
                material.emissiveIntensity = this.nightFade * eintensity;
                material.gloss = lerp(0.7, 0.3, this.nightFade);
                material.update();
            }
        }

        material.setParameter('spherePositions[0]', positions);
        material.setParameter('sphereColors[0]', colors);
        material.setParameter('nightFade', this.nightFade);
        material.setParameter("nightAmbient", [this.nightAmbient.r, this.nightAmbient.g, this.nightAmbient.b]);

        this.app.scene.skyboxIntensity = lerp(1.0, 0.2, this.nightFade);

        this.app.fire('nightFade', this.nightFade);
    }
};

OK. I fixed it. I don’t know whether this could be permanent, nor guaranteed to work for later. But it works for Engine 2.18.1.

Just replace the current night-mode.mjs with the above code.

@slimbuck

Which hardware/os/browser are you using? This works fine on my Mac M4 under chrome and safari.

Also, what is the console output for the failure?

Following was F12 messages.=============== Powered by PlayCanvas 2.18.1 5e45104
messenger.ts:104 messenger connected
debug.js:14 DEPRECATED: pc.createShaderFromCode has been deprecated. Use ShaderUtils.createShader instead.
deprecated @ debug.js:14Understand this warning
viewport-error-console.ts:186 Failed to compile vertex shader:

ERROR: 0:664: ‘readCenter’ : no matching overloaded function found
ERROR: 0:664: ‘=’ : dimension mismatch
ERROR: 0:664: ‘=’ : cannot convert from ‘const mediump float’ to ‘highp 3-component vector of float’
ERROR: 0:680: ‘readColor’ : no matching overloaded function found
ERROR: 0:680: ‘=’ : dimension mismatch
ERROR: 0:680: ‘=’ : cannot convert from ‘const mediump float’ to ‘highp 4-component vector of float’
ERROR: 0:690: ‘readSHData’ : no matching overloaded function found
ERROR: 0:701: ‘constructor’ : too many arguments
ERROR: 0:703: ‘prepareOutputFromGamma’ : no matching overloaded function found
ERROR: 0:703: ‘constructor’ : not enough data provided for construction

@slimbuck

It was Windows. Chrome. Engine 2.18.1