three.js icon indicating copy to clipboard operation
three.js copied to clipboard

Scene: Add background blur.

Open Mugen87 opened this issue 3 years ago • 8 comments

Related issue: -

Description

We have tried to integrate background blurriness in the past (e.g. #20463), however the approach at that time wasn't right. This one uses textureCubeLodEXT()/textureLod() to retrieved blurred samples of the configured environment map.

The PR introduces WebGLRenderer.setBackgroundBlurriness() which accepts values in the [0,1] range. Because textureCubeLodEXT()/textureLod() relies on mipmapping, the environment map has to set generateMipmaps to true and also use LinearMipmapLinearFilter.

Important: The configuration of the environment map has to be done on app level and can't be changed in WebGLBackground. That's because equirectangular textures are internally converted to cube map render targets and it is not possible to change render target texture parameters after their creation right now, see #14375.

Mugen87 avatar Mar 12 '22 16:03 Mugen87

Thank you for working on this!

If scene.background were a cubemap, could/should that be used instead?

I might suggest naming this parameter blur instead of blurriness. Easier to remember, and matches Blender. :)

donmccurdy avatar Mar 12 '22 17:03 donmccurdy

If scene.background were a cubemap, could/should that be used instead?

That would work, too.

I might suggest naming this parameter blur instead of blurriness. Easier to remember, and matches Blender. :)

I'm fine with a different notation. Your suggestion would lead to:

blurriness -> blur
setBackgroundBlurriness() -> setBackgroundBlur()
getBackgroundBlurriness() -> getBackgroundBlur()

Mugen87 avatar Mar 12 '22 20:03 Mugen87

Updated the PR as suggested and marked it as "Ready for Review".

Mugen87 avatar Mar 16 '22 08:03 Mugen87

I wouldn't add that to WebGLRenderer...

I think, ideally... it would be something like this:

scene.background = new THREE.TextureBackground( texture ); // new THREE.ColorBackground( color )
scene.background.blur = 0.5;

But, maybe in the meantime we can just do...

scene.backgroundBlur = 0.5;

mrdoob avatar Mar 16 '22 18:03 mrdoob

Sounds good! Let me update the PR.

Mugen87 avatar Mar 16 '22 21:03 Mugen87

@mrdoob Would you be more comfortable with merging this PR if I give TextureBackground a shot? 😇

Regarding #17420, do we need the distinction between TextureBackground and CubeTextureBackground? It seems a property like fit only applies to TextureBackground but something like rotation (see #16328) only to a skybox.

Mugen87 avatar Mar 25 '22 08:03 Mugen87

Just wanted to reference this forum discussion here regarding the "perceived smoothness" of the background when using regular mipmaps vs. when using the mipmaps from PMREM. I've often seen game engines actually use the latter because it leads to smoother appearance (less jagged/pixelated) at medium desired blurriness values. At full blurriness=1 it doesn't make a difference. https://discourse.threejs.org/t/ability-to-reuse-the-pmrem-generated-texture-from-scene-environment/37752

hybridherbst avatar May 03 '22 11:05 hybridherbst

BTW: If we decide to use PMREM for background blurriness, we can use (parts of) #20463. I've started to use PMREM since BabylonJS does it the same way.

Mugen87 avatar Jul 28 '22 08:07 Mugen87

Seems #20463 has landed (as part of #22178) - think it would make sense to use PMREM for background blurriness then and continue here?

hybridherbst avatar Oct 03 '22 08:10 hybridherbst

I would be fine with that. However, @WestLangley had objections against the PMREM solution (see https://github.com/mrdoob/three.js/issues/20115#issuecomment-675644813). I would only rewrite the PR if he agrees on PMREM, too.

Mugen87 avatar Oct 03 '22 09:10 Mugen87

I see. Copying in the images from my post above fo quicker comparison here.

Blurriness with just mipmaps Blurriness with PMREM
image image

My opinion would be that neither are perfect (would need to sample more times to get perfectly smooth results), but PMREM gets closer to the desired goal of "smooth blur" while just mipmaps leave non-smooth jagged edges.

hybridherbst avatar Oct 03 '22 13:10 hybridherbst

However, @WestLangley had objections against the PMREM solution (see https://github.com/mrdoob/three.js/issues/20115#issuecomment-675644813). I would only rewrite the PR if he agrees on PMREM, too.

I appreciate that, @Mugen87, but I don't want to be a blocker...so I won't be.

Still, I think the blurry background should be computed once in a high-quality pre-processing step -- or by the user, offline.

Is that workflow somehow not acceptable?

WestLangley avatar Oct 03 '22 17:10 WestLangley

Is that workflow somehow not acceptable?

TBH, I don't think it's worth adding a new code path if we can use the existing PMREM implementation. Even if the quality would be slightly better. Other engines (Unity, BabylonJS) use PMREM as well. It should be good enough.

I suggest to start with PMREM and a new Scene property. I just want to finally see blurred backgrounds in three.js. We can easily have it now and optimize it later (if necessary).

Mugen87 avatar Oct 06 '22 09:10 Mugen87

I have filed a fresh PR with the PMREM solution. Closing this one.

Mugen87 avatar Oct 06 '22 09:10 Mugen87