Once again I am having trouble with loading an editor build in my engine-only app. My models in the custom app look different than the ones in the normal build.
I have been able to narrow the issue down to one property in my material, ‘specularUniform’. It is a different value in my custom loader than in the normal loader (opening index.html from the build), when I simply force that value to be the same, it looks fine.
See the color difference below:
I’ll explain my loader code here,
First of all I set all the assets to not ‘preload’, I want to control this myself, then I download files from my server and turn them into blob urls and set those urls to the asset.file.url for each asset.
for (const assetId in buildData.assets) {
const asset = buildData.assets[assetId];
if (asset.type !== 'script') buildData.assets[assetId].preload = false;
if (asset.file) {
let responseType = '';
if (asset.type === 'model') responseType = 'application/json';
if (asset.type === 'texture') responseType = 'arraybuffer';
// Loading from local files for debug
const promise = new Promise((resolve, reject) => {
axios.get(`/playcanvas_build/${asset.file.url}`, {
responseType,
}).then((result) => {
const data = result.data;
let assetBlob;
if (asset.type === 'model') assetBlob = new Blob([JSON.stringify(data)], {
type: 'application/json'
});
if (asset.type === 'texture') assetBlob = bytesToB64Blob(new Uint8Array(data));
else assetBlob = new Blob([data]);
const assetUrl = URL.createObjectURL(assetBlob);
buildData.assets[assetId].file.url = assetUrl;
resolve();
});
});
loadPromises.push(promise);
}
}
Then following the start script of normal builds, I run app.configure with the build json file url and create a scene from my scene json. Then I only preload the texture files by directly loading it with the resource manager, otherwise it adds ?t=...
which breaks blob urls.
app.configure(buildUrl, async (err) => {
if (err) return console.error(err);
// Create the scene entry
const sceneBlobData = JSON.stringify(sceneData);
const blob = new Blob([sceneBlobData], {
type: 'application/json',
});
const url = URL.createObjectURL(blob);
pc.app.scenes.add('CustomBuild', url);
const scene = pc.app.scenes.find('CustomBuild');
// Go through all the texture assets and load them manually
// (bypassing the app.assets.load method)
const assets = app.assets._assets;
const textureLoads = [];
for (let index = 0; index < assets.length; index++) {
const asset = assets[index];
if (asset.type === 'texture') {
const promise = new Promise((resolve) => {
const file = asset.file;
// _opened and _loaded copied from Playcanvas source
const _opened = function (resource) {
if (resource instanceof Array) {
asset.resources = resource;
} else {
asset.resource = resource;
}
app.loader.patch(asset, app.assets);
app.assets.fire('load', asset);
app.assets.fire(`load:${asset.id}`, asset);
if (file && file.url) app.assets.fire(`load:url:${file.url}`, asset);
asset.fire('load', asset);
resolve();
};
const _loaded = function (err, resource, extra) {
asset.loaded = true;
asset.loading = false;
if (err) {
app.assets.fire('error', err, asset);
app.assets.fire(`error:${asset.id}`, err, asset);
asset.fire('error', err, asset);
} else {
_opened(resource);
}
};
// Load through the ResourceLoader directly
app.loader.load(asset.file.url, asset.type, _loaded, asset);
});
textureLoads.push(promise);
}
}
await Promise.all(textureLoads);
// Finally, add the scene hierarchy to the app
app.loadSceneHierarchy(scene.url, () => {
resolve();
console.log(app.assets);
});
After this I simply start the app.
Does anyone know why the specularUniform can be different in the different builds?
If you need more information please let me know!