• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include <algorithm>
16 #include "ge_log.h"
17 #include "ge_wavy_ripple_light_shader.h"
18 
19 namespace OHOS {
20 namespace Rosen {
21 namespace {
22 static constexpr char WAVY_PROG[] = R"(
23     uniform vec2 iResolution;
24     uniform vec2 center;
25     uniform float radius;
26     uniform float thickness;
27     const float noiseScale = 0.3;
28     const float waveScale  = 0.5;
29     const float freqX = 4.0;
30     const float freqY = 6.0;
31     const float freqDiag = 8.0;
32     float shapeSDF(vec2 p, float radius)
33     {
34         float dist = length(p);
35         float noise = 0.0;
36         noise += sin(p.x * freqX) * 0.25;
37         noise += sin(p.y * freqY) * 0.35;
38         noise += sin((p.x + p.y) * freqDiag) * 0.1;
39         float distortedDist = dist + noise * noiseScale;
40         float attenuation = waveScale / (1.0 + distortedDist * 5.0);
41         float wave = sin(distortedDist * 30.0) * attenuation;
42         return distortedDist - radius + wave * 0.05;
43     }
44     vec4 main(vec2 fragCoord)
45     {
46         vec2 uv = fragCoord.xy / iResolution.xy;
47         float aspect = iResolution.x / iResolution.y;
48         vec3 color = vec3(0.0);
49         vec2 p = uv * 2.0 - 1.0;
50         p.x *= aspect;
51         vec2 c = center * 2.0 - 1.0;
52         c.x *= aspect;
53         vec2 delta = p - c;
54         float dist0 = length(c - vec2(-aspect, -1.0));
55         float dist1 = length(c - vec2(-aspect,  1.0));
56         float dist2 = length(c - vec2(aspect, -1.0));
57         float dist3 = length(c - vec2(aspect,  1.0));
58         float maxRadius = thickness + max(max(dist0, dist1), max(dist2, dist3));
59         float currentRadius = maxRadius * radius;
60         float d = abs(shapeSDF(delta, currentRadius));
61         float mask = smoothstep(thickness, 0.0, d);
62         vec3 baseColor = vec3(0.8, 0.5, 1.0);
63         color = baseColor * mask;
64         return vec4(color, mask);
65     }
66 )";
67 } // anonymous namespace
GEWavyRippleLightShader()68 GEWavyRippleLightShader::GEWavyRippleLightShader() {}
69 
GEWavyRippleLightShader(Drawing::GEWavyRippleLightShaderParams & param)70 GEWavyRippleLightShader::GEWavyRippleLightShader(Drawing::GEWavyRippleLightShaderParams& param)
71 {
72     wavyRippleLightParams_ = param;
73 }
74 
CreateWavyRippleLightShader(Drawing::GEWavyRippleLightShaderParams & param)75 std::shared_ptr<GEWavyRippleLightShader> GEWavyRippleLightShader::CreateWavyRippleLightShader(
76     Drawing::GEWavyRippleLightShaderParams& param)
77 {
78     std::shared_ptr<GEWavyRippleLightShader> wavyRippleLightShader = std::make_shared<GEWavyRippleLightShader>(param);
79     return wavyRippleLightShader;
80 }
81 
MakeDrawingShader(const Drawing::Rect & rect,float progress)82 void GEWavyRippleLightShader::MakeDrawingShader(const Drawing::Rect& rect, float progress)
83 {
84     drShader_ = MakeWavyRippleLightShader(rect);
85 }
86 
GetWavyRippleLightBuilder()87 std::shared_ptr<Drawing::RuntimeShaderBuilder> GEWavyRippleLightShader::GetWavyRippleLightBuilder()
88 {
89     thread_local std::shared_ptr<Drawing::RuntimeEffect> wavyRippleLightShaderEffect_ = nullptr;
90 
91     if (wavyRippleLightShaderEffect_ == nullptr) {
92         wavyRippleLightShaderEffect_ = Drawing::RuntimeEffect::CreateForShader(WAVY_PROG);
93     }
94     if (wavyRippleLightShaderEffect_ == nullptr) {
95         GE_LOGE("GEWavyRippleLightShader::GetWavyRippleLightBuilder wavyRippleLightShaderEffect_ is nullptr.");
96         return nullptr;
97     }
98     return std::make_shared<Drawing::RuntimeShaderBuilder>(wavyRippleLightShaderEffect_);
99 }
100 
MakeWavyRippleLightShader(const Drawing::Rect & rect)101 std::shared_ptr<Drawing::ShaderEffect> GEWavyRippleLightShader::MakeWavyRippleLightShader(const Drawing::Rect& rect)
102 {
103     auto width = rect.GetWidth();
104     auto height = rect.GetHeight();
105     builder_ = GetWavyRippleLightBuilder();
106     builder_->SetUniform("iResolution", width, height);
107     builder_->SetUniform("center", wavyRippleLightParams_.center_.first,
108         wavyRippleLightParams_.center_.second);
109     builder_->SetUniform("radius", std::max(0.0f, wavyRippleLightParams_.radius_));
110     builder_->SetUniform("thickness", std::max(0.01f, wavyRippleLightParams_.thickness_)); // 0.01f: minimum thickness
111     auto wavyRippleLightShader = builder_->MakeShader(nullptr, false);
112     if (wavyRippleLightShader == nullptr) {
113         GE_LOGE("GEWavyRippleLightShader::MakeWavyRippleLightShader wavyRippleLightShader is nullptr.");
114         return nullptr;
115     }
116     return wavyRippleLightShader;
117 }
118 
119 } // namespace Rosen
120 } // namespace OHOS