| /* |
| * Copyright (C) 2010 University of Szeged |
| * Copyright (C) 2010 Zoltan Herczeg |
| * Copyright (C) 2013 Google Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY |
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF SZEGED OR |
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #include "third_party/blink/renderer/platform/graphics/filters/fe_lighting.h" |
| |
| #include "third_party/blink/renderer/platform/graphics/filters/distant_light_source.h" |
| #include "third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.h" |
| #include "third_party/blink/renderer/platform/graphics/filters/point_light_source.h" |
| #include "third_party/blink/renderer/platform/graphics/filters/spot_light_source.h" |
| #include "third_party/skia/include/core/SkPoint3.h" |
| |
| namespace blink { |
| |
| FELighting::FELighting(Filter* filter, |
| LightingType lighting_type, |
| const Color& lighting_color, |
| float surface_scale, |
| float diffuse_constant, |
| float specular_constant, |
| float specular_exponent, |
| scoped_refptr<LightSource> light_source) |
| : FilterEffect(filter), |
| lighting_type_(lighting_type), |
| light_source_(std::move(light_source)), |
| lighting_color_(lighting_color), |
| surface_scale_(surface_scale), |
| diffuse_constant_(std::max(diffuse_constant, 0.0f)), |
| specular_constant_(std::max(specular_constant, 0.0f)), |
| specular_exponent_(clampTo(specular_exponent, 1.0f, 128.0f)) {} |
| |
| sk_sp<PaintFilter> FELighting::CreateImageFilter() { |
| if (!light_source_) |
| return CreateTransparentBlack(); |
| base::Optional<PaintFilter::CropRect> crop_rect = GetCropRect(); |
| const PaintFilter::CropRect* rect = base::OptionalOrNullptr(crop_rect); |
| Color light_color = AdaptColorToOperatingInterpolationSpace(lighting_color_); |
| sk_sp<PaintFilter> input(paint_filter_builder::Build( |
| InputEffect(0), OperatingInterpolationSpace())); |
| switch (light_source_->GetType()) { |
| case LS_DISTANT: { |
| DistantLightSource* distant_light_source = |
| static_cast<DistantLightSource*>(light_source_.get()); |
| float azimuth_rad = deg2rad(distant_light_source->Azimuth()); |
| float elevation_rad = deg2rad(distant_light_source->Elevation()); |
| const SkPoint3 direction = SkPoint3::Make( |
| cosf(azimuth_rad) * cosf(elevation_rad), |
| sinf(azimuth_rad) * cosf(elevation_rad), sinf(elevation_rad)); |
| return sk_make_sp<LightingDistantPaintFilter>( |
| GetLightingType(), direction, light_color.Rgb(), surface_scale_, |
| GetFilterConstant(), specular_exponent_, std::move(input), rect); |
| } |
| case LS_POINT: { |
| PointLightSource* point_light_source = |
| static_cast<PointLightSource*>(light_source_.get()); |
| const FloatPoint3D position = point_light_source->GetPosition(); |
| const SkPoint3 sk_position = |
| SkPoint3::Make(position.X(), position.Y(), position.Z()); |
| return sk_make_sp<LightingPointPaintFilter>( |
| GetLightingType(), sk_position, light_color.Rgb(), surface_scale_, |
| GetFilterConstant(), specular_exponent_, std::move(input), rect); |
| } |
| case LS_SPOT: { |
| SpotLightSource* spot_light_source = |
| static_cast<SpotLightSource*>(light_source_.get()); |
| const SkPoint3 location = |
| SkPoint3::Make(spot_light_source->GetPosition().X(), |
| spot_light_source->GetPosition().Y(), |
| spot_light_source->GetPosition().Z()); |
| const SkPoint3 target = |
| SkPoint3::Make(spot_light_source->Direction().X(), |
| spot_light_source->Direction().Y(), |
| spot_light_source->Direction().Z()); |
| float specular_exponent = spot_light_source->SpecularExponent(); |
| float limiting_cone_angle = spot_light_source->LimitingConeAngle(); |
| if (!limiting_cone_angle || limiting_cone_angle > 90 || |
| limiting_cone_angle < -90) |
| limiting_cone_angle = 90; |
| return sk_make_sp<LightingSpotPaintFilter>( |
| GetLightingType(), location, target, specular_exponent, |
| limiting_cone_angle, light_color.Rgb(), surface_scale_, |
| GetFilterConstant(), specular_exponent_, std::move(input), rect); |
| } |
| default: |
| NOTREACHED(); |
| return nullptr; |
| } |
| } |
| |
| PaintFilter::LightingType FELighting::GetLightingType() { |
| return specular_constant_ > 0 ? PaintFilter::LightingType::kSpecular |
| : PaintFilter::LightingType::kDiffuse; |
| } |
| |
| float FELighting::GetFilterConstant() { |
| return GetLightingType() == PaintFilter::LightingType::kSpecular |
| ? specular_constant_ |
| : diffuse_constant_; |
| } |
| |
| } // namespace blink |