chromium/third_party/skia/modules/skottie/src/effects/SphereEffect.cpp

/*
 * Copyright 2021 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/core/SkBlendMode.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkM44.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPicture.h"
#include "include/core/SkPictureRecorder.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkScalar.h"
#include "include/core/SkShader.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkTileMode.h"
#include "include/effects/SkRuntimeEffect.h"
#include "include/private/base/SkAssert.h"
#include "include/private/base/SkPoint_impl.h"
#include "include/private/base/SkTPin.h"
#include "modules/skottie/src/Adapter.h"
#include "modules/skottie/src/SkottiePriv.h"
#include "modules/skottie/src/SkottieValue.h"
#include "modules/skottie/src/effects/Effects.h"
#include "modules/sksg/include/SkSGNode.h"
#include "modules/sksg/include/SkSGRenderNode.h"

#include <array>
#include <cmath>
#include <cstdio>
#include <utility>
#include <vector>

namespace skjson {
class ArrayValue;
}
namespace sksg {
class InvalidationController;
}

namespace skottie::internal {
namespace {

// This shader maps its child shader onto a sphere.  To simplify things, we set it up such that:
//
//   - the sphere is centered at origin and has r == 1
//   - the eye is positioned at (0,0,eye_z), where eye_z is chosen to visually match AE
//   - the POI for a given pixel is on the z = 0 plane (x,y,0)
//   - we're only rendering inside the projected circle, which guarantees a quadratic solution
//
// Effect stages:
//
//   1) ray-cast to find the sphere intersection (selectable front/back solution);
//      given the sphere geometry, this is also the normal
//   2) rotate the normal
//   3) UV-map the sphere
//   4) scale uv to source size and sample
//   5) apply lighting model
//
// Note: the current implementation uses two passes for two-side ("full") rendering, on the
//       assumption that in practice most textures are opaque and two-side mode is infrequent;
//       if this proves to be problematic, we could expand the implementation to blend both sides
//       in one pass.
//
static constexpr char gSphereSkSL[] =
;

// CC Sphere uses a Phong-like lighting model:
//
//   - "ambient" controls the intensity of the texture color
//   - "diffuse" controls a multiplicative mix of texture and light color
//   - "specular" controls a light color specular component
//   - "roughness" is the specular exponent reciprocal
//   - "light intensity" modulates the diffuse and specular components (but not ambient)
//   - "light height" and "light direction" specify the light source position in spherical coords
//
// Implementation-wise, light intensity/height/direction are all combined into l_vec.
// For efficiency, we fall back to a stripped-down shader (ambient-only) when the diffuse & specular
// components are not used.
//
// TODO: "metal" and "reflective" parameters are ignored.
static constexpr char gBasicLightSkSL[] =
;

static constexpr char gFancyLightSkSL[] =
;

static sk_sp<SkRuntimeEffect> sphere_fancylight_effect() {}

static sk_sp<SkRuntimeEffect> sphere_basiclight_effect() {}

class SphereNode final : public sksg::CustomRenderNode {};

class SphereAdapter final : public DiscardableAdapterBase<SphereAdapter, SphereNode> {};

} // namespace

sk_sp<sksg::RenderNode> EffectBuilder::attachSphereEffect(
        const skjson::ArrayValue& jprops, sk_sp<sksg::RenderNode> layer) const {}

} // namespace skottie::internal