Loading weathereffects/assets/shaders/fog_effect.agsl +9 −9 Original line number Diff line number Diff line Loading @@ -20,26 +20,26 @@ uniform float2 uvOffsetFgd; uniform float2 uvScaleFgd; uniform float2 uvOffsetBgd; uniform float2 uvScaleBgd; uniform half2 timeForeground; uniform half2 timeBackground; uniform half timeForeground; uniform half timeBackground; uniform half screenAspectRatio; uniform half2 screenSize; uniform half pixelDensity; #include "shaders/constants.agsl" #include "shaders/utils.agsl" #include "shaders/simplex_noise.agsl" #include "shaders/simplex_flow_noise.agsl" // TODO: explore a more performant way of generating the volumetric fog effect. const int numOctaves = 2; float fbm (vec3 st, vec2 time) { vec3 p = st; float fbm(vec2 p, half time) { float a = 0.5; float result = 0.0; float rot = 1.2; for (int i = 0; i < numOctaves; i++) { result += a * simplex3d(vec3(p.xy + time, p.z)); result += a * simplex2d_flow(p, rot, time); rot *= 1.25; p *= 2.0152; a *= 0.5; } Loading @@ -54,8 +54,8 @@ vec4 main(float2 fragCoord) { vec4 colorForeground = foreground.eval(fragCoord * uvScaleFgd + uvOffsetFgd); vec4 color = background.eval(fragCoord * uvScaleBgd + uvOffsetBgd); float frontFog = smoothstep(-0.616, 0.552, fbm(vec3(uv * 0.886, 123.1), timeForeground)); float bgdFog = smoothstep(-0.744, 0.28, fbm(vec3(uv * 1.2, 231.), timeBackground)); float frontFog = smoothstep(-0.616, 0.552, fbm(uv * 0.8, timeForeground)); float bgdFog = smoothstep(-0.744, 0.28, fbm(uv * 1.2, timeBackground)); float dither = 1. - triangleNoise(fragCoord * pixelDensity) * 0.161; Loading weathereffects/assets/shaders/simplex_flow_noise.agsl 0 → 100644 +80 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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. */ const float SKEW = 0.366025404; // (sqrt(3)-1)/2 const float UNSKEW = 0.211324865; // (3-sqrt(3))/6 half2 hash2d(vec2 p) { p = vec2(dot(p,vec2(157.1, 235.7)), dot(p,vec2(573.5, 13.3))); return fract(sin(p) * 877.343) * 2. -1.; // [-1, 1] } half hash1d(vec2 p) { return fract(sin(dot(p, vec2(343.0, 49.0)))) * 2. -1.; // [-1, 1] } vec2 getVectorFromAngle(float theta) { return vec2(cos(theta), sin(theta)); } // 2D Simplex noise with dynamic gradient vectors. Return value [-1, 1]. // // This method produces similar visuals to Simplex noise 3D, but at a lower computational cost. // The snapshot of the noise is the same as a regular Simplex noise. However, when animated, it // creates a swirling motion that is more suitable for flow-y effects. // // The difference in motion is not noticeable unless the following conditions are met: // 1) The rotation offset is identical for all vertex gradients. // 2) The noise is moving quickly. // 3) The noise is tiled. // // This method is recommended for use because it is significantly more performant than 3D Simplex // noise. It is especially useful for simulating fire, clouds, and fog, which all have advection. // // rot is an angle in radian that you want to step for each dt. float simplex2d_flow(vec2 p, float rot, float time) { // Skew the input coordinate and find the simplex index. vec2 i = floor(p + (p.x + p.y) * SKEW); // First vertex of the triangle. vec2 v0 = p - i + (i.x + i.y) * UNSKEW; // Find two other vertices. // Determines which triangle we should walk. // If y>x, m=0 upper triangle, x>y, m=1 lower triangle. float side = step(v0.y, v0.x); vec2 walk = vec2(side, 1.0 - side); vec2 v1 = v0 - walk + UNSKEW; vec2 v2 = v0 - 1.0 + 2.*UNSKEW; // Get random gradient vector. vec2 g0 = hash2d(i); vec2 g1 = hash2d(i+walk); vec2 g2 = hash2d(i+1.0); // Make the gradient vectors dynamic by adding rotations. g0 += getVectorFromAngle(rot * time * hash1d(i)); g1 += getVectorFromAngle(rot * time * hash1d(i+walk)); g2 += getVectorFromAngle(rot * time * hash1d(i+1.)); // Kernel summation vec3 w = max(0.5 - vec3(dot(v0, v0), dot(v1, v1), dot(v2, v2)), 0.0); w = w*w*w*w; vec3 n = w * vec3(dot(v0, g0), dot(v1, g1), dot(v2, g2)); return dot(n, vec3(32.0)); } weathereffects/src/com/google/android/wallpaper/weathereffects/fog/FogEffect.kt +5 −18 Original line number Diff line number Diff line Loading @@ -35,10 +35,6 @@ class FogEffect( ) : WeatherEffect { private val fogPaint = Paint().also { it.shader = fogConfig.colorGradingShader } private val variationFgd: FloatArray = FloatArray(2) private val timeFgd: FloatArray = FloatArray(2) private val variationBgd: FloatArray = FloatArray(2) private val timeBgd: FloatArray = FloatArray(2) private var elapsedTime: Float = 0f init { Loading @@ -51,23 +47,14 @@ class FogEffect( override fun update(deltaMillis: Long, frameTimeNanos: Long) { val time = 0.02f * frameTimeNanos.toFloat() * NANOS_TO_SECONDS val variation = sin(time + sin(3f * time)) * 0.5f + 0.5f elapsedTime += variation * deltaMillis * MILLIS_TO_SECONDS val speed = elapsedTime * 0.248f variationFgd[0] = 0.256f * sin(speed) variationFgd[1] = 0.156f * sin(speed) * sin(speed) timeFgd[0] = 0.04f * elapsedTime * 5f + variationFgd[0] timeFgd[1] = 0.003f * elapsedTime * 5f + variationFgd[1] // Variation range [1, 1.5]. We don't want the variation to be 0. val variation = (sin(time + sin(3f * time)) * 0.5f + 0.5f) * 1.5f elapsedTime += variation * deltaMillis * MILLIS_TO_SECONDS variationBgd[0] = 0.156f * sin((speed + Math.PI.toFloat() / 2.0f)) variationBgd[1] = 0.0156f * sin((speed * Math.PI.toFloat() / 3.0f)) * sin(speed) timeBgd[0] = 0.08f * elapsedTime * 5f + variationBgd[0] timeBgd[1] = 0.02f * elapsedTime * 5f + variationBgd[1] fogConfig.shader.setFloatUniform("timeBackground", elapsedTime * 1.5f) fogConfig.shader.setFloatUniform("timeForeground", elapsedTime * 2.0f) fogConfig.shader.setFloatUniform("timeForeground", timeFgd[0], timeFgd[1]) fogConfig.shader.setFloatUniform("timeBackground", timeBgd[0], timeBgd[1]) fogConfig.colorGradingShader.setInputShader("texture", fogConfig.shader) } Loading Loading
weathereffects/assets/shaders/fog_effect.agsl +9 −9 Original line number Diff line number Diff line Loading @@ -20,26 +20,26 @@ uniform float2 uvOffsetFgd; uniform float2 uvScaleFgd; uniform float2 uvOffsetBgd; uniform float2 uvScaleBgd; uniform half2 timeForeground; uniform half2 timeBackground; uniform half timeForeground; uniform half timeBackground; uniform half screenAspectRatio; uniform half2 screenSize; uniform half pixelDensity; #include "shaders/constants.agsl" #include "shaders/utils.agsl" #include "shaders/simplex_noise.agsl" #include "shaders/simplex_flow_noise.agsl" // TODO: explore a more performant way of generating the volumetric fog effect. const int numOctaves = 2; float fbm (vec3 st, vec2 time) { vec3 p = st; float fbm(vec2 p, half time) { float a = 0.5; float result = 0.0; float rot = 1.2; for (int i = 0; i < numOctaves; i++) { result += a * simplex3d(vec3(p.xy + time, p.z)); result += a * simplex2d_flow(p, rot, time); rot *= 1.25; p *= 2.0152; a *= 0.5; } Loading @@ -54,8 +54,8 @@ vec4 main(float2 fragCoord) { vec4 colorForeground = foreground.eval(fragCoord * uvScaleFgd + uvOffsetFgd); vec4 color = background.eval(fragCoord * uvScaleBgd + uvOffsetBgd); float frontFog = smoothstep(-0.616, 0.552, fbm(vec3(uv * 0.886, 123.1), timeForeground)); float bgdFog = smoothstep(-0.744, 0.28, fbm(vec3(uv * 1.2, 231.), timeBackground)); float frontFog = smoothstep(-0.616, 0.552, fbm(uv * 0.8, timeForeground)); float bgdFog = smoothstep(-0.744, 0.28, fbm(uv * 1.2, timeBackground)); float dither = 1. - triangleNoise(fragCoord * pixelDensity) * 0.161; Loading
weathereffects/assets/shaders/simplex_flow_noise.agsl 0 → 100644 +80 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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. */ const float SKEW = 0.366025404; // (sqrt(3)-1)/2 const float UNSKEW = 0.211324865; // (3-sqrt(3))/6 half2 hash2d(vec2 p) { p = vec2(dot(p,vec2(157.1, 235.7)), dot(p,vec2(573.5, 13.3))); return fract(sin(p) * 877.343) * 2. -1.; // [-1, 1] } half hash1d(vec2 p) { return fract(sin(dot(p, vec2(343.0, 49.0)))) * 2. -1.; // [-1, 1] } vec2 getVectorFromAngle(float theta) { return vec2(cos(theta), sin(theta)); } // 2D Simplex noise with dynamic gradient vectors. Return value [-1, 1]. // // This method produces similar visuals to Simplex noise 3D, but at a lower computational cost. // The snapshot of the noise is the same as a regular Simplex noise. However, when animated, it // creates a swirling motion that is more suitable for flow-y effects. // // The difference in motion is not noticeable unless the following conditions are met: // 1) The rotation offset is identical for all vertex gradients. // 2) The noise is moving quickly. // 3) The noise is tiled. // // This method is recommended for use because it is significantly more performant than 3D Simplex // noise. It is especially useful for simulating fire, clouds, and fog, which all have advection. // // rot is an angle in radian that you want to step for each dt. float simplex2d_flow(vec2 p, float rot, float time) { // Skew the input coordinate and find the simplex index. vec2 i = floor(p + (p.x + p.y) * SKEW); // First vertex of the triangle. vec2 v0 = p - i + (i.x + i.y) * UNSKEW; // Find two other vertices. // Determines which triangle we should walk. // If y>x, m=0 upper triangle, x>y, m=1 lower triangle. float side = step(v0.y, v0.x); vec2 walk = vec2(side, 1.0 - side); vec2 v1 = v0 - walk + UNSKEW; vec2 v2 = v0 - 1.0 + 2.*UNSKEW; // Get random gradient vector. vec2 g0 = hash2d(i); vec2 g1 = hash2d(i+walk); vec2 g2 = hash2d(i+1.0); // Make the gradient vectors dynamic by adding rotations. g0 += getVectorFromAngle(rot * time * hash1d(i)); g1 += getVectorFromAngle(rot * time * hash1d(i+walk)); g2 += getVectorFromAngle(rot * time * hash1d(i+1.)); // Kernel summation vec3 w = max(0.5 - vec3(dot(v0, v0), dot(v1, v1), dot(v2, v2)), 0.0); w = w*w*w*w; vec3 n = w * vec3(dot(v0, g0), dot(v1, g1), dot(v2, g2)); return dot(n, vec3(32.0)); }
weathereffects/src/com/google/android/wallpaper/weathereffects/fog/FogEffect.kt +5 −18 Original line number Diff line number Diff line Loading @@ -35,10 +35,6 @@ class FogEffect( ) : WeatherEffect { private val fogPaint = Paint().also { it.shader = fogConfig.colorGradingShader } private val variationFgd: FloatArray = FloatArray(2) private val timeFgd: FloatArray = FloatArray(2) private val variationBgd: FloatArray = FloatArray(2) private val timeBgd: FloatArray = FloatArray(2) private var elapsedTime: Float = 0f init { Loading @@ -51,23 +47,14 @@ class FogEffect( override fun update(deltaMillis: Long, frameTimeNanos: Long) { val time = 0.02f * frameTimeNanos.toFloat() * NANOS_TO_SECONDS val variation = sin(time + sin(3f * time)) * 0.5f + 0.5f elapsedTime += variation * deltaMillis * MILLIS_TO_SECONDS val speed = elapsedTime * 0.248f variationFgd[0] = 0.256f * sin(speed) variationFgd[1] = 0.156f * sin(speed) * sin(speed) timeFgd[0] = 0.04f * elapsedTime * 5f + variationFgd[0] timeFgd[1] = 0.003f * elapsedTime * 5f + variationFgd[1] // Variation range [1, 1.5]. We don't want the variation to be 0. val variation = (sin(time + sin(3f * time)) * 0.5f + 0.5f) * 1.5f elapsedTime += variation * deltaMillis * MILLIS_TO_SECONDS variationBgd[0] = 0.156f * sin((speed + Math.PI.toFloat() / 2.0f)) variationBgd[1] = 0.0156f * sin((speed * Math.PI.toFloat() / 3.0f)) * sin(speed) timeBgd[0] = 0.08f * elapsedTime * 5f + variationBgd[0] timeBgd[1] = 0.02f * elapsedTime * 5f + variationBgd[1] fogConfig.shader.setFloatUniform("timeBackground", elapsedTime * 1.5f) fogConfig.shader.setFloatUniform("timeForeground", elapsedTime * 2.0f) fogConfig.shader.setFloatUniform("timeForeground", timeFgd[0], timeFgd[1]) fogConfig.shader.setFloatUniform("timeBackground", timeBgd[0], timeBgd[1]) fogConfig.colorGradingShader.setInputShader("texture", fogConfig.shader) } Loading