{"record":{"id":"dd54f8a956a9b3b7","repo":"BabylonJS/Babylon.js","slug":"hdr-prefiltering-is-not-available-in-webgl-1-you-dd54f8","errorCode":null,"errorMessage":"HDR prefiltering is not available in WebGL 1., you can use real time filtering instead.","messagePattern":"HDR prefiltering is not available in WebGL 1\\., you can use real time filtering instead\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/dev/core/src/Materials/Textures/Filtering/hdrIrradianceFiltering.ts","lineNumber":206,"sourceCode":"     * @param texture Texture to filter\r\n     * @returns true if the filter is ready\r\n     */\r\n    public isReady(texture: BaseTexture) {\r\n        return texture.isReady() && this._effectWrapper.effect.isReady();\r\n    }\r\n\r\n    /**\r\n     * Prefilters a cube texture to contain IBL irradiance.\r\n     * Prefiltering will be invoked at the end of next rendering pass.\r\n     * This has to be done once the map is loaded, and has not been prefiltered by a third party software.\r\n     * See http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf for more information\r\n     * @param texture Texture to filter\r\n     * @returns Promise called when prefiltering is done\r\n     */\r\n    // eslint-disable-next-line @typescript-eslint/naming-convention\r\n    public async prefilter(texture: BaseTexture): Promise<BaseTexture> {\r\n        if (!this._engine._features.allowTexturePrefiltering) {\r\n            throw new Error(\"HDR prefiltering is not available in WebGL 1., you can use real time filtering instead.\");\r\n        }\r\n\r\n        if (this.useCdf) {\r\n            this._cdfGenerator = new IblCdfGenerator(this._engine);\r\n            this._cdfGenerator.iblSource = texture;\r\n\r\n            await this._cdfGenerator.renderWhenReady();\r\n        }\r\n\r\n        this._effectRenderer = new EffectRenderer(this._engine);\r\n        this._effectWrapper = this._createEffect(texture);\r\n        await this._effectWrapper.effect.whenCompiledAsync();\r\n\r\n        const irradianceTexture = this._prefilterInternal(texture);\r\n\r\n        if (this.useCdf) {\r\n            // eslint-disable-next-line github/no-then\r\n            await this._cdfGenerator.findDominantDirection().then((dir) => {\r","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/core/src/Materials/Textures/Filtering/hdrIrradianceFiltering.ts#L188-L224","documentation":"HDRFiltering (HDR irradiance pipeline) prefilter() bakes an HDR texture into a pre-filtered IBL texture. It throws when engine._features.allowTexturePrefiltering is false, which is the case on WebGL 1 (or engines lacking the feature). The message advises using the real-time filtering path instead of offline prefiltering.","triggerScenarios":"Calling hdrIrradianceFiltering.prefilter(texture) on a WebGL 1 engine or any engine whose _features.allowTexturePrefiltering is false; also reached indirectly via loaders (e.g., _loadTexture invoking prefilter) on unsupported engines.","commonSituations":"Legacy browser or iOS device limited to WebGL 1; loading an HDR environment for IBL in a scene; a tool/importer path that always calls prefilter without checking engine capabilities.","solutions":["Check engine._features.allowTexturePrefiltering before calling prefilter() and branch to real-time filtering when false","Use a pre-converted .env (prefiltered) cube texture instead of prefiltering .hdr at runtime on WebGL 1","Force WebGL 2 context (or WebGPU engine) in application bootstrap so the feature flag is enabled","If the error surfaces from a loader, update the loading code to fall back to non-prefiltered IBL estimation on unsupported engines"],"exampleFix":"// before\nconst filtering = new HDRFiltering(engine);\nconst baked = await filtering.prefilter(hdrTexture);\n// after\nlet baked: BaseTexture;\nif (engine._features.allowTexturePrefiltering) {\n    baked = await new HDRFiltering(engine).prefilter(hdrTexture);\n} else {\n    baked = CubeTexture.CreateFromPrefilteredData('environment.env', scene);\n}","handlingStrategy":"fallback","validationCode":"if (!engine._features.allowTexturePrefiltering) {\n    return CubeTexture.CreateFromPrefilteredData('environment.env', scene);\n}\nconst baked = await hdrIrradianceFiltering.prefilter(hdrTexture);","typeGuard":"function supportsTexturePrefiltering(engine: AbstractEngine): boolean {\n    return !!engine._features?.allowTexturePrefiltering;\n}","tryCatchPattern":"try {\n    baked = await filtering.prefilter(hdrTexture);\n} catch (e) {\n    if (String(e?.message).includes('HDR prefiltering')) {\n        baked = CubeTexture.CreateFromPrefilteredData('environment.env', scene);\n    } else {\n        throw e;\n    }\n}","preventionTips":["Gate prefilter() behind an engine feature check at call sites and loaders","Force WebGL2/WebGPU context creation in app bootstrap","Ship prefiltered .env assets for environments that must run on WebGL 1","Add a CI smoke test running the load path on a WebGL 1 context"],"tags":["webgl1","hdr","prefiltering","engine-capability","ibl"],"backgroundTag":"unsupported-webgl-feature","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}