Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dc47878f authored by Sherry Zhou's avatar Sherry Zhou
Browse files

Fix sun effect is too bright and parallax translation is not accurate

Bug: 409297176
Flag: EXEMPT, Magic Portrait only
Test: manual test

Change-Id: Iab9fdd71a314d179226cf4abf2d6129ab92719d7
parent 2a810456
Loading
Loading
Loading
Loading
+15 −6
Original line number Diff line number Diff line
@@ -30,8 +30,8 @@ uniform mat3 transformMatrixWeather;

#include "shaders/lens_flare.agsl"

const vec2 sunCenter = vec2(0.57, -0.8);
const vec3 godRaysColor = vec3(1., 0.857, 0.71428);
const vec2 sunCenter = vec2(0.67, -1.0);

float calculateRay(float angle, float time) {
    /*
@@ -94,16 +94,25 @@ float checkBrightnessGodRaysAtCenter(
}

vec4 main(float2 fragCoord) {
    float2 aspectRatioAdj = vec2(1.);
    if (screenAspectRatio > 1) {
        aspectRatioAdj.x = screenAspectRatio;
    } else {
        aspectRatioAdj.y = 1. / screenAspectRatio;
    }
    // Apply transform matrix to fragCoord
    float2 adjustedUv = transformPoint(transformMatrixBitmap, fragCoord);

    float2 uv = transformPoint(transformMatrixWeather, fragCoord) / screenSize;
    uv -= vec2(0.5, 0.5);
    uv.y /= screenAspectRatio;
    vec2 sunVariation = vec2(0.1 * sin(time * 0.3), 0.14 * cos(time * 0.5));
    sunVariation += 0.1 * (0.5 * sin(time * 0.456) + 0.5) * sunCenter / vec2(1., screenAspectRatio);
    vec2 sunPos = sunVariation + sunCenter / vec2(1., screenAspectRatio);
    //TODO(b/375214506): fix the uv position of the sun
    uv *= aspectRatioAdj;
    // Random sun variation based on sin/cos signal.
    vec2 sunVariation = 0.08 * vec2(sin(time * 0.3), cos(time * 0.5));
    // Variation that moves sun on the same direction than the vector that goes from (0,0)
    // to sunCenter, but scaling distance.
    sunVariation += 0.1 * (0.5 * sin(time * 0.456) + 0.5) * sunCenter;
    vec2 sunPos = sunVariation + sunCenter;
    sunPos *= aspectRatioAdj;

    vec4 colorForeground = foreground.eval(adjustedUv);
    vec4 color = background.eval(adjustedUv);
+32 −8
Original line number Diff line number Diff line
@@ -24,9 +24,9 @@ import android.graphics.RuntimeShader
import android.graphics.Shader
import android.util.SizeF
import com.google.android.wallpaper.weathereffects.graphics.utils.GraphicsUtils
import com.google.android.wallpaper.weathereffects.graphics.utils.MatrixUtils.calculateTransformDifference
import com.google.android.wallpaper.weathereffects.graphics.utils.MatrixUtils.calculateTranslationDifference
import com.google.android.wallpaper.weathereffects.graphics.utils.MatrixUtils.centerCropMatrix
import com.google.android.wallpaper.weathereffects.graphics.utils.MatrixUtils.getScale
import com.google.android.wallpaper.weathereffects.graphics.utils.MatrixUtils.getScaleFromMatrixValues
import com.google.android.wallpaper.weathereffects.graphics.utils.MatrixUtils.invertAndTransposeMatrix
import kotlin.random.Random

@@ -42,13 +42,22 @@ abstract class WeatherEffectBase(
            surfaceSize,
            SizeF(background.width.toFloat(), background.height.toFloat()),
        )
        set(value) {
            field = value
            value.getValues(centerCropMatrixValues)
        }

    protected var parallaxMatrix = Matrix(centerCropMatrix)
    private val centerCropMatrixValues: FloatArray =
        FloatArray(9).apply { centerCropMatrix.getValues(this) }
    private val parallaxMatrixValues: FloatArray =
        FloatArray(9).apply { parallaxMatrix.getValues(this) }
    // Currently, we use same transform for both foreground and background
    protected open val transformMatrixBitmap: FloatArray = FloatArray(9)
    // Apply to weather components not rely on image textures
    // Should be identity matrix in editor, and only change when parallax applied in homescreen
    private val transformMatrixWeather: FloatArray = FloatArray(9)
    protected var bitmapScale = getScale(centerCropMatrix)
    protected var bitmapScale = getScaleFromMatrixValues(centerCropMatrixValues)
    protected var elapsedTime: Float = 0f

    abstract val shader: RuntimeShader
@@ -57,14 +66,19 @@ abstract class WeatherEffectBase(
    abstract val colorGradingIntensity: Float

    override fun setMatrix(matrix: Matrix) {
        this.parallaxMatrix.set(matrix)
        bitmapScale = getScale(parallaxMatrix)
        this.parallaxMatrix.setAndUpdateFloatArray(matrix, parallaxMatrixValues)
        bitmapScale = getScaleFromMatrixValues(parallaxMatrixValues)
        adjustCropping(surfaceSize)
    }

    /** This function will be called every time parallax changes, don't do heavy things here */
    open fun adjustCropping(newSurfaceSize: SizeF) {
        invertAndTransposeMatrix(parallaxMatrix, transformMatrixBitmap)
        calculateTransformDifference(centerCropMatrix, parallaxMatrix, transformMatrixWeather)
        calculateTranslationDifference(
            centerCropMatrixValues,
            parallaxMatrixValues,
            transformMatrixWeather,
        )
        shader.setFloatUniform("transformMatrixBitmap", transformMatrixBitmap)
        shader.setFloatUniform("transformMatrixWeather", transformMatrixWeather)
        shader.setFloatUniform("screenSize", newSurfaceSize.width, newSurfaceSize.height)
@@ -75,6 +89,11 @@ abstract class WeatherEffectBase(

    override fun resize(newSurfaceSize: SizeF) {
        surfaceSize = newSurfaceSize
        centerCropMatrix =
            centerCropMatrix(
                surfaceSize,
                SizeF(background.width.toFloat(), background.height.toFloat()),
            )
        adjustCropping(newSurfaceSize)
        updateGridSize(newSurfaceSize)
    }
@@ -113,8 +132,8 @@ abstract class WeatherEffectBase(
                surfaceSize,
                SizeF(background.width.toFloat(), background.height.toFloat()),
            )
        parallaxMatrix.set(centerCropMatrix)
        bitmapScale = getScale(centerCropMatrix)
        parallaxMatrix.setAndUpdateFloatArray(centerCropMatrix, parallaxMatrixValues)
        bitmapScale = getScaleFromMatrixValues(centerCropMatrixValues)
        shader.setInputBuffer(
            "background",
            BitmapShader(this.background, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR),
@@ -139,6 +158,11 @@ abstract class WeatherEffectBase(
        )
    }

    private fun Matrix.setAndUpdateFloatArray(src: Matrix, targetFloatArray: FloatArray) {
        set(src)
        src.getValues(targetFloatArray)
    }

    companion object {
        // When extracting the scale from the parallax matrix, there will be a very small difference
        // due to floating-point precision.
+51 −0
Original line number Diff line number Diff line
@@ -55,6 +55,10 @@ object MatrixUtils {
        return matrixValues[0]
    }

    fun getScaleFromMatrixValues(matrixValuesArray: FloatArray): Float {
        return matrixValuesArray[0]
    }

    /**
     * Calculates the transformation matrix that, when applied to `originMatrix`, results in
     * `targetMatrix`. Current use case: Calculating parallax effect for the homescreen compared
@@ -77,6 +81,53 @@ object MatrixUtils {
        return transposeMatrixArray(matrixValues, outArray)
    }

    /**
     * Calculates the difference in translation between two transformation matrices, represented as
     * FloatArrays (`centerCropMatrixValues` and `parallaxMatrixValues`), after scaling
     * `parallaxMatrixValues` to match the scale of `centerCropMatrixValues`. The resulting
     * translation difference is then stored in the provided `outArray` as a 3x3 translation matrix
     * (in column-major order).
     *
     * @param centerCropMatrixValues A FloatArray of length 9 representing the reference
     *   transformation matrix (center-cropped view) in row-major order.
     * @param parallaxMatrixValues A FloatArray of length 9 representing the transformation matrix
     *   whose translation difference relative to `centerCropMatrixValues` is to be calculated, also
     *   in row-major order. This array will be scaled to match the scale of
     *   `centerCropMatrixValues`.
     * @param outArray A FloatArray of length 9 to store the resulting 3x3 translation matrix. The
     *   translation components (deltaX, deltaY) will be placed in the appropriate positions for a
     *   column-major matrix.
     */
    fun calculateTranslationDifference(
        centerCropMatrixValues: FloatArray,
        parallaxMatrixValues: FloatArray,
        outArray: FloatArray,
    ): FloatArray {
        val scaleX = centerCropMatrixValues[0] / parallaxMatrixValues[0]
        val scaleY = centerCropMatrixValues[4] / parallaxMatrixValues[4]

        val scaledParallaxTransX = parallaxMatrixValues[2] * scaleX
        val scaledParallaxTransY = parallaxMatrixValues[5] * scaleY

        val originTransX = centerCropMatrixValues[2]
        val originTransY = centerCropMatrixValues[5]

        val deltaTransX = originTransX - scaledParallaxTransX
        val deltaTransY = originTransY - scaledParallaxTransY

        outArray[0] = 1f
        outArray[1] = 0f
        outArray[2] = 0f
        outArray[3] = 0f
        outArray[4] = 1f
        outArray[5] = 0f
        outArray[6] = deltaTransX
        outArray[7] = deltaTransY
        outArray[8] = 1f

        return outArray
    }

    // Transpose 3x3 matrix values as a FloatArray[9], write results to outArray
    private fun transposeMatrixArray(inMatrixArray: FloatArray, outArray: FloatArray): FloatArray {
        for (i in 0 until 3) {