preprocessing an environment map with PMREMGenerator

Viewed 991

I'm trying to understand how to preprocess envMaps correctly with the PMREMGenerator.

My current situation:

I create a PMREM immediately after setting up my scene, and compile its equirectangular shader (that compile step is not clear to me, but that's what I've seen in examples):

 this.mPmremGenerator = new THREE.PMREMGenerator(this.mRenderer);
this.mPmremGenerator.compileEquirectangularShader();

Next, I use TextureLoader to load the envmap texture, and in its callback, I use fromEquirectangular to preprocess the envmap into a RenderTarget, and extract the new texture from it and return it.

private preprocessEnvMap(pEnvMap: Texture) { 
     const WorldContext.mainScene.pmremGenerator;
     return aPmremGenerator.fromEquirectangular(pEnvMap).texture;
}

Finally, I take the returned texture, assign it as my material's envMap, and call the material's needsUpdate = true.

The result is that I get a shader error:

THREE.WebGLProgram: shader error:  0 35715 false gl.getProgramInfoLog No compiled fragment shader when at least one graphics shader is attached.

Help will be much appreciated,

Thanks

EDIT:

This is an example where I use the PMREMGenerator with a standard material: https://codepen.io/tfreifeld/pen/OJWgdem

You can see that both the image in the background and in the envmap are blurry.

This is the original image:

https://imgur.com/a/M2mwNFa

1 Answers

(that compile step is not clear to me, but that's what I've seen in examples):

This is done in order to pre-compile the internal shader. Otherwise the generator has to do this when processing an environment map. So calling compileEquirectangularShader() just distributes some work to the application start.

Next, I use TextureLoader to load the envmap texture, and in its callback, I use fromEquirectangular to preprocess the envmap into a RenderTarget, and extract the new texture from it and return it.

Keep in mind that you should use PMREMGenerator with HDR textures for best quality (although it is not mandatory). So you probably want a setup where you use RGBELoader, RGBMLoader or EXRLoader instead of TextureLoader as well as respective HDR textures.

Finally, I take the returned texture, assign it as my material's envMap, and call the material's needsUpdate = true.

It should not be necessary to set needsUpdate to true.

If the error still pops up, I suggest you demonstrate the issue with a live example (so it's possible to debug the issue).

Related