Recently I've been migrating my app from normal cubemap to PMREM and noticing 3-5x drop in performance (it was 50fps, but now is just 11fps using PMREM).
After looking around in the source code to find out the difference, I see in fragment shader, function textureCubeUV has 1 to 2 calls to bilinearCubeUV, each call will access the envMap 4 times:
https://github.com/mrdoob/three.js/blob/c1ea11e4ff7aaa41334cd8d2154a5cd55b94b641/src/renderers/shaders/ShaderChunk/cube_uv_reflection_fragment.glsl.js#L118
So each pixel will access envMap texture 4 or 8 times per frame? I guess this is where the performance drop come from.
Could the PMREM code can be improved somehow to achieve better performance?
/ping @elalish
FYI @bhouston
@Ben-Mack Thanks for giving us some performance feedback! Any texture lookup with LINEAR_MIPMAP_LINEAR also accesses 8 texels, so the hope is that this compiles to machine code that isn't too much less efficient than what a plain GLSL texture lookup compiles to. However, I'll be the first to admit this hasn't been measured or optimized enough. Could you give us a glitch where we can compare your PMREM and non-PMREM versions with framerate displays? It's also entirely possible that this works better on some GPUs than others.
It's a quite heavy model with ~500k triangles, more than 100s MeshPhysicalMaterial, benchmarked on Samsung S7.
@Ben-Mack 100s of different materials? The draw call overhead alone could be a bigger problem. Is there no way to combine them with texture atlasing? In any case, if you can share an example we can test with/without PMREM then we'll have a much better chance of improving the performance.
I am pretty sure texture interpolation, including even mipmap interpolation can be handled fully within a texture unit. By doing multiple non-interpolated requests and then manual interpolation, we are by passing full hardware accelaration.
GPU technology keeps changing but this was at least the case at one point recently:
https://www.iquilezles.org/www/articles/texture/texture.htm
https://www.iquilezles.org/www/articles/hwinterpolation/hwinterpolation.htm
I wouldn't be surprised if NVIDIA gpus handle this differently that mobile GPUs.
@bhouston recently I also was working on envMaps (switched from cubemap to PMREM). No matter one or many objects use the material.envMap I am having a huge fps drop (60 to 20~25).
I'm running on GPU GTX1060 6gb. When I was using cubemaps (I was getting warnings in the console) but envMaps were working fine.
Most helpful comment
@Ben-Mack 100s of different materials? The draw call overhead alone could be a bigger problem. Is there no way to combine them with texture atlasing? In any case, if you can share an example we can test with/without PMREM then we'll have a much better chance of improving the performance.