BabylonJS/Babylon.js · error

Shader bindings not set!

Error message

Shader bindings not set!

What it means

OptimizedShaderBlock defers creation of its ShaderBinding until bindings are set during optimization (this._shaderBindings). getShaderBinding() throws this error if called before the optimizer has populated them, because there is no object available to bind uniforms/textures to the effect.

Source

Thrown at packages/dev/smartFilters/src/optimization/optimizedShaderBlock.ts:114

    public setShaderProgram(shaderProgram: ShaderProgram): void {
        this._shaderProgram = shaderProgram;
    }

    /**
     * Sets the list of shader bindings to use to render the block.
     * @param shaderBindings - The list of shader bindings to use to render the block
     */
    public setShaderBindings(shaderBindings: ShaderBinding[]): void {
        this._shaderBindings = shaderBindings;
    }

    /**
     * Get the class instance that binds all the required data to the shader (effect) when rendering.
     * @returns The class instance that binds the data to the effect
     */
    public getShaderBinding(): ShaderBinding {
        if (this._shaderBindings === null) {
            throw new Error("Shader bindings not set!");
        }

        for (const input of this.inputs) {
            const name = input.name;

            if (input.type === ConnectionPointType.Texture) {
                /**
                 * These are the inputs created by the OptimizedShaderBlock
                 * We pass them to OptimizedShaderBinding so that their value can be set appropriately at runtime (in the bind method)
                 */
                this._inputTextures[name] = input.runtimeData as RuntimeData<ConnectionPointType.Texture>;
            }
        }

        return new OptimizedShaderBinding(this._shaderBindings, this._inputTextures);
    }
}

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Run SmartFilterOptimizer (or the standard filter build) to populate shader bindings before rendering.
  2. Ensure the previous optimization step did not throw and leave the block partially optimized.
  3. Only render/execute optimized filters through the SmartFilter runtime rather than calling getShaderBinding manually.

Example fix

// before
const binding = optimizedBlock.getShaderBinding(); // too early
// after
const runtimeData = await SmartFilterOptimizer.OptimizeAsync(engine, smartFilter, texture);
// runtime data is now bound; use runtimeData to render
Defensive patterns

Strategy: validation

Validate before calling

if (!optimizedBlock["_shaderBindings"]) {
  throw new Error("Run SmartFilterOptimizer before accessing shader bindings");
}

Type guard

null

Try / catch

try {
  const binding = optimizedBlock.getShaderBinding();
} catch (e) {
  if (e.message === "Shader bindings not set!") {
    throw new Error("Filter must be optimized via SmartFilterOptimizer before rendering");
  } else throw e;
}

Prevention

When it happens

Trigger: Calling getShaderBinding() on an OptimizedShaderBlock that was constructed manually or whose optimization pipeline never completed (e.g. SmartFilterOptimizer was not run, or threw before binding setup).

Common situations: Using optimized blocks outside the normal SmartFilter runtime flow; the optimizer run aborted midway due to another error, leaving blocks unbound; custom runtimes reading bindings before the first optimize pass.

Related errors


AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30). Data as JSON: /api/errors/78548331182d6198. Report an issue: GitHub.