Coder Social home page Coder Social logo

Comments (13)

hybridherbst avatar hybridherbst commented on June 14, 2024 2

After a bit of thinking I believe fixing this would be good:

  • if one was happy with the previous quality, the image resolution can now be halved at basically no loss in quality.
  • otherwise, one gets higher quality backgrounds without having to do anything, at the expense of some memory.

I agree there is a risk that someone was using 4k backgrounds before to offset the extra blur that a 2k background introduced (I certainly did that in a number of projects), and memory requirements are now 4x. But the fix is easy, just not use 4k in that case, reaching the desired 2k quality.

from three.js.

elalish avatar elalish commented on June 14, 2024 2

@hybridherbst is a significant <model-viewer> user and I generally trust his judgement, so this change is probably good. I'll admit to being a bit surprised though - a cubemap with height/2 seems like it should have very similar pixel density to an equirect of height. Is this because of HDR interpolation happening in linear space? Or just out toward the corners of the cube?

It would be nice if we had a standard cubemap image format so we didn't need to worry about all these conversions. Is KTX2 a possibility?

from three.js.

hybridherbst avatar hybridherbst commented on June 14, 2024 1

Well, the end result is that the background is blurrier than it should be given the provided texture – we had a number of people complain about that so I'd certainly like to understand better how to fix it. "Just don't use .background, make a sphere" doesn't sound very usable.

Converting an equirect texture to a cubemap does not inherently make it blurrier (e.g. it doesn't in Unity).

from three.js.

Mugen87 avatar Mugen87 commented on June 14, 2024 1

When I remember correctly, in earlier days examples often used a fixed size to convert equirectangular env maps to the cube map format. E.g.

scene.background = new THREE.WebGLCubeRenderTarget( 512 ).fromEquirectangularTexture( renderer, texture );

#19911 introduced the image.height / 2 pattern which seems to be a good compromise between memory allocation and quality. Not sure about the performance implications when the engine would always use e.g. image.height as the cube render target's size.

from three.js.

donmccurdy avatar donmccurdy commented on June 14, 2024 1

KTX2Loader cannot load float16 or float32 cubemaps at this point, see #26642 (comment). It does support LDR cubemaps (with Basis Universal compression), so it'd work for scene.background but not scene.environment.

from three.js.

Mugen87 avatar Mugen87 commented on June 14, 2024

GroundedSkybox displays the equirectangular dikhololo_night_2k.hdr directly onto a sphere mesh.

When applying this texture to Scene.background, the texture is converted to the cube map format (assuming you use no background blurriness). That's because the internal env map shaders do not support the ENVMAP_TYPE_EQUIREC anymore. The mipmap and texture filter settings are retained during the conversion process.

So we comparing two different env map techniques here and it's not surprising to see slightly different results.

from three.js.

Mugen87 avatar Mugen87 commented on June 14, 2024

Do you get better results if you increase the resolution of the internal cube render target here?

const renderTarget = new WebGLCubeRenderTarget( image.height / 2 );
renderTarget.fromEquirectangularTexture( renderer, texture );

from three.js.

hybridherbst avatar hybridherbst commented on June 14, 2024

Yes, indeed, then the results look much better – I believe Unity always uses the full height (and not height / 2) for this operation too.

Pixel counts:

    2048 x 1024 = 2.097.152
6 x  512 x  512 = 1.572.864 (undersampled – will lose a lot of quality)
6 x 1024 x 1024 = 6.291.456 (oversampled at more than 2x – will not lose quality)

from three.js.

hybridherbst avatar hybridherbst commented on June 14, 2024

An interesting alternative might be doing regular or rotated-grid supersampling in the fromEquirectangularTexture fragment shader – tapping the source texture multiple times on distortions can mitigate undersampling problems.

from three.js.

Mugen87 avatar Mugen87 commented on June 14, 2024

Just updating the size of the cube map would at least be an easy fix^^. Still unsure about the performance implications though.

I don't know how the supersampling approach works out but I wonder if you would be happy with a "slightly" better result compared to using a cube render target with higher size that provides an optimal result.

from three.js.

hybridherbst avatar hybridherbst commented on June 14, 2024

True that! I'm not sure if the shader-based solution can achieve similar quality, it's just something I've used in the past for crisper text rendering and such cases...

from three.js.

Mugen87 avatar Mugen87 commented on June 14, 2024

Some memory allocation data for comparison:

RGBA8:

EquiRect: 2048 x 1024 x 4 (RGBA) x UNSIGNED_BYTE = 8.388.608 BYTE 
CubeMap: 6 x  512 x  512 x 4 (RGBA) x UNSIGNED_BYTE = 6.291.456 BYTE
CubeMap: 6 x 1024 x 1024 x 4 (RGBA) x UNSIGNED_BYTE = 25.165.824 BYTE

FP16 (HDR):

EquiRect: 2048 x 1024 x 4 (RGBA) x HALF_FLOAT = 16.777.216 BYTE 
CubeMap: 6 x  512 x  512 x 4 (RGBA) x HALF_FLOAT = 12.582.912 BYTE
CubeMap: 6 x 1024 x 1024 x 4 (RGBA) x HALF_FLOAT = 50.331.648 BYTE

The additional required memory for 1024 x 1024 is quite a bit. However, the improvement in quality is noticeable.

@elalish What would you recommend from <model-viewer> perspective? Can low end mobile devices afford the additional memory and bandwidth cost?

from three.js.

elalish avatar elalish commented on June 14, 2024

Thanks for the info! I hear Binomial is doing some work on HDR compression, so maybe this'll get improved soon.

from three.js.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.