Skip to content

Commit

Permalink
Adjust code to precalculate values where feasible
Browse files Browse the repository at this point in the history
  • Loading branch information
mjurczyk committed Jul 8, 2024
1 parent fdc4cd7 commit 845e66e
Showing 1 changed file with 88 additions and 63 deletions.
151 changes: 88 additions & 63 deletions examples/jsm/loaders/UltraHDRLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,9 @@ class UltraHDRLoader extends Loader {

} else {

sections[ sections.length - 1 ].section.push( byte );
sections[ sections.length - 1 ].section.push( byte, leadingByte );

byteOffset ++;
byteOffset += 2;

}

Expand All @@ -140,6 +140,8 @@ class UltraHDRLoader extends Loader {

}

let primaryImage, gainmapImage;

for ( let i = 0; i < sections.length; i ++ ) {

const { sectionType, section, sectionOffset } = sections[ i ];
Expand Down Expand Up @@ -213,42 +215,51 @@ class UltraHDRLoader extends Loader {
sectionOffset +
6;

const primaryImage = new Uint8Array(
primaryImage = new Uint8Array(
data.buffer,
primaryImageOffset,
primaryImageSize
);
const gainmapImage = new Uint8Array(

gainmapImage = new Uint8Array(
data.buffer,
gainmapImageOffset,
gainmapImageSize
);

this._applyGainmapToSDR(
xmpMetadata,
primaryImage,
gainmapImage,
( hdrBuffer, width, height ) => {
}

onLoad( {
width,
height,
data: hdrBuffer,
format: RGBAFormat,
type: this.type,
} );
}

},
( error ) => {
}

throw new Error( error );
if ( primaryImage && gainmapImage ) {

}
);
this._applyGainmapToSDR(
xmpMetadata,
primaryImage,
gainmapImage,
( hdrBuffer, width, height ) => {

onLoad( {
width,
height,
data: hdrBuffer,
format: RGBAFormat,
type: this.type,
} );

},
( error ) => {

throw new Error( error );

}
);

}
} else {

throw new Error( 'THREE.UltraHDRLoader: Could not parse UltraHDR images' );

}

Expand Down Expand Up @@ -387,12 +398,6 @@ class UltraHDRLoader extends Loader {

}

_clamp( value, min, max ) {

return Math.min( Math.max( value, min ), max );

}

_applyGainmapToSDR(
xmpMetadata,
sdrBuffer,
Expand Down Expand Up @@ -455,7 +460,7 @@ class UltraHDRLoader extends Loader {

const canvas = document.createElement( 'canvas' );
const ctx = canvas.getContext( '2d', {
willReadFrequently: false,
willReadFrequently: true,
colorSpace: 'srgb',
} );

Expand Down Expand Up @@ -496,9 +501,7 @@ class UltraHDRLoader extends Loader {

if ( this.type === HalfFloatType ) {

hdrBuffer = new Uint16Array( sdrImageData.data.length ).fill(
DataUtils.toHalfFloat( 255 )
);
hdrBuffer = new Uint16Array( sdrImageData.data.length ).fill( 23544 );

} else {

Expand All @@ -516,39 +519,61 @@ class UltraHDRLoader extends Loader {
const unclampedWeightFactor =
( Math.log2( maxDisplayBoost ) - xmpMetadata.hdrCapacityMin ) /
( xmpMetadata.hdrCapacityMax - xmpMetadata.hdrCapacityMin );
const weightFactor = this._clamp( unclampedWeightFactor, 0.0, 1.0 );

sdrImageData.data.forEach( ( sdrValue, index ) => {

/* Prefilled buffer already contains the alpha channel */
if ( ( index + 1 ) % 4 === 0 ) return;

const x = index % ( sdrImage.width * 4 );
const y = Math.floor( index / ( sdrImage.width * 4 ) );

const gainmapIndex = y * sdrImage.width * 4 + x;
const gainmapValue = gainmapImageData.data[ gainmapIndex ] / 255.0;

const logRecovery = Math.pow( gainmapValue, 1.0 / xmpMetadata.gamma );
const logBoost =
xmpMetadata.gainMapMin * ( 1.0 - logRecovery ) +
xmpMetadata.gainMapMax * logRecovery;
const hdrValue =
( sdrValue + xmpMetadata.offsetSDR ) *
Math.pow( 2, logBoost * weightFactor ) -
xmpMetadata.offsetHDR;
const linearHDRValue = this._clamp(
this._srgbToLinear( hdrValue ),
0,
65504
);
const weightFactor = Math.min(
Math.max( unclampedWeightFactor, 1.0 ),
0.0
);
const useGammaOne = xmpMetadata.gamma === 1.0;
const sdrImageWidthStride = sdrImage.width * 4;

hdrBuffer[ index ] =
this.type === HalfFloatType
? DataUtils.toHalfFloat( linearHDRValue )
: linearHDRValue;
for (
let pixelIndex = 0;
pixelIndex < sdrImageData.data.length;
pixelIndex += 4
) {

} );
const x = ( pixelIndex / 4 ) % sdrImage.width;
const y = Math.floor( pixelIndex / 4 / sdrImage.width );

for ( let index = pixelIndex; index < pixelIndex + 3; index ++ ) {

const sdrValue = sdrImageData.data[ index ];

const gainmapIndex = y * sdrImageWidthStride + x;
const gainmapValue = gainmapImageData.data[ gainmapIndex ] / 255.0;

/* Gamma is 1.0 by default */
const logRecovery = useGammaOne
? gainmapValue
: Math.pow( gainmapValue, 1.0 / xmpMetadata.gamma );

const logBoost =
xmpMetadata.gainMapMin * ( 1.0 - logRecovery ) +
xmpMetadata.gainMapMax * logRecovery;

const hdrValue =
( sdrValue + xmpMetadata.offsetSDR ) *
( logBoost * weightFactor === 0.0
? 1.0
: Math.pow( 2, logBoost * weightFactor ) ) -
xmpMetadata.offsetHDR;

const linearHDRValue = Math.min(
Math.max(
this._srgbToLinear( hdrValue ),
0
),
65504
);

hdrBuffer[ index ] =
this.type === HalfFloatType
? DataUtils.toHalfFloat( linearHDRValue )
: linearHDRValue;

}

}

onSuccess( hdrBuffer, sdrImage.width, sdrImage.height );

Expand Down

0 comments on commit 845e66e

Please sign in to comment.