1/* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17uniform shader texture; 18uniform float time; 19uniform float screenAspectRatio; 20uniform float2 screenSize; 21uniform half intensity; 22 23#include "shaders/constants.agsl" 24#include "shaders/utils.agsl" 25#include "shaders/glass_rain.agsl" 26#include "shaders/rain_constants.agsl" 27 28vec4 main(float2 fragCoord) { 29 // 0. Add a bit of noise so that the droplets are not perfect circles. 30 fragCoord += vec2(valueNoise(fragCoord) * 0.015 - 0.0025); 31 32 float2 uv = fragCoord / screenSize; 33 34 // 1. Generate small glass rain. 35 GlassRain smallDrippingRain = generateGlassRain( 36 uv, 37 screenAspectRatio, 38 time, 39 /* Grid size = */ vec2(4.0, 2.0), 40 intensity); 41 float dropMask = smallDrippingRain.dropMask; 42 float droppletsMask = smallDrippingRain.droppletsMask; 43 float trailMask = smallDrippingRain.trailMask; 44 vec2 dropUvMasked = smallDrippingRain.drop * dropMask; 45 vec2 droppletsUvMasked = smallDrippingRain.dropplets * droppletsMask; 46 47 // 2. Generate medium size glass rain. 48 GlassRain medDrippingRain = generateGlassRain( 49 uv, 50 screenAspectRatio, 51 time * 1.267, 52 /* Grid size = */ vec2(3.5, 1.5), 53 intensity); 54 55 // 3. Combine those two glass rains. 56 dropMask = max(medDrippingRain.dropMask, dropMask); 57 droppletsMask = max(medDrippingRain.droppletsMask, droppletsMask); 58 trailMask = max(medDrippingRain.trailMask, trailMask); 59 dropUvMasked = mix(dropUvMasked, 60 medDrippingRain.drop * medDrippingRain.dropMask, medDrippingRain.dropMask); 61 droppletsUvMasked = mix(droppletsUvMasked, 62 medDrippingRain.dropplets * medDrippingRain.droppletsMask, medDrippingRain.droppletsMask); 63 64 // 4. Add static rain droplets on the glass surface. (They stay in place and dissapate.) 65 vec3 staticRain = generateStaticGlassRain(uv, screenAspectRatio, time, intensity); 66 dropMask = max(dropMask, staticRain.z); 67 dropUvMasked = mix(dropUvMasked, staticRain.xy * staticRain.z, staticRain.z); 68 69 // 5. Distort uv for the rain drops and dropplets. 70 float distortionDrop = -0.1; 71 vec2 uvDiffractionOffsets = 72 distortionDrop * dropUvMasked; 73 vec2 s = screenSize; 74 // Ensure the diffracted image in drops is not inverted. 75 s.y *= -1; 76 77 vec4 color = texture.eval(fragCoord); 78 vec3 sampledColor = texture.eval(fragCoord + uvDiffractionOffsets * s).rgb; 79 color.rgb = mix(color.rgb, sampledColor, max(dropMask, droppletsMask)); 80 81 // 6. Add color tint to the rain drops. 82 color.rgb = mix( 83 color.rgb, 84 dropTint, 85 dropTintIntensity * smoothstep(0.7, 1., max(dropMask, droppletsMask))); 86 87 // 7. Add highlight to the drops. 88 color.rgb = mix( 89 color.rgb, 90 highlightColor, 91 highlightIntensity 92 * smoothstep(0.05, 0.08, max(dropUvMasked * 1.7, droppletsUvMasked * 2.6)).x); 93 94 // 8. Add shadows to the drops. 95 color.rgb = mix( 96 color.rgb, 97 contactShadowColor, 98 dropShadowIntensity * 99 smoothstep(0.055, 0.1, max(length(dropUvMasked * 1.7), 100 length(droppletsUvMasked * 1.9)))); 101 102 return color; 103}