I am trying to render a smooth gradient from 0% to 10% gray across the screen of Asus Rog Phone 2 which supposedly has an HDR10 screen. In standard (8bit?) rendering mode I can clearly see banding between the gradient levels.
I followed the instructions from Android to modify the Vulkan tutorial sample code in the following way:
- Added
android:colorMode="wideColorGamut
to AndroidManifest.xml. - Changed
VkSwapchainCreateInfoKHR.imageFormat
,VkAttachmentDescription.format
andVkImageViewCreateInfo.format
toVK_FORMAT_R16G16B16A16_SFLOAT
(everything to setup swapchain). - Changed
VkSwapchainCreateInfoKHR.imageColorSpace
toVK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT
.
I render the gradient dynamically in a custom fragment shader as a function of texturing coordinates mapped to a full-screen quad:
layout (location = 0) in vec2 texcoord;
layout (location = 0) out vec4 uFragColor;
void main() {
uFragColor = vec4(vec3(texcoord.x*0.1), 1.0);
}
As a result I observe absolutely no difference from the original 8bit(?) mode. I am not quite sure how to debug it and what to try.
I also tried to implement the same effect in Unity with HDR options enabled. There I see that all the intermediate rendering passes (in Forward mode) render to Float16 but the last extra pass likely converts it into RGB8. The visual result is the same banding again.
This makes me wonder whether this is not caused by some missing setting. In another thread I saw discussion of Window.setFormat(PixelFormat) or SurfaceHolder.setFormat(PixelFormat) but I am not sure how this related to a Native Android app. I cannot see a way how to call such function and I am not even sure if it would make sense.
Thank you for any suggestions.