Heightmap compression in VRAM #615
Xtarsia
announced in
Architecture
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Absoltley none of this would be required if desktop GPU manufacturers implementd ASTC/EAC support etc, as those formats contain HDR single channel float32 block compression standards, that are superior this my rudimentry implementation here... oh well!
Compression algorithm, currently in gdscript, pretty much a BC4 implementation:
next a decode function in the shader:
testing mipmaps, the mip value insidedecompressFetch() for each texelFetch should be manually set to 0 when testing, due to not actually using mipmaps.
decompressing in gdscript, currently decompresses the entire image, however if someone were to use compressed mode in an exported game, and wanted to use get_height() it should be reasonable to use a similar approach as the shader decoder to do the exact same thing CPU side.
a comparison function, due to the min and max values being stored losslessly, data is only lost on the remaining 14 pixels of any 4x4 block. which means saving using this mode, decompressing, editing, and re-compressing on save is "lossless" in a rough sense, as the endpoints for any given block are themselves lossless. So we could reduce file sizes a bit when loading / saving regions potentially.
some initial comparisions for what would be mip0, with a potential 75% filesize, RAM and VRAM reduction!
1st pass from true source, to compressed:
96% of pixels having an error of less than 15cm is pretty great, and almost 80% being accurate to 5cm.
less than 1mm accuracy is garenteed for 12.5% as 2 out of every 16 pixels are the end points, higher % likley is down to very flat and smooth portions of the map.
Recompressing, and decompressing results in perfect back and forth:
demoing 256kb per region "mipmap":
![image](https://private-user-images.githubusercontent.com/69606701/410450311-c1879b12-33e0-4d07-acac-b0d2d763ece8.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzkyOTAxODgsIm5iZiI6MTczOTI4OTg4OCwicGF0aCI6Ii82OTYwNjcwMS80MTA0NTAzMTEtYzE4NzliMTItMzNlMC00ZDA3LWFjYWMtYjBkMmQ3NjNlY2U4LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjExVDE2MDQ0OFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWNiNTEzMzU5MmJiZDRjYjI1OTY4MDEyNGQ2YTNmYTk1ZGJhZGJkNGFkZTBhMWJjZDFhZWJkNmI1M2YyYWJjOGMmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.vUExwqvywj7vVic1XkFwIgS1G3_W94wvPKlj7WRMHMA)
and the full size, compressed "mip0":
![image](https://private-user-images.githubusercontent.com/69606701/410452030-d83dcfe8-3291-45c7-8311-73cfabe0d593.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzkyOTAxODgsIm5iZiI6MTczOTI4OTg4OCwicGF0aCI6Ii82OTYwNjcwMS80MTA0NTIwMzAtZDgzZGNmZTgtMzI5MS00NWM3LTgzMTEtNzNjZmFiZTBkNTkzLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjExVDE2MDQ0OFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWQwZjQyYTdiOGRiZWU3Yjc2MjEzNzlkZjU1NGJkZGJkNGQwZGQxNjNkZTk2N2E4M2U4OWMzMjBlYzNiZWUyOGEmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.7gJflYnryrXclFy1omsgCr0EZk8PgjWFvXPTDnjkceA)
Final note: Selecting the correct mipmap manually in fragment, can be done by modifying the lookup offsets, and calculating following (pending potential better methods?):
For vertex, we can use the scale, derived from the MODEL_MATRIX[0] component, to determine the LOD level, -1.0 can be increased as a sort of LOD bias if desired:
Beta Was this translation helpful? Give feedback.
All reactions