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

Commit 0f1a3800 authored by Michel Comin Escude's avatar Michel Comin Escude
Browse files

Adding Sun effect

Added sun effect, with flare and god rays shaders

Flag: EXEMPT only change in Magic Portrait
Bug: 347299395
Test: visual

Change-Id: I75e1aff3fb8f46a03dc1bbe97a7729c2e2bdf6b7
parent 5f4fbf95
Loading
Loading
Loading
Loading
+39 −1
Original line number Diff line number Diff line
@@ -13,5 +13,43 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
vec3 addFlareCircle(
    vec2 uv, vec2 sunPos, float distScale, float size, float chroAb, float definition) {
    float dR = distance(uv, distScale * (1. - chroAb) * sunPos) / (size * (1. - chroAb));
    float dG = distance(uv, distScale * 1. * sunPos) / (size);
    float dB = distance(uv, distScale * (1 + chroAb) * sunPos) / (size * (1. + chroAb));
    float wR = 1.0 - smoothstep(definition, 0.75, dR);
    float wG = 1.0 - smoothstep(definition, 0.75, dG);
    float wB = 1.0 - smoothstep(definition, 0.75, dB);
    return vec3(wR, wG, wB);
}

// TODO(b/347299395): to add flare
vec3 addFlareRing(vec2 uv, vec2 sunPos, float distScale, float size, float chroAb, float stroke) {
    float dR = distance(uv, distScale * (1. - chroAb) * sunPos) / (size * (1. - chroAb));
    float dG = distance(uv, distScale * 1. * sunPos) / (size);
    float dB = distance(uv, distScale * (1 + chroAb) * sunPos) / (size * (1. + chroAb));
    float wR = smoothstep(0.75 - stroke, 0.75, dR) - smoothstep(0.75, 0.75 + stroke, dR);
    float wG = smoothstep(0.75 - stroke, 0.75, dG) - smoothstep(0.75, 0.75 + stroke, dG);
    float wB = smoothstep(0.75 - stroke, 0.75, dB) - smoothstep(0.75, 0.75 + stroke, dB);
    return vec3(wR, wG, wB);
}

vec3 addFlareCircle(vec2 uv, vec2 sunPos, float distScale, float size, float chroAb) {
    return addFlareCircle(uv, sunPos, distScale, size, chroAb, 0.25);
}

vec3 addFlareDistorted(vec2 uv, vec2 sunPos, float distScale, float size, float chroAb) {
    vec2 uvd = uv*(length(uv));
    return addFlareCircle(uvd, sunPos, distScale, size, chroAb, 0.35);
}

vec3 addFlare(vec3 color, vec2 uv, vec2 sunPos, float intensity, float time) {
    vec3 ret = vec3(0.0);
    ret += vec3(0.7) * addFlareCircle(uv, sunPos, -0.1, 0.1, 0.04);
    ret += vec3(0.64) * addFlareCircle(uv, sunPos, 0.05, 0.035, 0.04);
    ret += vec3(0.5) * addFlareCircle(uv, sunPos, -0.22, 0.18, 0.04);
    ret += vec3(0.34) * addFlareRing(uv, sunPos, -0.35, 0.4, 0.02, 0.16);
    ret += vec3(0.52) * addFlareDistorted(uv, sunPos, -0.4, 0.3, 0.08);
    ret += vec3(0.57) * addFlareDistorted(uv, sunPos, 0.4, 0.15, 0.06);
    return mix(color.rgb, vec3(1., 0.95, 0.88), intensity * ret);
}
+101 −6
Original line number Diff line number Diff line
@@ -26,28 +26,123 @@ uniform mat3 transformMatrixBgd;

#include "shaders/constants.agsl"
#include "shaders/utils.agsl"
#include "shaders/simplex2d.agsl"
#include "shaders/simplex3d.agsl"

#include "shaders/lens_flare.agsl"

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

float calculateRay(float angle, float time) {
    /*
     * God rays oscilations. It works like a fourier series, using the the uv position angle
     * and time and phase to adjust how it looks.
     */
    float rays = 17.5 + 8.0 * sin(3. * angle + time);
    rays += 4.0 * sin(12. * angle - 0.3 * time);
    rays += 4.0 * sin(25. * angle + 0.9252 * time);
    rays += -1.8 * cos(38. * angle - 0.114 * time);
    rays += 0.45 * cos(60.124 * angle + 0.251 * time);
    return rays;
}

float godRays(vec2 uv, vec2 center, float phase, float frequency, float time, float intensity) {
    // Adjust position to center.
    uv -= center;
    // For each position, get the angle.
    float angle = atan(uv.y, uv.x);
    // The glow around the position of the sun.
    float sunGlow = 1.0 / (1. + 20.0 * length(uv));
    float rays = calculateRay(angle * frequency, phase + time);
    return intensity * sunGlow * (rays * 0.4 + 2 + 2 * length(uv));
}

vec3 addGodRays(
    vec3 background,
    vec2 fragCoord,
    vec2 uv,
    vec2 sunPos,
    float phase,
    float frequency,
    float timeSpeed) {
    float rays =
        godRays(
            uv,
            sunPos,
            phase,
            frequency,
            timeSpeed * time,
            intensity);
    // Dithering.
    rays -= triangleNoise(fragCoord.xy) * 0.025;
    rays = clamp(rays, 0., 1.);
    vec3 raysColor = mix(godRaysColor, min(godRaysColor + 0.5, vec3(1)), smoothstep(0.15, 0.6, rays));
    return normalBlendNotPremultiplied(background.rgb, raysColor, smoothstep(0.1, 1., rays));
}

float checkBrightnessGodRaysAtCenter(
    vec2 center,
    float phase,
    float frequency,
    float timeSpeed) {
    // For each position, get the angle.
    float angle = atan(-center.y, -center.x);
    float rays = calculateRay(angle * frequency, phase + timeSpeed * time);
    // Normalize [0, 1] the brightness.
    return smoothstep(-0.75, 35.25, rays);

}

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


    float2 uv = adjustedUvBackground / screenSize;
    float2 uv = 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

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

    // TODO(b/347299395): to add flare and sun effect background

    // add foreground
    color.rgb = normalBlend(color.rgb, colorForeground.rgb, colorForeground.a);

    // TODO(b/347299395): to add flare and sun effect foreground
    // Calculate brightness from sunrays.
    float brightnessSunray = checkBrightnessGodRaysAtCenter(sunPos, 10.0, 1.1, 0.9);
    brightnessSunray *= brightnessSunray;

    // Adjusts contrast and brightness.
    float compression = 0.88;
    float brightnessIncriease = 0.02;
    float noise = triangleNoise(fragCoord.xy + vec2(12.31, 1024.1241));
    color.rgb *= mix(1., compression + noise * 0.025, intensity);
    color.rgb += brightnessIncriease * intensity;

    // Adjust color grading for shadows and highlights.
    float lum = relativeLuminance(color.rgb);
    vec3 highlightColor = vec3(0.41, 0.69, 0.856);
    float highlightThres = 0.66;
    float highlightBlend = 0.30 +  + brightnessSunray * 0.1;
    vec3 shadowColor = vec3(0.756, 0.69, 0.31);
    float shadowThres = 0.33;
    float shadowBlend = 0.2 + brightnessSunray * 0.1;

    float highlightsMask = smoothstep(highlightThres, 1., lum);
    float shadowsMask = 1. - smoothstep(0., shadowThres, lum);

    color.rgb = normalBlendNotPremultiplied(
        color.rgb, shadowColor, intensity * shadowBlend * shadowsMask);
    color.rgb = normalBlendNotPremultiplied(
        color.rgb, highlightColor, intensity * highlightBlend * highlightsMask);

    // Add god rays.
    color.rgb = addGodRays(color.rgb, fragCoord.xy, uv, sunPos, 10.0, 1.1, 0.9);
    // Add flare.
    color.rgb = addFlare(color.rgb, uv, sunPos, (0.4 + 0.8 * brightnessSunray) * intensity, time);
    return color;
}
+14 −2
Original line number Diff line number Diff line
@@ -90,8 +90,16 @@ vec3 normalBlend(vec3 b, vec3 f, float o) {
    return b * (1. - o) + f;
}

vec3 screenBlend(vec3 b, float o) {
    return b * (1. - o) + o;
float screenBlend(float bgd, float fgd) {
    return mix(bgd, 1., fgd);
}

vec3 screenBlend(vec3 bgd, float fgd) {
    return mix(bgd, vec3(1.), fgd);
}

vec3 screenBlend(vec3 bgd, vec3 fgd) {
    return mix(bgd, vec3(1.), fgd);
}

/*
@@ -108,6 +116,10 @@ vec3 normalBlendNotPremultiplied(vec3 b, vec3 f, float o) {
    return mix(b, f, o);
}

float relativeLuminance(vec3 color) {
    return dot(vec3(0.2126, 0.7152, 0.0722), color);
}

/** Math Utils */
// function created on Grapher (equation decided by testing in Grapher).
float wiggle(float time, float wiggleSpeed) {
+2 −2
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@ import com.google.android.wallpaper.weathereffects.graphics.WeatherEffect
import com.google.android.wallpaper.weathereffects.graphics.utils.GraphicsUtils
import com.google.android.wallpaper.weathereffects.graphics.utils.MatrixUtils.centerCropMatrix
import com.google.android.wallpaper.weathereffects.graphics.utils.MatrixUtils.postprocessParallaxMatrix
import java.util.concurrent.TimeUnit
import com.google.android.wallpaper.weathereffects.graphics.utils.TimeUtils
import kotlin.random.Random

/** Defines and generates the sunny weather animation. */
@@ -59,7 +59,7 @@ class SunEffect(
    }

    override fun update(deltaMillis: Long, frameTimeNanos: Long) {
        elapsedTime += TimeUnit.MILLISECONDS.toSeconds(deltaMillis)
        elapsedTime += TimeUtils.millisToSeconds(deltaMillis)
        sunConfig.shader.setFloatUniform("time", elapsedTime)
        sunConfig.colorGradingShader.setInputShader("texture", sunConfig.shader)
    }