From 4d7c65ab00724da99b06cca22ed1cade7502cdf8 Mon Sep 17 00:00:00 2001 From: xumale Date: Mon, 9 Jun 2025 19:11:28 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E6=96=B0=E5=A2=9EcontentLight=20filter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BUILD.gn | 1 + include/ge_content_light_shader_filter.h | 56 +++++++++++++++++ include/ge_shader_filter_params.h | 14 +++++ include/ge_visual_effect.h | 3 + include/ge_visual_effect_impl.h | 15 +++++ src/ge_content_light_shader_filter.cpp | 80 ++++++++++++++++++++++++ src/ge_render.cpp | 6 ++ src/ge_visual_effect.cpp | 10 +++ src/ge_visual_effect_impl.cpp | 72 +++++++++++++++++++++ 9 files changed, 257 insertions(+) create mode 100644 include/ge_content_light_shader_filter.h create mode 100644 src/ge_content_light_shader_filter.cpp diff --git a/BUILD.gn b/BUILD.gn index e12ecf7..2cf2e1a 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -78,6 +78,7 @@ ohos_source_set("graphics_effect_src") { "src/ge_visual_effect_container.cpp", "src/ge_visual_effect_impl.cpp", "src/ge_water_ripple_filter.cpp", + "src/ge_content_light_filter.cpp", ] deps = [ ":utils" ] diff --git a/include/ge_content_light_shader_filter.h b/include/ge_content_light_shader_filter.h new file mode 100644 index 0000000..b65ddb6 --- /dev/null +++ b/include/ge_content_light_shader_filter.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * 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. + */ + #ifndef GRAPHICS_EFFECT_GE_WATER_RIPPLE_FILTER_H + #define GRAPHICS_EFFECT_GE_WATER_RIPPLE_FILTER_H + + #include + + #include "ge_shader_filter.h" + #include "ge_visual_effect.h" + + #include "draw/canvas.h" + #include "effect/color_filter.h" + #include "effect/runtime_effect.h" + #include "effect/runtime_shader_builder.h" + #include "image/image.h" + #include "utils/matrix.h" + #include "utils/rect.h" + + namespace OHOS { + namespace Rosen { + class GEContentLightFilter : public GEShaderFilter { + public: + GE_EXPORT GEContentLightFilter(const Drawing::GEContentLightFilterParams& params); + ~GEContentLightFilter() override = default; + + GE_EXPORT std::shared_ptr ProcessImage(Drawing::Canvas &canvas, + const std::shared_ptr image, const Drawing::Rect &src, const Drawing::Rect &dst) override; + + private: + std::shared_ptr GetContentLightEffect(); + + inline static const std::string shaderStringContentLight = R"( + )"; + + Vector3f lightPosition_; + Vector4f lightColor_; + float lightIntensity_; + Drawing::Matrix matrix_; + }; + + } // namespace Rosen + } // namespace OHOS + + #endif // GRAPHICS_EFFECT_GE_WATER_RIPPLE_FILTER_H \ No newline at end of file diff --git a/include/ge_shader_filter_params.h b/include/ge_shader_filter_params.h index c42f27d..947fa7f 100644 --- a/include/ge_shader_filter_params.h +++ b/include/ge_shader_filter_params.h @@ -19,6 +19,7 @@ #include #include +#include "common/rs_vector3.h" #include "common/rs_vector4.h" #include "utils/matrix.h" #include "ge_shader_mask.h" @@ -266,6 +267,19 @@ struct GEDispersionShaderFilterParams { float blueOffsetY; }; + +constexpr char GE_FILTER_CONTENT_LIGHT[] = "CONTENT_LIGHT"; +constexpr char GE_FILTER_CONTENT_LIGHT_POSITION[] = "CONTENT_LIGHT_POSITION"; +constexpr char GE_FILTER_CONTENT_LIGHT_COLOR[] = "CONTENT_LIGHT_CLOLOR"; +constexpr char GE_FILTER_CONTENT_LIGHT_INTENSITY[] = "CONTENT_LIGHT_INTENSITY"; +constexpr char GE_FILTER_CONTENT_LIGHT[] = "CONTENT_LIGHT_MATRIX"; +struct GEContentLightFilterParams { + Vector3f lightPosition; + Vector4f lightColor; + float lightIntensity; + Drawing::Matrix matrix; +}; + } // namespace Drawing } // namespace Rosen } // namespace OHOS diff --git a/include/ge_visual_effect.h b/include/ge_visual_effect.h index 0708f6c..404c542 100644 --- a/include/ge_visual_effect.h +++ b/include/ge_visual_effect.h @@ -18,6 +18,7 @@ #include #include +#include "common/rs_vector3.h" #include "common/rs_vector4.h" #include "effect/color_filter.h" #include "effect/runtime_effect.h" @@ -58,6 +59,8 @@ public: void SetParam(const std::string& tag, const std::vector param); void SetParam(const std::string& tag, const std::shared_ptr param); void SetParam(const std::string& tag, const Drawing::Color4f& param); + void SetParam(const std::string& tag, const Vector3f& param); + void SetParam(const std::string& tag, const Vector4f& param); const std::string& GetName() const { diff --git a/include/ge_visual_effect_impl.h b/include/ge_visual_effect_impl.h index 0e656f0..778cf76 100644 --- a/include/ge_visual_effect_impl.h +++ b/include/ge_visual_effect_impl.h @@ -23,6 +23,8 @@ #include "ge_shader_filter_params.h" #include "ge_visual_effect.h" +#include "common/rs_vector3.h" +#include "common/rs_vector4.h" #include "effect/color_filter.h" #include "effect/runtime_effect.h" #include "effect/runtime_shader_builder.h" @@ -79,6 +81,8 @@ public: void SetParam(const std::string& tag, const std::vector param); void SetParam(const std::string& tag, const std::shared_ptr param); void SetParam(const std::string& tag, const Drawing::Color4f& param); + void SetParam(const std::string& tag, const Vector3f& param); + void SetParam(const std::string& tag, const Vector4f& param); void SetFilterType(FilterType type) { @@ -220,6 +224,16 @@ public: return dispersionParams_; } + void MakeContentLightParams() + { + contentLightParams_ = std::make_shared(); + } + + const std::shared_ptr& GetContentLightParams() const + { + return contentLightParams_; + } + private: static std::map> g_initialMap; @@ -256,6 +270,7 @@ private: std::shared_ptr edgeLightParams_ = nullptr; std::shared_ptr bezierWarpParams_ = nullptr; std::shared_ptr dispersionParams_ = nullptr; + std::shared_ptr contentLightParams_ = nullptr; }; } // namespace Drawing diff --git a/src/ge_content_light_shader_filter.cpp b/src/ge_content_light_shader_filter.cpp new file mode 100644 index 0000000..90d76ba --- /dev/null +++ b/src/ge_content_light_shader_filter.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * 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. + */ + + + #include "ge_log.h" + #include "ge_content_light_filter.h" + + namespace OHOS { + namespace Rosen { + + GEContentLightFilter::GEContentLightFilter(const Drawing::GEContentLightFilterParams& params) + : lightPosition_(params.lightPosition), lightColor_(params.lightColor), lightIntensity_(params.lightIntensity), + matrix_(params.matrix) + {} + + std::shared_ptr GEContentLightFilter::ProcessImage(Drawing::Canvas& canvas, + const std::shared_ptr image, const Drawing::Rect& src, const Drawing::Rect& dst) + { + if (image == nullptr) { + LOGE("GEContentLightFilter::ProcessImage input is invalid"); + return nullptr; + } + + Drawing::Matrix matrix; + auto shader = Drawing::ShaderEffect::CreateImageShader(*image, Drawing::TileMode::CLAMP, + Drawing::TileMode::CLAMP, Drawing::SamplingOptions(Drawing::FilterMode::LINEAR), matrix); + auto imageInfo = image->GetImageInfo(); + float height = imageInfo.GetHeight(); + float width = imageInfo.GetWidth(); + if (height < 1e-6 || width < 1e-6) { + return nullptr; + } + auto contentLight = GetContentLightEffect(); + if (contentLight == nullptr) { + LOGE("GEContentLightFilter::ProcessImage g_contentLightEffect init failed"); + return nullptr; + } + Drawing::RuntimeShaderBuilder builder(contentLight); + // builder.SetChild("image", shader); + // builder.SetUniform("iResolution", width, height); + // builder.SetUniform("progress", progress_); + // builder.SetUniform("waveCount", static_cast(waveCount_)); + // builder.SetUniform("rippleCenter", rippleCenterX_, rippleCenterY_); + #ifdef RS_ENABLE_GPU + auto invertedImage = builder.MakeImage(canvas.GetGPUContext().get(), nullptr, imageInfo, false); + #else + auto invertedImage = builder.MakeImage(nullptr, nullptr, imageInfo, false); + #endif + if (invertedImage == nullptr) { + LOGE("GEContentLightFilter::ProcessImage make image failed"); + return nullptr; + } + return invertedImage; + } + + + std::shared_ptr GEContentLightFilter::GetContentLightEffect() + { + static std::shared_ptr contentLightEffect = nullptr; + if (contentLightEffect == nullptr) { + contentLightEffect = Drawing::RuntimeEffect::CreateForShader(shaderStringContentLight); + } + return contentLightEffect; + } + + + } // namespace Rosen + } // namespace OHOS \ No newline at end of file diff --git a/src/ge_render.cpp b/src/ge_render.cpp index 95d05ee..ac8540f 100644 --- a/src/ge_render.cpp +++ b/src/ge_render.cpp @@ -29,6 +29,7 @@ #include "ge_sound_wave_filter.h" #include "ge_external_dynamic_loader.h" #include "ge_edge_light_shader_filter.h" +#include "ge_content_light_shader_filter.h" namespace OHOS { @@ -204,6 +205,11 @@ std::vector> GERender::GenerateShaderFilter( shaderFilter = GenerateExtShaderFilter(ve); break; } + case Drawing::GEVisualEffectImpl::FilterType::CONTENT_LIGHT: { + const auto& contentLightParams = ve->GetContentLightParams(); + shaderFilter = std::make_shared(*contentLightParams); + break; + } default: break; } diff --git a/src/ge_visual_effect.cpp b/src/ge_visual_effect.cpp index 27e679f..4b80bf2 100644 --- a/src/ge_visual_effect.cpp +++ b/src/ge_visual_effect.cpp @@ -99,6 +99,16 @@ void GEVisualEffect::SetParam(const std::string& tag, const Drawing::Color4f& pa visualEffectImpl_->SetParam(tag, param); } +void GEVisualEffect::SetParam(const std::string& tag, const Vector3f& param) +{ + visualEffectImpl_->SetParam(tag, param); +} + +void GEVisualEffect::SetParam(const std::string& tag, const Vector3f& param) +{ + visualEffectImpl_->SetParam(tag, param); +} + } // namespace Drawing } // namespace Rosen } // namespace OHOS diff --git a/src/ge_visual_effect_impl.cpp b/src/ge_visual_effect_impl.cpp index f494c49..195ac77 100644 --- a/src/ge_visual_effect_impl.cpp +++ b/src/ge_visual_effect_impl.cpp @@ -19,6 +19,7 @@ #include "ge_log.h" #include "ge_external_dynamic_loader.h" #include "common/rs_vector4.h" +#include "common/rs_vector3.h" namespace OHOS { namespace Rosen { @@ -102,6 +103,12 @@ std::map> GEVisualEf impl->SetFilterType(GEVisualEffectImpl::FilterType::DISPERSION); impl->MakeDispersionParams(); } + }, + { GE_FILTER_CONTENT_LIGHT, + [](GEVisualEffectImpl* impl) { + impl->SetFilterType(GEVisualEffectImpl::FilterType::CONTENT_LIGHT); + impl->MakeContentFilterParams(); + } } }; @@ -243,6 +250,10 @@ void GEVisualEffectImpl::SetParam(const std::string& tag, float param) SetDispersionParams(tag, param); break; } + case FilterType::CONTENT_LIGHT: { + SetContentLightParams(tag, param); + break; + } default: break; } @@ -269,6 +280,16 @@ void GEVisualEffectImpl::SetParam(const std::string& tag, const Drawing::Matrix } break; } + case FilterType::CONTENT_LIGHT: { + if (contentLightrParams_ == nullptr) { + return; + } + + if (tag == GE_FILTER_CONTENT_LIGHT_MATRIX) { + contentLightrParams_->matrix = param; + } + break; + } default: break; } @@ -425,6 +446,40 @@ void GEVisualEffectImpl::SetParam(const std::string& tag, const std::shared_ptr< } } +void GEVisualEffectImpl::SetParam(const std::string& tag, const Vector3f param) +{ + switch (filterType_) { + case FilterType::CONTENT_LIGHT: { + if (contentLightParams_ == nullptr) { + return; + } + if (tag == GE_FILTER_CONTENT_LIGHT_POSITION) { + contentLightParams_->lightPosition = param; + } + break; + } + default: + break; + } +} + +void GEVisualEffectImpl::SetParam(const std::string& tag, const Vector4f param) +{ + switch (filterType_) { + case FilterType::CONTENT_LIGHT: { + if (contentLightParams_ == nullptr) { + return; + } + if (tag == GE_FILTER_CONTENT_LIGHT_COLOR) { + contentLightParams_->lightColor = param; + } + break; + } + default: + break; + } +} + void GEVisualEffectImpl::SetParam(const std::string& tag, const Drawing::Color4f& param) { switch (filterType_) { @@ -728,6 +783,23 @@ void GEVisualEffectImpl::SetDispersionParams(const std::string& tag, float param } } +void GEVisualEffectImpl::SetContentLightParams(const std::string& tag, float param) +{ + if (contentLightParams_ == nullptr) { + return; + } + + static std::unordered_map> actions = { + { GE_FILTER_CONTENT_LIGHT_INTENSITY, + [](GEVisualEffectImpl* obj, float p) { obj->contentLightParams_->lightIntensity = p; } }, + }; + + auto it = actions.find(tag); + if (it != actions.end()) { + it->second(this, param); + } +} + } // namespace Drawing } // namespace Rosen } // namespace OHOS -- Gitee From 518bbb97a05e33d147e10ba0a92cba74b92d7d7a Mon Sep 17 00:00:00 2001 From: xumale Date: Mon, 9 Jun 2025 19:13:20 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E6=96=B0=E5=A2=9EcontentLight=20filter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/ge_shader_filter_params.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/ge_shader_filter_params.h b/include/ge_shader_filter_params.h index 947fa7f..4b7a1a9 100644 --- a/include/ge_shader_filter_params.h +++ b/include/ge_shader_filter_params.h @@ -272,7 +272,7 @@ constexpr char GE_FILTER_CONTENT_LIGHT[] = "CONTENT_LIGHT"; constexpr char GE_FILTER_CONTENT_LIGHT_POSITION[] = "CONTENT_LIGHT_POSITION"; constexpr char GE_FILTER_CONTENT_LIGHT_COLOR[] = "CONTENT_LIGHT_CLOLOR"; constexpr char GE_FILTER_CONTENT_LIGHT_INTENSITY[] = "CONTENT_LIGHT_INTENSITY"; -constexpr char GE_FILTER_CONTENT_LIGHT[] = "CONTENT_LIGHT_MATRIX"; +constexpr char GE_FILTER_CONTENT_LIGHT_MATRIX[] = "CONTENT_LIGHT_MATRIX"; struct GEContentLightFilterParams { Vector3f lightPosition; Vector4f lightColor; -- Gitee From aa80a2291833c760899aeaf0f0895f3c070e00cc Mon Sep 17 00:00:00 2001 From: xumale Date: Tue, 10 Jun 2025 11:11:26 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BUILD.gn | 2 +- include/ge_content_light_shader_filter.h | 6 +++--- include/ge_visual_effect_impl.h | 2 ++ src/ge_content_light_shader_filter.cpp | 8 ++++---- src/ge_visual_effect.cpp | 2 +- src/ge_visual_effect_impl.cpp | 10 +++++----- 6 files changed, 16 insertions(+), 14 deletions(-) diff --git a/BUILD.gn b/BUILD.gn index 2cf2e1a..f5bab7b 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -78,7 +78,7 @@ ohos_source_set("graphics_effect_src") { "src/ge_visual_effect_container.cpp", "src/ge_visual_effect_impl.cpp", "src/ge_water_ripple_filter.cpp", - "src/ge_content_light_filter.cpp", + "src/ge_content_light_shader_filter.cpp", ] deps = [ ":utils" ] diff --git a/include/ge_content_light_shader_filter.h b/include/ge_content_light_shader_filter.h index b65ddb6..bd48fc1 100644 --- a/include/ge_content_light_shader_filter.h +++ b/include/ge_content_light_shader_filter.h @@ -12,8 +12,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #ifndef GRAPHICS_EFFECT_GE_WATER_RIPPLE_FILTER_H - #define GRAPHICS_EFFECT_GE_WATER_RIPPLE_FILTER_H + #ifndef GRAPHICS_EFFECT_GE_CONTENT_LIGHT_FILTER_H + #define GRAPHICS_EFFECT_GE_CONTENT_LIGHT_FILTER_H #include @@ -53,4 +53,4 @@ } // namespace Rosen } // namespace OHOS - #endif // GRAPHICS_EFFECT_GE_WATER_RIPPLE_FILTER_H \ No newline at end of file + #endif // GRAPHICS_EFFECT_GE_CONTENT_LIGHT_FILTER_H \ No newline at end of file diff --git a/include/ge_visual_effect_impl.h b/include/ge_visual_effect_impl.h index 778cf76..e6cadc5 100644 --- a/include/ge_visual_effect_impl.h +++ b/include/ge_visual_effect_impl.h @@ -57,6 +57,7 @@ public: EDGE_LIGHT, BEZIER_WARP, DISPERSION, + CONTENT_LIGHT, MAX }; @@ -250,6 +251,7 @@ private: void SetSoundWaveParamsFloat(const std::string& tag, float param); void SetEdgeLightParams(const std::string& tag, float param); void SetDispersionParams(const std::string& tag, float param); + void SetContentLightParams(const std::string& tag, float param); FilterType filterType_ = GEVisualEffectImpl::FilterType::NONE; diff --git a/src/ge_content_light_shader_filter.cpp b/src/ge_content_light_shader_filter.cpp index 90d76ba..72c2436 100644 --- a/src/ge_content_light_shader_filter.cpp +++ b/src/ge_content_light_shader_filter.cpp @@ -15,7 +15,7 @@ #include "ge_log.h" - #include "ge_content_light_filter.h" + #include "ge_content_light_shader_filter.h" namespace OHOS { namespace Rosen { @@ -48,9 +48,9 @@ return nullptr; } Drawing::RuntimeShaderBuilder builder(contentLight); - // builder.SetChild("image", shader); - // builder.SetUniform("iResolution", width, height); - // builder.SetUniform("progress", progress_); + builder.SetChild("image", shader); + builder.SetUniform("iResolution", width, height); + builder.SetUniform("lightIntensity", lightIntensity_); // builder.SetUniform("waveCount", static_cast(waveCount_)); // builder.SetUniform("rippleCenter", rippleCenterX_, rippleCenterY_); #ifdef RS_ENABLE_GPU diff --git a/src/ge_visual_effect.cpp b/src/ge_visual_effect.cpp index 4b80bf2..c1e95e2 100644 --- a/src/ge_visual_effect.cpp +++ b/src/ge_visual_effect.cpp @@ -104,7 +104,7 @@ void GEVisualEffect::SetParam(const std::string& tag, const Vector3f& param) visualEffectImpl_->SetParam(tag, param); } -void GEVisualEffect::SetParam(const std::string& tag, const Vector3f& param) +void GEVisualEffect::SetParam(const std::string& tag, const Vector4f& param) { visualEffectImpl_->SetParam(tag, param); } diff --git a/src/ge_visual_effect_impl.cpp b/src/ge_visual_effect_impl.cpp index 195ac77..96fb574 100644 --- a/src/ge_visual_effect_impl.cpp +++ b/src/ge_visual_effect_impl.cpp @@ -107,7 +107,7 @@ std::map> GEVisualEf { GE_FILTER_CONTENT_LIGHT, [](GEVisualEffectImpl* impl) { impl->SetFilterType(GEVisualEffectImpl::FilterType::CONTENT_LIGHT); - impl->MakeContentFilterParams(); + impl->MakeContentLightParams(); } } }; @@ -281,12 +281,12 @@ void GEVisualEffectImpl::SetParam(const std::string& tag, const Drawing::Matrix break; } case FilterType::CONTENT_LIGHT: { - if (contentLightrParams_ == nullptr) { + if (contentLightParams_ == nullptr) { return; } if (tag == GE_FILTER_CONTENT_LIGHT_MATRIX) { - contentLightrParams_->matrix = param; + contentLightParams_->matrix = param; } break; } @@ -446,7 +446,7 @@ void GEVisualEffectImpl::SetParam(const std::string& tag, const std::shared_ptr< } } -void GEVisualEffectImpl::SetParam(const std::string& tag, const Vector3f param) +void GEVisualEffectImpl::SetParam(const std::string& tag, const Vector3f& param) { switch (filterType_) { case FilterType::CONTENT_LIGHT: { @@ -463,7 +463,7 @@ void GEVisualEffectImpl::SetParam(const std::string& tag, const Vector3f param) } } -void GEVisualEffectImpl::SetParam(const std::string& tag, const Vector4f param) +void GEVisualEffectImpl::SetParam(const std::string& tag, const Vector4f& param) { switch (filterType_) { case FilterType::CONTENT_LIGHT: { -- Gitee From f5b323214e0c6531d1889062a1d239091ddc44c1 Mon Sep 17 00:00:00 2001 From: xumale Date: Fri, 13 Jun 2025 14:33:37 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E6=96=B0=E5=A2=9EcontentLight=20Filter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BUILD.gn | 2 +- include/ge_content_light_shader_filter.h | 81 ++++--- include/ge_shader_filter_params.h | 2 +- src/ge_content_light_shader_filter.cpp | 262 +++++++++++++++++------ 4 files changed, 238 insertions(+), 109 deletions(-) diff --git a/BUILD.gn b/BUILD.gn index f5bab7b..bc95b44 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -61,6 +61,7 @@ ohos_source_set("graphics_effect_src") { "src/ge_aibar_shader_filter.cpp", "src/ge_bezier_warp_shader_filter.cpp", "src/ge_color_gradient_shader_filter.cpp", + "src/ge_content_light_shader_filter.cpp", "src/ge_displacement_distort_shader_filter.cpp", "src/ge_edge_light_shader_filter.cpp", "src/ge_external_dynamic_loader.cpp", @@ -78,7 +79,6 @@ ohos_source_set("graphics_effect_src") { "src/ge_visual_effect_container.cpp", "src/ge_visual_effect_impl.cpp", "src/ge_water_ripple_filter.cpp", - "src/ge_content_light_shader_filter.cpp", ] deps = [ ":utils" ] diff --git a/include/ge_content_light_shader_filter.h b/include/ge_content_light_shader_filter.h index bd48fc1..bb2676b 100644 --- a/include/ge_content_light_shader_filter.h +++ b/include/ge_content_light_shader_filter.h @@ -12,45 +12,42 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #ifndef GRAPHICS_EFFECT_GE_CONTENT_LIGHT_FILTER_H - #define GRAPHICS_EFFECT_GE_CONTENT_LIGHT_FILTER_H - - #include - - #include "ge_shader_filter.h" - #include "ge_visual_effect.h" - - #include "draw/canvas.h" - #include "effect/color_filter.h" - #include "effect/runtime_effect.h" - #include "effect/runtime_shader_builder.h" - #include "image/image.h" - #include "utils/matrix.h" - #include "utils/rect.h" - - namespace OHOS { - namespace Rosen { - class GEContentLightFilter : public GEShaderFilter { - public: - GE_EXPORT GEContentLightFilter(const Drawing::GEContentLightFilterParams& params); - ~GEContentLightFilter() override = default; - - GE_EXPORT std::shared_ptr ProcessImage(Drawing::Canvas &canvas, - const std::shared_ptr image, const Drawing::Rect &src, const Drawing::Rect &dst) override; - - private: - std::shared_ptr GetContentLightEffect(); - - inline static const std::string shaderStringContentLight = R"( - )"; - - Vector3f lightPosition_; - Vector4f lightColor_; - float lightIntensity_; - Drawing::Matrix matrix_; - }; - - } // namespace Rosen - } // namespace OHOS - - #endif // GRAPHICS_EFFECT_GE_CONTENT_LIGHT_FILTER_H \ No newline at end of file +#ifndef GRAPHICS_EFFECT_GE_CONTENT_LIGHT_FILTER_H +#define GRAPHICS_EFFECT_GE_CONTENT_LIGHT_FILTER_H + +#include + +#include "ge_shader_filter.h" +#include "ge_visual_effect.h" + +#include "draw/canvas.h" +#include "effect/color_filter.h" +#include "effect/runtime_effect.h" +#include "effect/runtime_shader_builder.h" +#include "image/image.h" +#include "utils/matrix.h" +#include "utils/rect.h" + +namespace OHOS { +namespace Rosen { +class GEContentLightFilter : public GEShaderFilter { +public: + GE_EXPORT GEContentLightFilter(const Drawing::GEContentLightFilterParams& params); + ~GEContentLightFilter() override = default; + + GE_EXPORT std::shared_ptr ProcessImage(Drawing::Canvas &canvas, + const std::shared_ptr image, const Drawing::Rect &src, const Drawing::Rect &dst) override; + +private: + std::shared_ptr GetContentLightEffect(); + + Vector3f lightPosition_; + Vector4f lightColor_; + float lightIntensity_; + Drawing::Matrix matrix_; +}; + +} // namespace Rosen +} // namespace OHOS + +#endif // GRAPHICS_EFFECT_GE_CONTENT_LIGHT_FILTER_H \ No newline at end of file diff --git a/include/ge_shader_filter_params.h b/include/ge_shader_filter_params.h index 4b7a1a9..0ebea3b 100644 --- a/include/ge_shader_filter_params.h +++ b/include/ge_shader_filter_params.h @@ -270,7 +270,7 @@ struct GEDispersionShaderFilterParams { constexpr char GE_FILTER_CONTENT_LIGHT[] = "CONTENT_LIGHT"; constexpr char GE_FILTER_CONTENT_LIGHT_POSITION[] = "CONTENT_LIGHT_POSITION"; -constexpr char GE_FILTER_CONTENT_LIGHT_COLOR[] = "CONTENT_LIGHT_CLOLOR"; +constexpr char GE_FILTER_CONTENT_LIGHT_COLOR[] = "CONTENT_LIGHT_COLOR"; constexpr char GE_FILTER_CONTENT_LIGHT_INTENSITY[] = "CONTENT_LIGHT_INTENSITY"; constexpr char GE_FILTER_CONTENT_LIGHT_MATRIX[] = "CONTENT_LIGHT_MATRIX"; struct GEContentLightFilterParams { diff --git a/src/ge_content_light_shader_filter.cpp b/src/ge_content_light_shader_filter.cpp index 72c2436..40a7248 100644 --- a/src/ge_content_light_shader_filter.cpp +++ b/src/ge_content_light_shader_filter.cpp @@ -12,69 +12,201 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - - - #include "ge_log.h" - #include "ge_content_light_shader_filter.h" - - namespace OHOS { - namespace Rosen { - - GEContentLightFilter::GEContentLightFilter(const Drawing::GEContentLightFilterParams& params) - : lightPosition_(params.lightPosition), lightColor_(params.lightColor), lightIntensity_(params.lightIntensity), - matrix_(params.matrix) - {} - - std::shared_ptr GEContentLightFilter::ProcessImage(Drawing::Canvas& canvas, - const std::shared_ptr image, const Drawing::Rect& src, const Drawing::Rect& dst) - { - if (image == nullptr) { - LOGE("GEContentLightFilter::ProcessImage input is invalid"); - return nullptr; - } - - Drawing::Matrix matrix; - auto shader = Drawing::ShaderEffect::CreateImageShader(*image, Drawing::TileMode::CLAMP, - Drawing::TileMode::CLAMP, Drawing::SamplingOptions(Drawing::FilterMode::LINEAR), matrix); - auto imageInfo = image->GetImageInfo(); - float height = imageInfo.GetHeight(); - float width = imageInfo.GetWidth(); - if (height < 1e-6 || width < 1e-6) { - return nullptr; - } - auto contentLight = GetContentLightEffect(); - if (contentLight == nullptr) { - LOGE("GEContentLightFilter::ProcessImage g_contentLightEffect init failed"); - return nullptr; - } - Drawing::RuntimeShaderBuilder builder(contentLight); - builder.SetChild("image", shader); - builder.SetUniform("iResolution", width, height); - builder.SetUniform("lightIntensity", lightIntensity_); - // builder.SetUniform("waveCount", static_cast(waveCount_)); - // builder.SetUniform("rippleCenter", rippleCenterX_, rippleCenterY_); - #ifdef RS_ENABLE_GPU - auto invertedImage = builder.MakeImage(canvas.GetGPUContext().get(), nullptr, imageInfo, false); - #else - auto invertedImage = builder.MakeImage(nullptr, nullptr, imageInfo, false); - #endif - if (invertedImage == nullptr) { - LOGE("GEContentLightFilter::ProcessImage make image failed"); - return nullptr; - } - return invertedImage; - } - - - std::shared_ptr GEContentLightFilter::GetContentLightEffect() - { - static std::shared_ptr contentLightEffect = nullptr; - if (contentLightEffect == nullptr) { + + +#include "ge_log.h" +#include "ge_content_light_shader_filter.h" + +namespace OHOS { +namespace Rosen { + +constexpr size_t NUM_0 = 0; +constexpr size_t NUM_1 = 1; +constexpr size_t NUM_2 = 2; +constexpr size_t NUM_3 = 3; +constexpr size_t NUM_4 = 4; + +GEContentLightFilter::GEContentLightFilter(const Drawing::GEContentLightFilterParams& params) + : lightPosition_(params.lightPosition), lightColor_(params.lightColor), lightIntensity_(params.lightIntensity), + matrix_(params.matrix) +{} + +std::shared_ptr GEContentLightFilter::ProcessImage(Drawing::Canvas& canvas, + const std::shared_ptr image, const Drawing::Rect& src, const Drawing::Rect& dst) +{ + if (image == nullptr) { + LOGE("GEContentLightFilter::ProcessImage input is invalid"); + return nullptr; + } + + Drawing::Matrix matrix; + auto shader = Drawing::ShaderEffect::CreateImageShader(*image, Drawing::TileMode::CLAMP, + Drawing::TileMode::CLAMP, Drawing::SamplingOptions(Drawing::FilterMode::LINEAR), matrix); + auto imageInfo = image->GetImageInfo(); + float height = imageInfo.GetHeight(); + float width = imageInfo.GetWidth(); + matrix_ = canvas.GetTotalMatrix(); + if (height < 1e-6 || width < 1e-6) { + return nullptr; + } + auto contentLight = GetContentLightEffect(); + if (contentLight == nullptr) { + LOGE("GEContentLightFilter::ProcessImage g_contentLightEffect init failed"); + return nullptr; + } + float lightColor[NUM_4] = {lightColor_[NUM_0], lightColor_[NUM_1], lightColor_[NUM_2], lightColor_[NUM_3]}; + Drawing::RuntimeShaderBuilder builder(contentLight); + builder.SetChild("image", shader); + builder.SetUniform("iResolution", width, height); + builder.SetUniform("lightIntensity", lightIntensity_); + builder.SetUniform("lightPosition", lightPosition_[NUM_0], lightPosition_[NUM_1]. lightPosition_[NUM_2]); + builder.SetUniform("lightColor", lightColor_, 4); + builder.SetUniform("matrix", matrix_); +#ifdef RS_ENABLE_GPU + auto invertedImage = builder.MakeImage(canvas.GetGPUContext().get(), nullptr, imageInfo, false); +#else + auto invertedImage = builder.MakeImage(nullptr, nullptr, imageInfo, false); +#endif + if (invertedImage == nullptr) { + LOGE("GEContentLightFilter::ProcessImage make image failed"); + return nullptr; + } + return invertedImage; +} + + +std::shared_ptr GEContentLightFilter::GetContentLightEffect() +{ + static std::shared_ptr contentLightEffect = nullptr; + if (contentLightEffect == nullptr) { + const std::string shaderStringContentLight = R"( + uniform shader image; + uniform half2 iResolution; + uniform half lightIntensity; + uniform half3 lightPosition; + uniform half4 lightColor; + uniform mat3 matrix; + + const float cornerRadius = 30.0; + const float boundaryThickness = 5.0; + + // 计算圆角矩形SDF + float sdRoundedBox(vec2 p, vec2 b, float r) + { + vec2 q = abs(p)-b+r; + return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r; + } + + vec4 shinningEffect(in vec3 fragPos, in vec3 normal, in vec3 lightPos, in vec3 viewPos, + in vec4 specularColor, in float shinning) + { + vec3 lightDir = normalize(lightPos - fragPos); + vec3 viewDir = normalize(viewPos - fragPos); + vec3 halfwayDir = normalize(lightDir + viewDir); + + // Blinn-Phong + vec4 specularC = specularColor * pow(max(dot(normal, halfwayDir), 0.), shinning); + + return specularC; + } + + vec4 createContentNormal(vec2 pos, float maskAlpha) // pos in [-w, w] x [-1, 1] + { + if (maskAlpha < 0.01) { + return vec4(0.0, 0.0, -1.0, -1.0); + } + + ///////////////////////////////////////////////////////// + // 球面半径 = 4.0 * max(height, width) + // 球顶: z = sqrt(R^2 - x^2 - y^2) + h + // (x0, y0) x切向导数:2x0 / z0 + // (x0, y0) y切向导数:2y0 / z0 + // (x0, y0) 法向:normalize(2x0 / z0, 2y0 / z0, 1) + float R = max(width, height) * 4. / iResolution.y; + float z = sqrt(R * R - pos.x * pos.x - pos.y * pos.y); + vec3 normal = normalize(vec3(pos.x / z, pos.y / z, 0.5)); + + return vec4(normal, 1.); + } + + vec4 ContentShinning(vec2 uv, vec4 specularColor, float shinning, vec3 lightPos, vec3 viewPos, mat3 rotM, float maskAlpha) + { + vec3 fragPos = vec3(uv, 0.0); + vec4 normal = createContentNormal(uv, maskAlpha); + if (normal.w < 0.0) { + return vec4(0.0); + } + vec3 fragNormal = rotM * normal.xyz; + + vec4 shinningColor = shinningEffect(fragPos, fragNormal, lightPos, viewPos, specularColor, shinning); + // shinningColor *= smoothstep(0.0, 0.1, normal.w) * smoothstep(1.0, 0.9, normal.w); + return shinningColor; + } + + // 根据旋转前后法向量 计算旋转矩阵 + mat3 rotationMatrix(in vec3 originNormal, in vec3 centerNormal) + { + vec3 k = cross(originNormal, centerNormal); + mat3 R = mat3(1., 0., 0., 0., 1., 0., 0., 0., 1.); + if (length(k) < 1e-6) // 未区分平行和反向 + return R; + + float theta = acos(dot(originNormal, centerNormal)); + mat3 K = mat3(0., -k.z, k.y, + k.z, 0., -k.x, + -k.y, k.x, 0.); + R += sin(theta) * K + (1. - cos(theta)) * (K * K); + + return R; + } + + // test example + vec4 chessboardColor(in vec2 uv) + { + // random color + vec3 col = 0.5 + 0.5 * cos(uv.xyx + vec3(-1.5, 2.0, 4.0)); + // chessboard + float num = floor(uv.x * 5.0) + floor(uv.y * 5.0); + + return vec4(col, mod(num, 2.0)); + } + + // test example + vec4 DrawSmoothRRect(vec2 uv, vec2 center, vec2 halfWidthHeight, float radius) + { + radius = clamp(radius, 0.0, min(halfWidthHeight.x, halfWidthHeight.y)); + float dist = sdRoundedBox(uv - center, halfWidthHeight, radius); + + vec4 color = chessboardColor(uv); + + return dist < 0.0 ? smoothstep(0.0, -2.5 / iResolution.y, dist) * color : vec4(0.0); + } + + vec4 main(in vec2 fragCoord) + { + vec2 uv = fragCoord / iResolution.xy; + uv = uv + uv - 1.0; + float screenRatio = iResolution.x / iResolution.y; + uv.x *= screenRatio; + + float alpha = 0.7; + mat3 rotM = matrix; + vec4 specularColor = lightColor; + float shinning = 8.0; + vec3 lightPos = lightPosition; + + vec3 viewPos = lightPos; + + vec4 inputImage = image.eval(fragCoord); + vec4 shinningColor = ContentShinning(uv, specularColor, shinning, lightPos, viewPos, rotM, inputImage.w); + + return vec4(inputImage.rgb + shinningColor.rgb * lightIntensity, 1.0); + } + + )"; contentLightEffect = Drawing::RuntimeEffect::CreateForShader(shaderStringContentLight); - } - return contentLightEffect; - } - - - } // namespace Rosen - } // namespace OHOS \ No newline at end of file + } + return contentLightEffect; +} +} // namespace Rosen +} // namespace OHOS \ No newline at end of file -- Gitee From ee05043727558f257d5d6f9bad5479ced6701e27 Mon Sep 17 00:00:00 2001 From: xumale Date: Fri, 13 Jun 2025 16:09:52 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ge_content_light_shader_filter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ge_content_light_shader_filter.cpp b/src/ge_content_light_shader_filter.cpp index 40a7248..69e1846 100644 --- a/src/ge_content_light_shader_filter.cpp +++ b/src/ge_content_light_shader_filter.cpp @@ -59,8 +59,8 @@ std::shared_ptr GEContentLightFilter::ProcessImage(Drawing::Canv builder.SetChild("image", shader); builder.SetUniform("iResolution", width, height); builder.SetUniform("lightIntensity", lightIntensity_); - builder.SetUniform("lightPosition", lightPosition_[NUM_0], lightPosition_[NUM_1]. lightPosition_[NUM_2]); - builder.SetUniform("lightColor", lightColor_, 4); + builder.SetUniform("lightPosition", lightPosition_[NUM_0], lightPosition_[NUM_1], lightPosition_[NUM_2]); + builder.SetUniform("lightColor", lightColor, 4); builder.SetUniform("matrix", matrix_); #ifdef RS_ENABLE_GPU auto invertedImage = builder.MakeImage(canvas.GetGPUContext().get(), nullptr, imageInfo, false); -- Gitee