Howdy, my team uses Three version 129 and I’m exploring the possibility of moving to 147.
We have an internal tool which loads equirectangular .hdr files, runs them through PMREMGenerator, and then saves the output to a .bin file. The advantage of doing so is that we can load these pre-processed PMREMs into e.g. an Oculus Quest headset and sidestep the expensive conversion (which tends to fully lock up the headset for about half a second)
I’m migrating to version 147 now, and the PMREM system has changed considerably. The biggest changes causing problems for me seem to be:
-PMREMs can now be sizes other than 768x768
-PMREMs are half floats internally
-Images assigned as envmap are now automatically converted to PMREM (this is great, but not when I’m trying to get in the middle of that process and convert the image myself)
-my dataTextures simply… are not working
What worked in v129, approximately:
//Generate PMREM
hdrEquirecRenderTarget = pmremGenerator.fromEquirectangular( texture ); //
//Read PMREM into image buffer
imgBuffer = new Uint8Array( 2359296 );
renderer.readRenderTargetPixels ( hdrEquirecRenderTarget, 0, 0, 768, 768, imgBuffer )
//Put the texture into a blob for saving
var envBlob = new Blob([imgBuffer], { type: 'application/octet-stream' });
//<SAVE envBlob TO DISK>;
//To load the texture:
imgBuffer = new Uint8Array(<LOADED FILE>);
var loadedTexture = new THREE.DataTexture( imgBuffer, 768, 768, THREE.RGBAformat, THREE.UnsignedByteType );
loadedTexture.encoding = THREE.RGBEEncoding;
loadedTexture.mapping = THREE.CubeUVReflectionMapping;
//Assign to a mesh:
testMesh.material.envMap = loadedTexture;
testMesh.material.envMap.needsUpdate = true;
And I’m surely doing a lot wrong but… I can’t get any of this to work in 147. Here’s what I have:
//Generate PMREM
hdrEquirecRenderTarget = pmremGenerator.fromEquirectangular( texture );
//Read PMREM into image buffer
imgBuffer = new Uint16Array( hdrEquirecRenderTarget.width * hdrEquirecRenderTarget.height * 4 );
renderer.readRenderTargetPixels ( hdrEquirecRenderTarget, 0, 0, hdrEquirecRenderTarget.width, hdrEquirecRenderTarget.height, imgBuffer )
//Put the texture into a blob for saving
var envBlob = new Blob([imgBuffer], { type: 'application/octet-stream' });
//<SAVE envBlob TO DISK>;
//To load the texture:
imgBuffer = new Uint16Array(<LOADED FILE>);
var loadedTexture = new THREE.DataTexture( imgBuffer, hdrEquirecRenderTarget.width, hdrEquirecRenderTarget.height, THREE.RGBAformat, THREE.UnsignedByteType );
//Assign to a mesh:
testMesh.material.envMap = loadedTexture;
testMesh.material.envMap.needsUpdate = true;
And this doesn’t work even a little bit! As best I can figure, my dataTextures are totally malformed… but really, if anybody has any suggestions, I’m all ears. I know this is a fairly complicated process and I’ve had to cut my code down a lot to make this post manageable, but I’ll answer any questions that come up.
Thanks!