Skip to content

Commit 519334c

Browse files
bkaradzic-microsoftbkaradzic
authored andcommitted
Add .env fallback for cubemap loads + re-enable 7 tests
Babylon Native's NativeEngine.createCubeTexture override only handles .env single-file cubemaps and 6-face arrays; .dds / .ktx / .ktx2 URLs fall through to a throw ("Cannot load cubemap because 6 files were not defined"). The loader-aware path used by the WebGL engine (texture loader registry lookup) is bypassed entirely. Add a JS-side polyfill that detects .dds / .ktx / .ktx2 single-URL cubemap loads and retries with the .env extension. Babylon's CI generates both .dds and .env from the same source HDR and uploads them to the same CDN path, so the swap is transparent for the Babylon-hosted environments these tests reference. On 404 (no .env counterpart exists) the polyfill re-invokes the original code path, preserving the existing throw semantics. This unblocks 7 tests that were excluded because the throw aborted the scene before any rendering could happen: idx 141 NMEGLTF idx 172 Anisotropic idx 173 Clear Coat idx 246 PBRMetallicRoughnessMaterial idx 247 PBRSpecularGlossinessMaterial idx 248 PBR idx 290 Prepass SSAO + depth of field Strip excludeFromAutomaticTesting + reason from those 7 entries in config.json. All 7 validate sub-threshold on Win32 V8 D3D11 Release without --include-excluded after the strip (pixel diff range 308..2638, well under the 2.5% threshold).
1 parent 29eb33e commit 519334c

4 files changed

Lines changed: 115 additions & 14 deletions

File tree

Apps/Playground/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ set(DEPENDENCIES
1313
"../Dependencies/recast.js")
1414

1515
set(SCRIPTS
16+
"Scripts/cube_texture_polyfill.js"
1617
"Scripts/dom_polyfill.js"
1718
"Scripts/experience.js"
1819
"Scripts/fetch_polyfill.js"

Apps/Playground/Scripts/config.json

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -858,8 +858,6 @@
858858
{
859859
"title": "NMEGLTF",
860860
"playgroundId": "#WGZLGJ#10320",
861-
"excludeFromAutomaticTesting": true,
862-
"reason": "Pixel comparison fails (more than 20% pixels differ)",
863861
"referenceImage": "nmegltf.png"
864862
},
865863
{
@@ -1056,15 +1054,11 @@
10561054
{
10571055
"title": "Anisotropic",
10581056
"playgroundId": "#MAXCNU#1",
1059-
"excludeFromAutomaticTesting": true,
1060-
"reason": "Pixel comparison fails (more than 20% pixels differ)",
10611057
"referenceImage": "anisotropic.png"
10621058
},
10631059
{
10641060
"title": "Clear Coat",
10651061
"playgroundId": "#YACNQS#2",
1066-
"excludeFromAutomaticTesting": true,
1067-
"reason": "Pixel comparison fails (more than 20% pixels differ)",
10681062
"referenceImage": "clearCoat.png"
10691063
},
10701064
{
@@ -1575,22 +1569,16 @@
15751569
{
15761570
"title": "PBRMetallicRoughnessMaterial",
15771571
"playgroundId": "#2FDQT5#13",
1578-
"excludeFromAutomaticTesting": true,
1579-
"reason": "Pixel comparison fails (more than 20% pixels differ)",
15801572
"referenceImage": "PBRMetallicRoughnessMaterial.png"
15811573
},
15821574
{
15831575
"title": "PBRSpecularGlossinessMaterial",
15841576
"playgroundId": "#Z1VL3V#4",
1585-
"excludeFromAutomaticTesting": true,
1586-
"reason": "Pixel comparison fails (more than 20% pixels differ)",
15871577
"referenceImage": "PBRSpecularGlossinessMaterial.png"
15881578
},
15891579
{
15901580
"title": "PBR",
15911581
"playgroundId": "#LCA0Q4#27",
1592-
"excludeFromAutomaticTesting": true,
1593-
"reason": "Pixel comparison fails (more than 20% pixels differ)",
15941582
"referenceImage": "pbr.png"
15951583
},
15961584
{
@@ -1873,8 +1861,6 @@
18731861
"title": "Prepass SSAO + depth of field",
18741862
"playgroundId": "#8F5HYV#72",
18751863
"renderCount": 10,
1876-
"excludeFromAutomaticTesting": true,
1877-
"reason": "Pixel comparison fails (more than 20% pixels differ)",
18781864
"referenceImage": "prepass-ssao-dof.png"
18791865
},
18801866
{
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// Cube texture fallback for BN's NativeEngine.
2+
//
3+
// BN's NativeEngine.createCubeTexture only natively handles .env single-file
4+
// cubemaps and 6-file face arrays. Snippets that load .dds (or .ktx) cubemaps
5+
// without an explicit forcedExtension or 6-file array throw "Cannot load
6+
// cubemap because 6 files were not defined".
7+
//
8+
// Babylon's standard environment cubemaps are hosted both as <name>.dds and
9+
// <name>.env at the same path on assets.babylonjs.com and
10+
// playground.babylonjs.com. This polyfill detects the failure pre-condition
11+
// and transparently retries with the .env URL. If the .env counterpart 404s,
12+
// it falls through to the original (which throws), preserving existing
13+
// behavior.
14+
15+
(function () {
16+
"use strict";
17+
18+
if (typeof BABYLON === "undefined") {
19+
return;
20+
}
21+
if (!BABYLON.NativeEngine || !BABYLON.NativeEngine.prototype) {
22+
return;
23+
}
24+
25+
var proto = BABYLON.NativeEngine.prototype;
26+
if (proto.__cubeTexturePolyfillInstalled) {
27+
return;
28+
}
29+
proto.__cubeTexturePolyfillInstalled = true;
30+
31+
var original = proto.createCubeTexture;
32+
if (typeof original !== "function") {
33+
return;
34+
}
35+
36+
var FALLBACK_EXTS = [".dds", ".ktx", ".ktx2"];
37+
38+
function getExtension(url, forced) {
39+
if (forced) {
40+
return forced.toLowerCase();
41+
}
42+
var dot = url.lastIndexOf(".");
43+
if (dot < 0) {
44+
return "";
45+
}
46+
var ext = url.substring(dot).toLowerCase();
47+
var q = ext.indexOf("?");
48+
if (q >= 0) {
49+
ext = ext.substring(0, q);
50+
}
51+
return ext;
52+
}
53+
54+
function replaceExt(url, oldExt) {
55+
return url.substring(0, url.length - oldExt.length) + ".env";
56+
}
57+
58+
proto.createCubeTexture = function (rootUrl, scene, files, noMipmap, onLoad, onError, format, forcedExtension, createPolynomials, lodScale, lodOffset, fallback, loaderOptions, useSRGBBuffer, buffer) {
59+
var ext = getExtension(rootUrl, forcedExtension);
60+
var hasFiles = files && files.length === 6;
61+
var canFallback = !buffer && !forcedExtension && !hasFiles && FALLBACK_EXTS.indexOf(ext) >= 0;
62+
63+
if (!canFallback) {
64+
return original.apply(this, arguments);
65+
}
66+
67+
var self = this;
68+
var envUrl = replaceExt(rootUrl, ext);
69+
var texture = fallback || new BABYLON.InternalTexture(self, 7 /* Cube */);
70+
texture.isCube = true;
71+
texture.url = rootUrl;
72+
73+
var settled = false;
74+
var settle = function (action) {
75+
if (settled) {
76+
return;
77+
}
78+
settled = true;
79+
try {
80+
action();
81+
} catch (e) {
82+
if (onError) {
83+
onError(e && e.message ? e.message : String(e), e);
84+
}
85+
}
86+
};
87+
88+
var onEnvLoaded = function (data) {
89+
settle(function () {
90+
var buf = (data && data.byteLength !== undefined && !(data instanceof Uint8Array)) ? new Uint8Array(data, 0, data.byteLength) : data;
91+
original.call(self, envUrl, scene, files, noMipmap, onLoad, onError, format, ".env", createPolynomials, lodScale || 0, lodOffset || 0, texture, loaderOptions, useSRGBBuffer || false, buf);
92+
});
93+
};
94+
95+
var onEnvFailed = function (request, exception) {
96+
settle(function () {
97+
original.call(self, rootUrl, scene, files, noMipmap, onLoad, onError, format, forcedExtension, createPolynomials, lodScale, lodOffset, texture, loaderOptions, useSRGBBuffer, buffer);
98+
});
99+
};
100+
101+
try {
102+
self._loadFile(envUrl, onEnvLoaded, undefined, undefined, true, onEnvFailed);
103+
} catch (e) {
104+
onEnvFailed(null, e);
105+
}
106+
107+
return texture;
108+
};
109+
110+
if (typeof console !== "undefined" && console.log) {
111+
console.log("[cube_texture_polyfill] NativeEngine.createCubeTexture patched with .env fallback");
112+
}
113+
})();

Apps/Playground/Shared/AppContext.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ AppContext::AppContext(
222222
// Commenting out recast.js for now because v8jsi is incompatible with asm.js.
223223
// m_scriptLoader->LoadScript("app:///Scripts/recast.js");
224224
m_scriptLoader->LoadScript("app:///Scripts/babylon.max.js");
225+
m_scriptLoader->LoadScript("app:///Scripts/cube_texture_polyfill.js");
225226
m_scriptLoader->LoadScript("app:///Scripts/babylonjs.loaders.js");
226227
m_scriptLoader->LoadScript("app:///Scripts/babylonjs.materials.js");
227228
m_scriptLoader->LoadScript("app:///Scripts/babylon.gui.js");

0 commit comments

Comments
 (0)