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

Commit 5edfd952 authored by Sherry Zhou's avatar Sherry Zhou
Browse files

Fix sun effect starting at a wrong position in Magic Portrait editor

Refactor transform matrix calculation in weather effects

Bug: 375272898
Flag: EXEMPT only change in Magic Portrait
Test: manual test wallpaper of different sizes, sun rays are in the same
position in editor. Manual test all weather effects in editor and
applied wallpaper.

Change-Id: Ib4e114af23cab29c8644465c4b9ac498ad895099
parent 10e452e3
Loading
Loading
Loading
Loading
+4 −7
Original line number Diff line number Diff line
@@ -25,8 +25,7 @@ uniform half screenAspectRatio;
uniform half2 screenSize;
uniform half pixelDensity;
uniform half intensity;
uniform mat3 transformMatrixFgd;
uniform mat3 transformMatrixBgd;
uniform mat3 transformMatrixBitmap;
uniform mat3 transformMatrixWeather;

#include "shaders/constants.agsl"
@@ -48,15 +47,13 @@ vec4 main(float2 fragCoord) {
     * - Foreground
     * - fgdFogFar (layer 1) / fgdFogClose (layer 2)
     */

    float2 fgdCoord = transformPoint(transformMatrixFgd, fragCoord);
    float2 bgdCoord = transformPoint(transformMatrixBgd, fragCoord);
    float2 adjustedCoord = transformPoint(transformMatrixBitmap, fragCoord);
    float2 uv = transformPoint(transformMatrixWeather, fragCoord) / screenSize;
    uv.y /= screenAspectRatio;

    // Load background and foreground.
    vec4 fgd = foreground.eval(fgdCoord);
    vec4 bgd = background.eval(bgdCoord);
    vec4 fgd = foreground.eval(adjustedCoord);
    vec4 bgd = background.eval(adjustedCoord);

    // Adjusts contrast and brightness.
    float noise = 0.025 * triangleNoise(fragCoord.xy + vec2(12.31, 1024.1241));
+6 −8
Original line number Diff line number Diff line
@@ -22,8 +22,7 @@ uniform float screenAspectRatio;
uniform float gridScale;
uniform float2 screenSize;
uniform half intensity;
uniform mat3 transformMatrixFgd;
uniform mat3 transformMatrixBgd;
uniform mat3 transformMatrixBitmap;
uniform mat3 transformMatrixWeather;

#include "shaders/constants.agsl"
@@ -56,9 +55,9 @@ vec3 drawSplashes(vec2 uv, vec2 fragCoord, vec3 color) {
    vec2 pixUv = cellUv;
    pixUv.x *= -1;
    vec2 pixDistance = screenSize * pixUv / gridSize;
    float2 uvTextureFgd =  transformPoint(transformMatrixFgd, fragCoord + pixDistance);
    float2 uvTexture =  transformPoint(transformMatrixBitmap, fragCoord + pixDistance);

    float outline = step(0.1, outlineBuffer.eval(uvTextureFgd).r);
    float outline = step(0.1, outlineBuffer.eval(uvTexture).r);
    if (outline < 0.1) {
        // Simply return the given color when it's not considered as an outline.
        return color;
@@ -81,13 +80,12 @@ vec3 drawSplashes(vec2 uv, vec2 fragCoord, vec3 color) {

vec4 main(float2 fragCoord) {
    // Apply transform matrix to fragCoord
    float2 uvTextureFgd = transformPoint(transformMatrixFgd, fragCoord);
    float2 uvTextureBgd = transformPoint(transformMatrixBgd, fragCoord);
    float2 uvTexture = transformPoint(transformMatrixBitmap, fragCoord);
    // Calculate uv for snow based on transformed coordinates
    float2 uv = transformPoint(transformMatrixWeather, fragCoord) / screenSize;

    vec4 colorForeground = foreground.eval(uvTextureFgd);
    vec4 color = background.eval(uvTextureBgd);
    vec4 colorForeground = foreground.eval(uvTexture);
    vec4 color = background.eval(uvTexture);

    // Adjusts contrast and brightness.
    float noise = 0.025 * triangleNoise(fragCoord.xy + vec2(12.31, 1024.1241));
+5 −7
Original line number Diff line number Diff line
@@ -22,8 +22,7 @@ uniform float2 gridSize;
uniform float time;
uniform float screenAspectRatio;
uniform float2 screenSize;
uniform mat3 transformMatrixFgd;
uniform mat3 transformMatrixBgd;
uniform mat3 transformMatrixBitmap;
uniform mat3 transformMatrixWeather;

#include "shaders/constants.agsl"
@@ -52,15 +51,14 @@ vec4 main(float2 fragCoord) {
     */

    // Apply transform matrix to fragCoord
    float2 adjustedUvForeground = transformPoint(transformMatrixFgd, fragCoord);
    float2 adjustedUvBackground = transformPoint(transformMatrixBgd, fragCoord);
    float2 adjustedUv = transformPoint(transformMatrixBitmap, fragCoord);

    // Calculate uv for snow based on transformed coordinates
    float2 uv = transformPoint(transformMatrixWeather, fragCoord) / screenSize;
    float2 uvAdjusted = vec2(uv.x, uv.y / screenAspectRatio);

    vec4 colorForeground = foreground.eval(adjustedUvForeground);
    vec4 colorBackground = background.eval(adjustedUvBackground);
    vec4 colorForeground = foreground.eval(adjustedUv);
    vec4 colorBackground = background.eval(adjustedUv);

     // Adjusts contrast and brightness.
    float noiseT = triangleNoise(fragCoord.xy + vec2(12.31, 1024.1241));
@@ -100,7 +98,7 @@ vec4 main(float2 fragCoord) {
    float dither = abs(triangleNoise(fragCoord * 0.01));

    // Get the accumulated snow buffer. r contains its mask, g contains some random noise.
    vec2 accSnow = accumulatedSnow.eval(adjustedUvForeground).rg;
    vec2 accSnow = accumulatedSnow.eval(adjustedUv).rg;
    // Sharpen the mask of the accumulated snow, but not in excess.
    float accSnowMask = smoothstep(0.1, 0.9, /* mask= */ accSnow.r);
    // Makes the edges of the snow layer accumulation rougher.
+4 −6
Original line number Diff line number Diff line
@@ -20,8 +20,7 @@ uniform float screenAspectRatio;
uniform float2 screenSize;
uniform float time;
uniform float intensity;
uniform mat3 transformMatrixFgd;
uniform mat3 transformMatrixBgd;
uniform mat3 transformMatrixBitmap;
uniform mat3 transformMatrixWeather;


@@ -96,8 +95,7 @@ float checkBrightnessGodRaysAtCenter(

vec4 main(float2 fragCoord) {
    // Apply transform matrix to fragCoord
    float2 adjustedUvForeground = transformPoint(transformMatrixFgd, fragCoord);
    float2 adjustedUvBackground = transformPoint(transformMatrixBgd, fragCoord);
    float2 adjustedUv = transformPoint(transformMatrixBitmap, fragCoord);

    float2 uv = transformPoint(transformMatrixWeather, fragCoord) / screenSize;
    uv -= vec2(0.5, 0.5);
@@ -107,8 +105,8 @@ vec4 main(float2 fragCoord) {
    vec2 sunPos = sunVariation + sunCenter / vec2(1., screenAspectRatio);
    //TODO(b/375214506): fix the uv position of the sun

    vec4 colorForeground = foreground.eval(adjustedUvForeground);
    vec4 color = background.eval(adjustedUvBackground);
    vec4 colorForeground = foreground.eval(adjustedUv);
    vec4 color = background.eval(adjustedUv);
    // add foreground
    color.rgb = normalBlend(color.rgb, colorForeground.rgb, colorForeground.a);

+136 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.wallpaper.weathereffects.graphics

import android.graphics.Bitmap
import android.graphics.BitmapShader
import android.graphics.Canvas
import android.graphics.Matrix
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.centerCropMatrix
import com.google.android.wallpaper.weathereffects.graphics.utils.MatrixUtils.invertAndTransposeMatrix
import kotlin.random.Random

/** Give default implementation of some functions in WeatherEffect */
abstract class WeatherEffectBase(
    protected var foreground: Bitmap,
    protected var background: Bitmap,
    /** The initial size of the surface where the effect will be shown. */
    private var surfaceSize: SizeF,
) : WeatherEffect {
    private var centerCropMatrix: Matrix =
        centerCropMatrix(
            surfaceSize,
            SizeF(background.width.toFloat(), background.height.toFloat()),
        )
    protected var parallaxMatrix = Matrix(centerCropMatrix)
    // 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 elapsedTime: Float = 0f

    abstract val shader: RuntimeShader
    abstract val colorGradingShader: RuntimeShader
    abstract val lut: Bitmap?
    abstract val colorGradingIntensity: Float

    override fun setMatrix(matrix: Matrix) {
        this.parallaxMatrix = matrix
        adjustCropping(surfaceSize)
    }

    open fun adjustCropping(newSurfaceSize: SizeF) {
        invertAndTransposeMatrix(parallaxMatrix, transformMatrixBitmap)
        calculateTransformDifference(centerCropMatrix, parallaxMatrix, transformMatrixWeather)
        shader.setFloatUniform("transformMatrixBitmap", transformMatrixBitmap)
        shader.setFloatUniform("transformMatrixWeather", transformMatrixWeather)
        shader.setFloatUniform("screenSize", newSurfaceSize.width, newSurfaceSize.height)
        shader.setFloatUniform("screenAspectRatio", GraphicsUtils.getAspectRatio(newSurfaceSize))
    }

    open fun updateGridSize(newSurfaceSize: SizeF) {}

    override fun resize(newSurfaceSize: SizeF) {
        surfaceSize = newSurfaceSize
        adjustCropping(newSurfaceSize)
        updateGridSize(newSurfaceSize)
    }

    abstract override fun update(deltaMillis: Long, frameTimeNanos: Long)

    abstract override fun draw(canvas: Canvas)

    override fun reset() {
        elapsedTime = Random.nextFloat() * 90f
    }

    override fun release() {
        lut?.recycle()
    }

    override fun setIntensity(intensity: Float) {
        shader.setFloatUniform("intensity", intensity)
        colorGradingShader.setFloatUniform("intensity", colorGradingIntensity * intensity)
    }

    override fun setBitmaps(foreground: Bitmap?, background: Bitmap) {
        if (this.foreground == foreground && this.background == background) {
            return
        }
        // Only when background changes, we can infer the bitmap set changes
        if (this.background != background) {
            this.background.recycle()
            this.foreground.recycle()
        }
        this.foreground = foreground ?: background
        this.background = background

        centerCropMatrix =
            centerCropMatrix(
                surfaceSize,
                SizeF(background.width.toFloat(), background.height.toFloat()),
            )
        parallaxMatrix.set(centerCropMatrix)
        shader.setInputBuffer(
            "background",
            BitmapShader(this.background, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR),
        )
        shader.setInputBuffer(
            "foreground",
            BitmapShader(this.foreground, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR),
        )
        adjustCropping(surfaceSize)
    }

    open fun updateTextureUniforms() {
        shader.setInputBuffer(
            "foreground",
            BitmapShader(foreground, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR),
        )

        shader.setInputBuffer(
            "background",
            BitmapShader(background, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR),
        )
    }
}
Loading