Skip to content

Fix precision errors in pack/unpack depth #12005

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

Merged
merged 1 commit into from
Jun 16, 2022

Conversation

jtorresfabra
Copy link
Contributor

@jtorresfabra jtorresfabra commented Jun 16, 2022

Current code is introducing precision errors in the pack/unpack depth functions by not using the correct range of values. When the packed_depth is written to R8G8B8A8 texture the maximum value it can store is 255 per channel, not 256. We were introducing errors in the third decimal in a range from 0..1. Seems this code was also wrong in three.js and other libraries, hence the confusion. Coded a godbolt to prove the issue (https://godbolt.org/z/8MrrhPh11).

Link to the original post: https://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/

This fix also helps in gl-native terrain occlusion and others.

Tested manually that the problem addresed in this commit is still fixed.

outputB

cc: @mapbox/gl-native

Launch Checklist

  • briefly describe the changes in this PR
  • include before/after visuals or gifs if this PR includes visual changes
  • manually test the debug page
  • tagged @mapbox/map-design-team @mapbox/static-apis if this PR includes style spec API or visual changes
  • tagged @mapbox/gl-native if this PR includes shader changes or needs a native port
  • apply changelog label ('bug', 'feature', 'docs', etc) or use the label 'skip changelog'
  • add an entry inside this element for inclusion in the mapbox-gl-js changelog: <changelog>Fix precision errors in depth pack/unpack</changelog>

Sorry, something went wrong.

@jtorresfabra jtorresfabra self-assigned this Jun 16, 2022
@jtorresfabra jtorresfabra force-pushed the jtorres-fix-pack-unpack-depth branch from 0ada3c9 to 1ae72f1 Compare June 16, 2022 11:09
Current code is introducing precision errors in the pack/unpack depth functions by not using the correct range of values. When the packed_depth is written to R8G8B8A8 texture the maximum value it can store is 255 per channel, not 256. We were introducing errors in the third decimal in a range from 0..1. Seems this code was also wrong in three.js and other libraries, hence the confusion. Coded a godbolt to prove the issue (https://godbolt.org/z/8MrrhPh11).

This fix also helps in gl-native terrain occlusion and shadow rendering, as otherwise artifacts are visible
@jtorresfabra jtorresfabra force-pushed the jtorres-fix-pack-unpack-depth branch from 1ae72f1 to 0d0a130 Compare June 16, 2022 11:35
@mpulkki-mapbox
Copy link
Contributor

@jtorresfabra this is great nice find! I've been investigating incoherent behavior of the depth texture in the past but never got this far. I created few charts to better understand how the encoding function works on different input. Values in the charts represents relative error of the unpacked value compared to the actual value.

Broken

image

Fixed

Fixed version of the encoding provides much better precision where the maximum deviation is ~3% in my tests. For example value close to 0.132 produces some difference. Overall the error is constrained and could be used to deduce maximum required bias value when comparing depth values.
image

@karimnaaji karimnaaji merged commit f49831e into main Jun 16, 2022
@karimnaaji karimnaaji deleted the jtorres-fix-pack-unpack-depth branch June 16, 2022 15:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants