-
-
Notifications
You must be signed in to change notification settings - Fork 35.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PMREMGenerator: set internal/output render targets as RGBE. #19087
Conversation
If we decide to merge, it is important to notify on changelogs about the default output type changing. |
I think |
I'm ok with that, @elalish would that cause any problems that we are not considering? |
Tested on my Android phone Huawei Mate 10 Pro, purchased in 2018 for around 600 USD? So not the best but not budget either. Firefox and Chrome browsers fail both examples. UI renders, but the 3D content appears black. |
@sciecode @WestLangley It's true you could avoid Also, why do you expect iphones to fail your halfFloat test? It seems like we should test this on quite a few devices before making this change. Oh, and what exactly is the change to the default output type? |
iPhones don't seem to be able to decode
Previously the default behavior was to copy input texture parameters, in the current state it defaults to |
@sciecode Wait, hold on, I didn't grok this the first time through. If you set data type to float, you're changing all the render targets to float type, which doesn't work on most mobile devices. I thought the idea here was to just accept float input and still use the same 8-bit internal formats for compatibility. |
Well, the idea was to increase support. Let me explain. With dev version, PMREM only works on mobile if we input an RGBE 8-bit texture that outputs to RGBE as well. In other words, we are increasing the support of inputted texture formats, not outputted. If we want to output as |
How do you feel about this?
In the case of 3(a), I discussed this offline with @sciecode, and I think we agree that this makes sense. Any "gotchas" we are missing? |
@WestLangley 1 and 2 sound good. Number 3b has the same gotchas as number 2; in order to output a float texture you have to be able to render to a float texture, which mobiles can't reliably do. And in order to make use of linear filtering you'll need to change the cube_uv shader fragment to remove the custom interpolation. Hence my suggestion to save those for later and always go with 3a for now. |
@elalish Why not create a float data texture and populate it from the RGBE Uint internal render target? |
@WestLangley Do you mean by going through the CPU? Or is there another way to convert from RGBE to float texture without writing to a renderbuffer? I may just be unaware. |
Ok, I understand now. Now your comment about using hardware lerp vs shader lerp makes more sense to me. In that case, I say let's go with your proposal (1), (2) and (3a). I can study the impact of using |
I think this one is good to go, aye? 👍 |
As I proposed in #19087 (comment), I would only output |
@WestLangley @sciecode Sorry, but I again have to disagree here; I would approve this without the last commit this comment added. If we have input in an 8-bit nonlinear encoding (sRGB or Gamma), and we encode it as 8-bit linear, we get significant quantization loss. I know it would be nice to not convert back and forth all the time, but without writing floats, there's just not a good way around it. |
Let's just shake on |
@sciecode Is there a chance you pasted the same image twice? |
Nope, I can see clearly the "salt and pepper" difference in the Linear one. Especially on the darker street area. I do have a very high contrast on my monitor, try adjusting a bit in yours and I guarantee you're gonna see it. |
A couple years ago I quantified the loss when going from gamma to linear in a 256 byte wide color space: You start with 256 unique intensities and end up with just 184. See above spreadsheet. The trick is to not re-encode these from gamma to linear in 8-bit per channel textures, but rather do inline decoding. I had made this spreadsheet to communicate how evil the GammaPass was -- because it took as input one 8-bit per channel texture and converted it to another 8-bit per channel texture. Instead one should do inline gamma encoding when the value is still in its full range float format. The same rule applies to decoding. |
@bhouston thanks for the input. When you say inline decoding, you mean directly on the shader when reading the target texture correct? |
Yes, I mean that if you have an sRGB texture, leave it in sRGB format until you are in the shader itself, then decode it directly to floating point values. If you rencode an 8-bit sRGB texture into a 8-bit linear texture, you've just lost 25% of your possible color values, thus you lost you lost accuracy. The same goes for any conversion between sRGB, gamma and linear - never do this unnecessarily between 8-bit per channel textures. |
Thank you everybody. @elalish Please correct if it is still not what you support. Revised specification:
|
@WestLangley Yes, agreed. |
6d4b57c
to
3232a67
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for bearing with me!
Thank you guys ❤️ |
@mrdoob We have consensus! :-) |
And we will be not support the RGBM-encoded PNG workflows going forward right? Like this old example supports: https://threejs.org/examples/#webgl_materials_envmaps_hdr I am okay with this personally. |
Well, depends what you mean by support, PMREMGenerator can correctly read RGBM and output a readable render target, the only difference is that the output will be in RGBE instead of RGBM. |
Good enough for me. I support this consensus. This is a greatly simplification and imposition of smart best practice. |
@mrdoob /bump |
Anything in specific holding this PR back, @mrdoob? I know there's been a lot discussion, but I can try to summarize what's been discussed in order to make it easier to review. Current In order to allow broader use of input textures on all devices, we now enforce Hopefully this helps. |
Thanks everyone! 🙏 |
Fixes #19053
Based on #19053 (comment) and #19053 (comment)
This PR introduces the possibility for the output texture generated by PMREM to have different type than the inputted texture. This is important for mobile support, which often lacks the ability to render to floating point textures.See #19087 (comment) and #19087 (comment)