Add HDR texture support and metadata extraction

This commit is contained in:
2026-03-31 23:04:28 +02:00
parent d061aa3021
commit 514114892d

View File

@@ -184,6 +184,18 @@ function extractImageAssetMetadata(image: HTMLImageElement): ImageAssetMetadata
};
}
function extractHdrTextureMetadata(texture: DataTexture): ImageAssetMetadata {
const width = texture.image.width as number;
const height = texture.image.height as number;
const warnings: string[] = [];
if (Math.abs(width / height - 2) > 0.15) {
warnings.push("Background images work best as a 2:1 equirectangular panorama.");
}
return { kind: "image", width, height, hasAlpha: false, warnings };
}
function createImageTexture(image: HTMLImageElement): Texture {
const texture = new Texture(image);
texture.colorSpace = SRGBColorSpace;
@@ -192,6 +204,28 @@ function createImageTexture(image: HTMLImageElement): Texture {
return texture;
}
function configureHdrTexture(texture: DataTexture): DataTexture {
// HDR/EXR data is linear — do not apply sRGB color space
texture.colorSpace = LinearSRGBColorSpace;
texture.mapping = EquirectangularReflectionMapping;
texture.needsUpdate = true;
return texture;
}
function loadHdrTexture(url: string, sourceName: string): Promise<DataTexture> {
return new Promise<DataTexture>((resolve, reject) => {
if (getFileExtension(sourceName) === "exr") {
new EXRLoader().load(url, resolve, undefined, () => {
reject(new Error(`EXR file could not be loaded: ${sourceName}.`));
});
} else {
new RGBELoader().load(url, resolve, undefined, () => {
reject(new Error(`HDR file could not be loaded: ${sourceName}.`));
});
}
});
}
function createLoadedImageAsset(
asset: ImageAssetRecord,
image: HTMLImageElement,
@@ -208,6 +242,22 @@ function createLoadedImageAsset(
};
}
function createLoadedHdrImageAsset(
asset: ImageAssetRecord,
texture: DataTexture,
sourceUrl: string,
revokeSourceUrl: () => void
): LoadedImageAsset {
return {
assetId: asset.id,
storageKey: asset.storageKey,
metadata: asset.metadata,
texture: configureHdrTexture(texture),
sourceUrl,
revokeSourceUrl
};
}
function createImageAssetRecord(
sourceName: string,
mimeType: string,