Conversation
…into improvedPMREM
cdata
left a comment
There was a problem hiding this comment.
There is still room for improvement
Can you share your thoughts on specific areas for future improvement?
Generally this looks really good. I have to trust you that some of these changes work as advertised until #682 , but maybe you would be willing to show off with some screenshots in the mean time? 🙏
| (cubeTarget: WebGLRenderTargetCube, renderer: WebGLRenderer): | ||
| WebGLRenderTarget => { | ||
| const {cubeUVRenderTarget, cubeLods, meshes} = setup(cubeTarget); | ||
| const roughnessExtra = [0.5, 0.7, 1.0]; |
There was a problem hiding this comment.
I eventually determined that these were referring to lods, but from this line the purpose of these numbers seems kind of obscure.
| }); | ||
| meshes.forEach((mesh) => { | ||
| (mesh.material as Material).dispose(); | ||
| // (mesh.material as Material).dispose(); |
There was a problem hiding this comment.
Did we decide that we aren't going to dispose of this stuff? If so, maybe the meshes should just be a static array that gets updated as needed?
There was a problem hiding this comment.
The shaders take longer to compile than they take to run, so it's very important that we don't dispose of them, since three does such a nice job caching them. Are we worried about a leak here? The programs are always identical, so three ensures they don't get duplicated. We shouldn't delete them until will not be loading any new environments anymore, and basing that on page navigation sounds reasonable?
| const lodMax = 8; | ||
| // lodBase is the mip Level that is integrated to form all of the extra | ||
| // levels, but is not output directly into the PMREM texture. DO NOT | ||
| // CHANGE, as the Blur shader below is hard coded for this size. |
| vec3 direction = vec3(clamp(uv, -1.0, 1.0), 1.0); | ||
| uv = abs(uv); | ||
| float over = max(uv.x, uv.y) - 1.0; | ||
| if(over > 0.0) direction.z -= over; |
There was a problem hiding this comment.
This is an interesting tweak. What case is being handled here?
There was a problem hiding this comment.
Added a comment above.
| #define cubeUV_faceSize (256.0) | ||
| #define cubeUV_maxMipLevel (8.0) | ||
| const float cubeUV_maxMipLevel = 8.0; | ||
| const float cubeUV_minMipLevel = 3.0; |
There was a problem hiding this comment.
I almost wish these could be shared constants across this shader chunk and the PMREM generator (also mipBase). Or maybe uniforms? But that would be unnecessary since we can just "preprocess" them into the program source here..
There was a problem hiding this comment.
Yeah, really they should be uniforms, but since this is internal to three.js, we'll have to wait until it's upstreamed for that.
|
|
||
| vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) { | ||
|
|
||
| // Workaround for Adreno 3XX dFd*( vec3 ) bug. See #9988 |
There was a problem hiding this comment.
Is this file forked from Three.js? If so, can we document the nature of the changes? (ditto for lights_fragment_maps.glsl.js)
There was a problem hiding this comment.
Yes, I can do that.
| float f = fract(mip); | ||
| vec4 textureCubeUV(sampler2D envMap, vec3 sampleDir, float roughness) { | ||
| float filterMip = 0.0; | ||
| if(roughness >= 0.7){ |
There was a problem hiding this comment.
Nit: kinda funky formatting in this conditional, maybe match the one below?
| // This is a hack because IE claims that a shader which unrolls a loop to access | ||
| // 96 texture lookups has "complexity which exceeds allowed limits", however 48 | ||
| // seems to be fine, so we subsample. This could be improved if someone cares a | ||
| // lot about IE. |
There was a problem hiding this comment.
I wonder if there are low-end devices that might also have issues with this.
Separately, it might be cleaner to read if this was written as a preprocessor directive. Although as I write that, I'm not 100% sure if that will prevent IE from barfing when linking the shader.
There was a problem hiding this comment.
That's a good idea; I'll give that a try.
There was a problem hiding this comment.
Was it too cumbersome to use Three.js' defines property for ShaderMaterial to do this?
There was a problem hiding this comment.
Yeah, those are really for defining constants, not just a switch. I noticed this is the way three tends to do it internally.
| * even more filtered mips at the same lodMin resolution, associated with higher | ||
| * roughness levels. These extra mips are stored at X rather than Y offsets to | ||
| * help distiguish them. In this way we maintain resolution to smoothly | ||
| * interpolate diffuse lighting while limiting sampling computation. |
|
|
||
| //float envMapWidth = pow( 2.0, maxMIPLevelScalar ); | ||
| //float desiredMIPLevel = log2( envMapWidth * sqrt( 3.0 ) ) - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 ); | ||
| // (elalish) Changed from Blinn-Phong to Trowbridge-Reitz distribution and added anti-aliasing. |
| } | ||
|
|
||
| vec3 getLightProbeIndirectRadiance( /*const in SpecularLightProbe specularLightProbe,*/ const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) { | ||
| // (elalish) Changed the input from blinnShininessExponent to roughness, so that we can use the Trowbridge-Reitz distribution instead. |
|
|
||
| #endif | ||
|
|
||
| // (elalish) Mixing the reflection with the normal is more accurate and keeps rough objects from gathering light from behind their tangent plane. |
| vec3 N = normalize( surf_norm ); | ||
| mat3 tsn = mat3( S, T, N ); | ||
|
|
||
| // (elalish) Biased the normal mip to anti-alias the normal's screen-space derivatives |
| <!-- Uncomment the following script in order to debug shader errors in Sauce Labs. When | ||
| a shader fails to compile, it logs a console.error ("Shader failed to compile!") before it logs | ||
| the debug output from WebGL. Without this script, WCT bails out on the first error, so you | ||
| never see the useful log, which tends to be especially critical for IE11. --> |
Improved PMREM (google#710) * starting to work * blurShader working * updated IBL lookup * fixed roughness mapping * gave fidelity tests orbit controls * added antialiasing, corrected texelSize * added single-pixel mip * refactored blurShader * added bottom of mipmap chain * refactored antialiasing into cubeUV * extra mipmaps working * fixed moire mostly * simplified PMREM * minMip level => 3 * tweaked filtering function * removed debug export * switching const to #define for IE * fixed IE shader complexity bug * addressing feedback * refactored IE11 #defines * merging master * updated asset paths * replaced shader const with #define to support IE11 * fixed another const and a small math error * using defines in gaussianBlur
Fixes #587
Fixes #632
This is an improvement to the very simple PMREM approximation we were using before. It also includes several fixes to the three.js MeshStandardMaterial that we use. These changes mostly made HDR environment maps look more realistic, but also included is a change which cleans up the aliasing we were getting from high frequency normal maps. There is still room for improvement, but it's significantly better than what it was. I also updated our lighting & environment page to better showcase our rendering with HDR.