Merge "Fix sun effect is too bright and parallax translation is not accurate" into main
diff --git a/weathereffects/graphics/assets/shaders/sun_effect.agsl b/weathereffects/graphics/assets/shaders/sun_effect.agsl
index 601b3d3..3886eb3 100644
--- a/weathereffects/graphics/assets/shaders/sun_effect.agsl
+++ b/weathereffects/graphics/assets/shaders/sun_effect.agsl
@@ -30,8 +30,8 @@
#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 @@
}
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);
diff --git a/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/WeatherEffectBase.kt b/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/WeatherEffectBase.kt
index e2739b2..405d1df 100644
--- a/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/WeatherEffectBase.kt
+++ b/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/WeatherEffectBase.kt
@@ -24,9 +24,9 @@
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 @@
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 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 @@
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 @@
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 @@
)
}
+ 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.
diff --git a/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/utils/MatrixUtils.kt b/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/utils/MatrixUtils.kt
index 7d2afa6..4aa053a 100644
--- a/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/utils/MatrixUtils.kt
+++ b/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/utils/MatrixUtils.kt
@@ -55,6 +55,10 @@
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 @@
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) {