From 4c9a55087bcfd56d63432e7b3dde409162812870 Mon Sep 17 00:00:00 2001 From: Ahan Wu Date: Mon, 4 Mar 2019 15:35:28 +0800 Subject: [PATCH] Using linear interpolation in fragment shader to avoid over saturation. The color of wallpaper is over saturated after remapping in the fragment shader so we also apply linear interpolation between original color and remapped color to avoid over saturation. In addition, we also add some comments, which is offered by UX, to fragment shader, thanks the great help of Vignesh! Bug: 126500189 Bug: 123615467 Test: Manually set wallpaper, compare the saturation of the image between wallpaper and wallpaper picker. Change-Id: Ibc063dfbc880c9b7dce8bec33fa2fd189ecf7d72 --- .../raw/image_wallpaper_fragment_shader.glsl | 61 +++++++++++++++++-- .../glwallpaper/ImageGLWallpaper.java | 10 +-- .../glwallpaper/ImageWallpaperRenderer.java | 4 +- 3 files changed, 62 insertions(+), 13 deletions(-) diff --git a/packages/SystemUI/res/raw/image_wallpaper_fragment_shader.glsl b/packages/SystemUI/res/raw/image_wallpaper_fragment_shader.glsl index 586cdf3fbaaea..716e1272f8719 100644 --- a/packages/SystemUI/res/raw/image_wallpaper_fragment_shader.glsl +++ b/packages/SystemUI/res/raw/image_wallpaper_fragment_shader.glsl @@ -1,27 +1,76 @@ precision mediump float; +// The actual wallpaper texture. uniform sampler2D uTexture; -uniform float uCenterReveal; + +// The 85th percenile for the luminance histogram of the image (a value between 0 and 1). +// This value represents the point in histogram that includes 85% of the pixels of the image. +uniform float uPer85; + +// Reveal is the animation value that goes from 1 (the image is hidden) to 0 (the image is visible). uniform float uReveal; + +// The opacity of locked screen (constant value). uniform float uAod2Opacity; varying vec2 vTextureCoordinates; +/* + * Calculates the relative luminance of the pixel. + */ vec3 luminosity(vec3 color) { float lum = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b; return vec3(lum); } vec4 transform(vec3 diffuse) { - // TODO: Add well comments here, tracking on b/123615467. + // Getting the luminance for this pixel vec3 lum = luminosity(diffuse); - diffuse = mix(diffuse, lum, smoothstep(0., uCenterReveal, uReveal)); - float val = mix(uReveal, uCenterReveal, step(uCenterReveal, uReveal)); - diffuse = smoothstep(val, 1.0, diffuse); - diffuse *= uAod2Opacity * (1. - smoothstep(uCenterReveal, 1., uReveal)); + + /* + * while the reveal > per85, it shows the luminance image (B&W image) + * then when moving passed that value, the image gets colored. + */ + float trans = smoothstep(0., uPer85, uReveal); + diffuse = mix(diffuse, lum, trans); + + // 'lower' value represents the capped 'reveal' value to the range [0, per85] + float selector = step(uPer85, uReveal); + float lower = mix(uReveal, uPer85, selector); + + /* + * Remaps image: + * - from reveal=1 to reveal=per85 => lower=per85, diffuse=luminance + * That means that remaps black and white image pixel + * from a possible values of [0,1] to [per85, 1] (if the pixel is darker than per85, + * it's gonna be black, if it's between per85 and 1, it's gonna be gray + * and if it's 1 it's gonna be white). + * - from reveal=per85 to reveal=0 => lower=reveal, 'diffuse' changes from luminance to color + * That means that remaps each image pixel color (rgb) + * from a possible values of [0,1] to [lower, 1] (if the pixel color is darker than 'lower', + * it's gonna be 0, if it's between 'lower' and 1, it's gonna be remap to a value + * between 0 and 1 and if it's 1 it's gonna be 1). + * - if reveal=0 => lower=0, diffuse=color image + * The image is shown as it is, colored. + */ + vec3 remaps = smoothstep(lower, 1., diffuse); + + // Interpolate between diffuse and remaps using reveal to avoid over saturation. + diffuse = mix(diffuse, remaps, uReveal); + + /* + * Fades in the pixel value: + * - if reveal=1 => fadeInOpacity=0 + * - from reveal=1 to reveal=per85 => 0<=fadeInOpacity<=1 + * - if reveal>per85 => fadeInOpacity=1 + */ + float fadeInOpacity = 1. - smoothstep(uPer85, 1., uReveal); + diffuse *= uAod2Opacity * fadeInOpacity; + return vec4(diffuse.r, diffuse.g, diffuse.b, 1.); } void main() { + // gets the pixel value of the wallpaper for this uv coordinates on screen. vec4 fragColor = texture2D(uTexture, vTextureCoordinates); gl_FragColor = transform(fragColor.rgb); } \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java index 19d85b155cbac..a313336e3d712 100644 --- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java +++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java @@ -50,7 +50,7 @@ class ImageGLWallpaper { static final String A_POSITION = "aPosition"; static final String A_TEXTURE_COORDINATES = "aTextureCoordinates"; - static final String U_CENTER_REVEAL = "uCenterReveal"; + static final String U_PER85 = "uPer85"; static final String U_REVEAL = "uReveal"; static final String U_AOD2OPACITY = "uAod2Opacity"; static final String U_TEXTURE = "uTexture"; @@ -87,7 +87,7 @@ class ImageGLWallpaper { private int mAttrPosition; private int mAttrTextureCoordinates; private int mUniAod2Opacity; - private int mUniCenterReveal; + private int mUniPer85; private int mUniReveal; private int mUniTexture; private int mTextureId; @@ -131,7 +131,7 @@ class ImageGLWallpaper { private void setupUniforms() { mUniAod2Opacity = mProgram.getUniformHandle(U_AOD2OPACITY); - mUniCenterReveal = mProgram.getUniformHandle(U_CENTER_REVEAL); + mUniPer85 = mProgram.getUniformHandle(U_PER85); mUniReveal = mProgram.getUniformHandle(U_REVEAL); mUniTexture = mProgram.getUniformHandle(U_TEXTURE); } @@ -144,8 +144,8 @@ class ImageGLWallpaper { return mAttrTextureCoordinates; case U_AOD2OPACITY: return mUniAod2Opacity; - case U_CENTER_REVEAL: - return mUniCenterReveal; + case U_PER85: + return mUniPer85; case U_REVEAL: return mUniReveal; case U_TEXTURE: diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java index 991b1161dde2d..72950088eb39a 100644 --- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java +++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java @@ -93,13 +93,13 @@ public class ImageWallpaperRenderer implements GLSurfaceView.Renderer, @Override public void onDrawFrame(GL10 gl) { - float threshold = mImageProcessHelper.getPercentile85(); + float per85 = mImageProcessHelper.getPercentile85(); float reveal = mImageRevealHelper.getReveal(); glClear(GL_COLOR_BUFFER_BIT); glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_AOD2OPACITY), 1); - glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_CENTER_REVEAL), threshold); + glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_PER85), per85); glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_REVEAL), reveal); mWallpaper.useTexture();