-
Notifications
You must be signed in to change notification settings - Fork 89
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
Add tonemapper that hashes to a random color #234
base: master
Are you sure you want to change the base?
Conversation
5f7a741
to
8a0a3ca
Compare
Hi Andrew, thanks a bunch for the contribution! This sounds neat to have (though I didn't test it yet). Could you also implement a CPU-side version of the tonemap in |
0e192b3
to
4258fec
Compare
Hello again Thomas, Sorry for the delay. I have been tinkering with hash functions. You were correct to be concerned about deviations in the hash function behavior. I have updated the branch with two possible solutions, one in each commit. The first commit changes the original hash function up a bit and replaces the The second commit replaces the original function with an implementation of PCG3D from the Jarzynski and Olano. This gives me rock-solid matching results between the CPU-side and the GPU-side when using the GLSL backend, even with crazy exposures like +40 or -40. Nor does the hash break down at those exposures. However, I do see differing hashed colors with the GLES backend. The downside of this option was that I had to bump the ubershader to GLSL 3.3/3.0 ES to use If you prefer the second option, I'm happy to rework this branch to split the bumping of the ubershader language version from the addition of the hash tonemapper. (I'd also understand if you wish to decline this PR at this time.) |
Hi Andrew, thank you very much for the follow-up. That's so much extra effort you've expended! In a vacuum I'd prefer the PCG solution, but you bring up the downsides yourself... I'm really hesitant to bump GL and GLES versions since some people use tev on ancient machines (or, say, VMs with virtual drivers that only support ancient GL / GLES versions). Plus, the discrepancy you report between GLES and GL bothers me more than the exposure limits on the "tamer" hash function you came up with. Long story short: I'd love to go with your first proposed option. I don't think it's a big deal that the hash function breaks down at very low or very high exposures -- at least for the purposes that you initially implemented the hash tonemap for -- and there seems to be no other downside from your description. Once again, thanks for all the time you put into this. Lmk once the PR is updated to reflect what you'd like me to merge! |
6274f3c
to
1964b05
Compare
Hi Tom, I think it's now in a good state for reviewing, testing, and merging. Compared to my last go-round:
|
Hi Andrew, thanks once again for the thorough revision! I was about to merge, but while testing I noticed that mip mapping ruins the effect of the hash function if the zoom level is even slightly below 1. The obvious fix would be to disable all texture interpolation while hash tonemapping is enabled, but this turns out to involve changes to nanogui internals which weren't programmed with dynamically changing texture parameters in mind. I'm happy to make those changes myself, but don't yet know when I'll get to it. (FWIW: I also considered explicit shader-side LoD selection & clamping to texel centers, but GLES 2.0 sadly doesn't support this.) |
Thanks, Thomas. I'll confess that when testing, I'd mostly been using either 1:1 pixels, or zoomed in on my test images, rather than zoomed out. In any event, there's no rush. I'm happy to keep this PR open as long as needed. (I usually build this tool from source rather than use the pre-built releases,, so building it from my own branch is no problem until then.) |
Hi Thomas,
Thanks for this fantastic image viewer. I have gotten a lot of use out of it over the last few years.
This PR adds a new tonemapping option that simply hashes input values to random(ish) colors.
Rationale:
My primary motivation was in viewing uint id channels (e.g., obj id, prim id, or mat id), where it's useful to show a solid block of color for each id but to decorrelate the colors of adjacent id values. However, in testing it on non-id images, I found that it was also useful for revealing regions of constant color -- in particular clipped blacks and whites on LDR images.
Hash:
The hash function itself is based on a popular hash function for shaders floating around on the web. I have modified it to map a vec3 to a vec3. I have also replaced the constants with random floating point values whose mantissas are prime numbers with not-too-clumpy bit patterns (no three 0's or 1's in a row), just to add what I hope is a bit better mixing.
I would have preferred to have used one of the better hash functions from this JCGT paper, but I also did not want to add a dependency on a shader version that supports something like floatBitsToUint(). For a simple visual decorrelation, I think this is sufficient.
Testing:
I have tested this both on an NVIDIA card under Fedora (KDE Plasma on Wayland) with the OpenGL and GLES backends, and on AMD integrated graphics under Windows (Ubuntu on WSL2) with just the OpenGL backend.
I have not tested it on native Windows with MSVC, nor on a Mac with Metal. However, I have tried to match the style of the rest of the Metal shader, so hopefully it just works.