Add intensity uniform param.

Bug: 325090421
Test: m WeatherEffectsGraphicsLib
Flag: NA
Change-Id: I9e6a39ca15a4ba4705544ae0c78ee65e34a5bce2
diff --git a/weathereffects/graphics/assets/shaders/fog_effect.agsl b/weathereffects/graphics/assets/shaders/fog_effect.agsl
index eab926b..57a3a1b 100644
--- a/weathereffects/graphics/assets/shaders/fog_effect.agsl
+++ b/weathereffects/graphics/assets/shaders/fog_effect.agsl
@@ -25,6 +25,7 @@
 uniform half screenAspectRatio;
 uniform half2 screenSize;
 uniform half pixelDensity;
+uniform half intensity;
 
 #include "shaders/constants.agsl"
 #include "shaders/utils.agsl"
@@ -59,11 +60,11 @@
 
     float dither = 1. - triangleNoise(fragCoord * pixelDensity) * 0.161;
 
-    color.rgb = normalBlendWithWhiteSrc(color.rgb, 0.8 * dither * bgdFog);
+    color.rgb = normalBlendWithWhiteSrc(color.rgb, 0.8 * dither * bgdFog * intensity);
     // Add the foreground. Any effect from here will be in front of the subject.
     color.rgb = normalBlend(color.rgb, colorForeground.rgb, colorForeground.a);
     // foreground fog.
-    color.rgb = normalBlendWithWhiteSrc(color.rgb, 0.5 * frontFog);
+    color.rgb = normalBlendWithWhiteSrc(color.rgb, 0.5 * frontFog * intensity);
 
     return color;
 }
diff --git a/weathereffects/graphics/assets/shaders/rain_effect.agsl b/weathereffects/graphics/assets/shaders/rain_effect.agsl
index 90a4f8b..13e3511 100644
--- a/weathereffects/graphics/assets/shaders/rain_effect.agsl
+++ b/weathereffects/graphics/assets/shaders/rain_effect.agsl
@@ -24,6 +24,7 @@
 uniform float time;
 uniform float screenAspectRatio;
 uniform float2 screenSize;
+uniform half intensity;
 
 #include "shaders/constants.agsl"
 #include "shaders/utils.agsl"
@@ -66,7 +67,7 @@
          screenAspectRatio,
          time,
          /* Grid size = */ vec2(4.0, 2.0),
-         /* rain intensity = */ 0.8);
+         intensity);
     float dropMask = drippingRain.dropMask;
     float droppletsMask = drippingRain.droppletsMask;
     float trailMask = drippingRain.trailMask;
@@ -79,7 +80,7 @@
           screenAspectRatio,
           time * 1.267,
           /* Grid size = */ vec2(3.0, 1.0),
-          /* rain intensity = */ 0.6);
+          intensity);
     dropMask = max(drippingRain.dropMask, dropMask);
     droppletsMask = max(drippingRain.droppletsMask, droppletsMask);
     trailMask = max(drippingRain.trailMask, trailMask);
@@ -139,7 +140,7 @@
           screenAspectRatio,
           time * 18.,
           /* Grid size = */ vec2(30.0, 4.0),
-          /* rain intensity = */ rainIntensity);
+          intensity);
 
     color.rgb = mix(color.rgb, highlightColor.rgb, rainVisibility * rain.dropMask);
 
@@ -152,7 +153,7 @@
           screenAspectRatio,
           time * 27.,
           /* Grid size = */ vec2(8.0, 3.0),
-          /* rain intensity = */ rainIntensity);
+          intensity);
 
     // The rain that is closer, make it less visible
     color.rgb = mix(color.rgb, highlightColor.rgb, 0.7 * rainVisibility * rain.dropMask);
diff --git a/weathereffects/graphics/assets/shaders/snow.agsl b/weathereffects/graphics/assets/shaders/snow.agsl
index 7e54a86..fe1bad4 100644
--- a/weathereffects/graphics/assets/shaders/snow.agsl
+++ b/weathereffects/graphics/assets/shaders/snow.agsl
@@ -24,6 +24,8 @@
     -0.7071067812, 0.7071067812 // second column.
 );
 
+uniform half intensity;
+
 /**
  * Generates snow flakes.
  *
@@ -74,6 +76,16 @@
     vec2 cellUv = fract(gridUv) - 0.5;
     cellUv.y *= -1.;
 
+   /*
+    * Disable snow flakes with some probabilty. This is done by 1) assigning a random intensity
+    * value to the cell 2) then compare it with the given intensity.
+    */
+    half cellIntensity = idGenerator(floor(vec2(cellId * 856.16, 272.2)));
+    if (cellIntensity < 1. - intensity) {
+        // Remove snow flakes by seeting flake mask to 0.
+        return Snow(/* flakeMask= */ 0, cellUv);
+    }
+
     /* Cell-id-based variations. */
     // Adjust time based on columnId.
     // Adjusts scale of each snow flake (higher is smaller).
diff --git a/weathereffects/graphics/assets/shaders/snow_accumulation.agsl b/weathereffects/graphics/assets/shaders/snow_accumulation.agsl
index baa34e6..c6ca44a 100644
--- a/weathereffects/graphics/assets/shaders/snow_accumulation.agsl
+++ b/weathereffects/graphics/assets/shaders/snow_accumulation.agsl
@@ -16,6 +16,7 @@
 
 uniform shader foreground;
 uniform float2 imageSize;
+uniform half intensity;
 
 #include "shaders/simplex2d.agsl"
 #include "shaders/utils.agsl"
@@ -27,7 +28,7 @@
 vec4 main(float2 fragCoord) {
     // fragCoord should be already the adjusted UVs to have the expected rect of the image.
     float variation = 0.5 + 0.5 * simplex2d(25. * fragCoord / imageSize.xx);
-    float distance = 8. * variation;
+    float distance = 8. * variation * intensity;
     float aN = foreground.eval(fragCoord + vec2(0., distance)).a;
     float aS = foreground.eval(fragCoord + vec2(0., -distance)).a;
     float dY = (aN - aS) * 0.5;
diff --git a/weathereffects/graphics/assets/shaders/snow_effect.agsl b/weathereffects/graphics/assets/shaders/snow_effect.agsl
index af040a6..c3a1f1e 100644
--- a/weathereffects/graphics/assets/shaders/snow_effect.agsl
+++ b/weathereffects/graphics/assets/shaders/snow_effect.agsl
@@ -55,20 +55,22 @@
 
     // Get color of the background texture.
     color.rgb = mix(colorBackground.rgb, glassTint.rgb, frostedGlassIntensity);
-    for (float i = 9.; i > 2.; i--) {
+    for (half i = 9.; i > 2.; i--) {
         // Generate snow behind the subject.
+        // Normalized layer index.
+        half idx = (i - 2.) / (9. - 2.);
         Snow snow = generateSnow(
               uv,
               screenAspectRatio,
-              time * 1.25,
-              /* Grid size = */ vec2(2.1, 1.4),
+              time * mix(1.25, 5., idx),
+              /* Grid size = */ vec2(mix(3.0, 6.0, idx), mix(1.0, 3.0, idx)),
               /* layer number = */ i);
 
         color.rgb = mix(color.rgb, snowColor.rgb, snowOpacity * snow.flakeMask);
     }
 
     // Add the foreground. Any effect from here will be in front of the subject.
-    color.rgb = mix(color.rgb, colorForeground.rgb, colorForeground.a);
+    color.rgb = normalBlend(color.rgb, colorForeground.rgb, colorForeground.a);
 
     // Add accumulated snow.
     vec2 accSnow = accumulatedSnow.eval(adjustedUvForeground).rg;
@@ -76,13 +78,13 @@
     float snowTexture = smoothstep(0.2, 0.7, accSnow.g);
     color.rgb = mix(color.rgb, vec3(0.95), 0.98 * snowLayer * (0.05 + 0.95 * snowTexture));
 
-    for (float i = 2.; i >= 0.; i--) {
+    for (half i = 2.; i >= 0.; i--) {
         // Generate snow behind the subject.
         Snow snow = generateSnow(
               uv,
               screenAspectRatio,
               time * 1.25,
-              /* Grid size = */ vec2(2.1, 1.4),
+              /* Grid size = */ vec2(i + 1., 1.4),
               /* layer number = */ i);
 
         color.rgb = mix(color.rgb, snowColor.rgb, snowOpacity * snow.flakeMask);
diff --git a/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/WeatherEffect.kt b/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/WeatherEffect.kt
index 8c751d5..0517fa3 100644
--- a/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/WeatherEffect.kt
+++ b/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/WeatherEffect.kt
@@ -18,6 +18,7 @@
 
 import android.graphics.Canvas
 import android.util.SizeF
+import androidx.annotation.FloatRange
 
 /** Defines a single weather effect with a main shader and a main LUT for color grading. */
 interface WeatherEffect {
@@ -50,4 +51,12 @@
 
     /** Releases the weather effect. */
     fun release()
+
+    /**
+     * Adjusts the intensity of the effect (that means both weather intensity and color grading
+     * intensity, if any).
+     *
+     * @param intensity [0, 1] the intensity of the weather effect.
+     */
+    fun setIntensity(@FloatRange(from = 0.0, to = 1.0) intensity: Float)
 }
diff --git a/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/fog/FogEffect.kt b/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/fog/FogEffect.kt
index d631c15..403b385 100644
--- a/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/fog/FogEffect.kt
+++ b/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/fog/FogEffect.kt
@@ -41,6 +41,7 @@
         updateTextureUniforms()
         adjustCropping(surfaceSize)
         prepareColorGrading()
+        setIntensity(fogConfig.intensity)
     }
 
     override fun resize(newSurfaceSize: SizeF) = adjustCropping(newSurfaceSize)
@@ -70,6 +71,14 @@
         fogConfig.lut?.recycle()
     }
 
+    override fun setIntensity(intensity: Float) {
+        fogConfig.shader.setFloatUniform("intensity", intensity)
+        fogConfig.colorGradingShader.setFloatUniform(
+            "intensity",
+            fogConfig.colorGradingIntensity * intensity
+        )
+    }
+
     private fun adjustCropping(surfaceSize: SizeF) {
         val imageCropFgd =
             ImageCrop.centerCoverCrop(
diff --git a/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/fog/FogEffectConfig.kt b/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/fog/FogEffectConfig.kt
index 8048eda..68e7f2b 100644
--- a/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/fog/FogEffectConfig.kt
+++ b/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/fog/FogEffectConfig.kt
@@ -30,14 +30,16 @@
     val colorGradingShader: RuntimeShader,
     /** The main lut (color grading) for the effect. */
     val lut: Bitmap?,
-    /** The intensity of the color grading. 0: no color grading, 1: color grading in full effect. */
-    @FloatRange(from = 0.0, to = 1.0) val colorGradingIntensity: Float,
     /** A bitmap containing the foreground of the image. */
     val foreground: Bitmap,
     /** A bitmap containing the background of the image. */
     val background: Bitmap,
     /** Pixel density of the display. Used for dithering. */
-    val pixelDensity: Float
+    val pixelDensity: Float,
+    /** The amount of the fog. This contributes to the color grading as well. */
+    @FloatRange(from = 0.0, to = 1.0) val intensity: Float = 1f,
+    /** The intensity of the color grading. 0: no color grading, 1: color grading in full effect. */
+    @FloatRange(from = 0.0, to = 1.0) val colorGradingIntensity: Float = 0.7f,
 ) {
 
     companion object {
@@ -63,7 +65,6 @@
                 colorGradingShader =
                     GraphicsUtils.loadShader(assets, "shaders/color_grading_lut.agsl"),
                 lut = GraphicsUtils.loadTexture(assets, "textures/lut_rain_and_fog.png"),
-                colorGradingIntensity = 0.7f,
                 foreground,
                 background,
                 pixelDensity
diff --git a/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/none/NoEffect.kt b/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/none/NoEffect.kt
index e9f95eb..592b627 100644
--- a/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/none/NoEffect.kt
+++ b/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/none/NoEffect.kt
@@ -54,4 +54,6 @@
     override fun reset() {}
 
     override fun release() {}
+
+    override fun setIntensity(intensity: Float) {}
 }
diff --git a/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/rain/RainEffect.kt b/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/rain/RainEffect.kt
index 3b12603..87c828f 100644
--- a/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/rain/RainEffect.kt
+++ b/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/rain/RainEffect.kt
@@ -41,6 +41,7 @@
         updateTextureUniforms()
         adjustCropping(surfaceSize)
         prepareColorGrading()
+        setIntensity(rainConfig.intensity)
     }
 
     override fun resize(newSurfaceSize: SizeF) = adjustCropping(newSurfaceSize)
@@ -64,6 +65,14 @@
         rainConfig.blurredBackground.recycle()
     }
 
+    override fun setIntensity(intensity: Float) {
+        rainConfig.shader.setFloatUniform("intensity", intensity)
+        rainConfig.colorGradingShader.setFloatUniform(
+            "intensity",
+            rainConfig.colorGradingIntensity * intensity
+        )
+    }
+
     private fun adjustCropping(surfaceSize: SizeF) {
         val imageCropFgd =
             ImageCrop.centerCoverCrop(
@@ -135,7 +144,6 @@
                 BitmapShader(it, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR)
             )
         }
-        rainConfig.colorGradingShader.setFloatUniform("intensity", rainConfig.colorGradingIntensity)
     }
 
     private companion object {
diff --git a/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/rain/RainEffectConfig.kt b/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/rain/RainEffectConfig.kt
index 29bbef2..355cda9 100644
--- a/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/rain/RainEffectConfig.kt
+++ b/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/rain/RainEffectConfig.kt
@@ -30,14 +30,16 @@
     val colorGradingShader: RuntimeShader,
     /** The main lut (color grading) for the effect. */
     val lut: Bitmap?,
-    /** The intensity of the color grading. 0: no color grading, 1: color grading in full effect. */
-    @FloatRange(from = 0.0, to = 1.0) val colorGradingIntensity: Float,
     /** A bitmap containing the foreground of the image. */
     val foreground: Bitmap,
     /** A bitmap containing the background of the image. */
     val background: Bitmap,
     /** A bitmap containing the blurred background. */
-    val blurredBackground: Bitmap
+    val blurredBackground: Bitmap,
+    /** The amount of the rain. This contributes to the color grading as well. */
+    @FloatRange(from = 0.0, to = 1.0) val intensity: Float = 1f,
+    /** The intensity of the color grading. 0: no color grading, 1: color grading in full effect. */
+    @FloatRange(from = 0.0, to = 1.0) val colorGradingIntensity: Float = 0.7f,
 ) {
 
     companion object {
@@ -57,7 +59,6 @@
                 colorGradingShader =
                     GraphicsUtils.loadShader(context.assets, "shaders/color_grading_lut.agsl"),
                 lut = GraphicsUtils.loadTexture(context.assets, "textures/lut_rain_and_fog.png"),
-                colorGradingIntensity = 0.7f,
                 foreground,
                 background,
                 GraphicsUtils.blurImage(context, background, 10f)
diff --git a/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/snow/SnowEffect.kt b/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/snow/SnowEffect.kt
index c29ca7d..aa9bc78 100644
--- a/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/snow/SnowEffect.kt
+++ b/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/snow/SnowEffect.kt
@@ -47,10 +47,13 @@
 
     init {
         frameBuffer.setRenderEffect(RenderEffect.createBlurEffect(4f, 4f, Shader.TileMode.CLAMP))
-        generateAccumulatedSnow()
         updateTextureUniforms()
         adjustCropping(surfaceSize)
         prepareColorGrading()
+        setIntensity(snowConfig.intensity)
+
+        // Generate accumulated snow at the end after we updated all the uniforms.
+        generateAccumulatedSnow()
     }
 
     override fun resize(newSurfaceSize: SizeF) = adjustCropping(newSurfaceSize)
@@ -75,6 +78,18 @@
         frameBuffer.close()
     }
 
+    override fun setIntensity(intensity: Float) {
+        snowConfig.shader.setFloatUniform("intensity", intensity)
+        snowConfig.colorGradingShader.setFloatUniform(
+            "intensity",
+            snowConfig.colorGradingIntensity * intensity
+        )
+        snowConfig.accumulatedSnowShader.setFloatUniform("intensity", intensity)
+
+        // Regenerate accumulated snow since the uniform changed.
+        generateAccumulatedSnow()
+    }
+
     private fun adjustCropping(surfaceSize: SizeF) {
         val imageCropFgd =
             ImageCrop.centerCoverCrop(
@@ -146,7 +161,6 @@
                 BitmapShader(it, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR)
             )
         }
-        snowConfig.colorGradingShader.setFloatUniform("intensity", snowConfig.colorGradingIntensity)
     }
 
     private fun generateAccumulatedSnow() {
diff --git a/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/snow/SnowEffectConfig.kt b/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/snow/SnowEffectConfig.kt
index 88ef554..4adf15a 100644
--- a/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/snow/SnowEffectConfig.kt
+++ b/weathereffects/graphics/src/main/java/com/google/android/wallpaper/weathereffects/graphics/snow/SnowEffectConfig.kt
@@ -32,14 +32,16 @@
     val colorGradingShader: RuntimeShader,
     /** The main lut (color grading) for the effect. */
     val lut: Bitmap?,
-    /** The intensity of the color grading. 0: no color grading, 1: color grading in full effect. */
-    @FloatRange(from = 0.0, to = 1.0) val colorGradingIntensity: Float,
     /** A bitmap containing the foreground of the image. */
     val foreground: Bitmap,
     /** A bitmap containing the background of the image. */
     val background: Bitmap,
     /** A bitmap containing the blurred background. */
-    val blurredBackground: Bitmap
+    val blurredBackground: Bitmap,
+    /** The amount of the snow flakes. This contributes to the color grading as well. */
+    @FloatRange(from = 0.0, to = 1.0) val intensity: Float = 1f,
+    /** The intensity of the color grading. 0: no color grading, 1: color grading in full effect. */
+    @FloatRange(from = 0.0, to = 1.0) val colorGradingIntensity: Float = 0.7f,
 ) {
 
     companion object {
@@ -61,7 +63,6 @@
                 colorGradingShader =
                     GraphicsUtils.loadShader(context.assets, "shaders/color_grading_lut.agsl"),
                 lut = GraphicsUtils.loadTexture(context.assets, "textures/lut_rain_and_fog.png"),
-                colorGradingIntensity = 0.7f,
                 foreground,
                 background,
                 GraphicsUtils.blurImage(context, background, 20f)