45class InvalidationController;
83static constexpr char gNoiseEffectSkSL[] =
84 "uniform float3x3 u_submatrix;"
86 "uniform float2 u_noise_planes;"
87 "uniform float u_noise_weight,"
92 "float hash(float3 v) {"
93 "v = fract(v*0.1031);"
94 "v += dot(v, v.zxy + 31.32);"
95 "return fract((v.x + v.y)*v.z);"
101 "float sample_noise(float2 xy) {"
104 "float n0 = hash(float3(xy, u_noise_planes.x)),"
105 "n1 = hash(float3(xy, u_noise_planes.y));"
110 "return mix(n0, n1, u_noise_weight);"
120 "float4 main(vec2 xy) {"
121 "float oct = u_octaves,"
128 "for (float i = 0; i < %u; ++i) {"
132 "float w = amp*min(oct,1.0);"
134 "n += w*fractal(filter(xy));"
137 "if (oct <= 1.0) { break; }"
140 "amp *= u_persistence;"
141 "xy = (u_submatrix*float3(xy,1)).xy;"
148 "return float4(n,n,n,1);"
151static constexpr char gFilterNearestSkSL[] =
152 "float filter(float2 xy) {"
153 "return sample_noise(xy);"
156static constexpr char gFilterLinearSkSL[] =
157 "float filter(float2 xy) {"
160 "float n00 = sample_noise(xy + float2(0,0)),"
161 "n10 = sample_noise(xy + float2(1,0)),"
162 "n01 = sample_noise(xy + float2(0,1)),"
163 "n11 = sample_noise(xy + float2(1,1));"
165 "float2 t = fract(xy);"
167 "return mix(mix(n00, n10, t.x), mix(n01, n11, t.x), t.y);"
170static constexpr char gFilterSoftLinearSkSL[] =
171 "float filter(float2 xy) {"
174 "float n00 = sample_noise(xy + float2(0,0)),"
175 "n10 = sample_noise(xy + float2(1,0)),"
176 "n01 = sample_noise(xy + float2(0,1)),"
177 "n11 = sample_noise(xy + float2(1,1));"
179 "float2 t = smoothstep(0, 1, fract(xy));"
181 "return mix(mix(n00, n10, t.x), mix(n01, n11, t.x), t.y);"
184static constexpr char gFractalBasicSkSL[] =
185 "float fractal(float n) {"
189static constexpr char gFractalTurbulentBasicSkSL[] =
190 "float fractal(float n) {"
191 "return 2*abs(0.5 - n);"
194static constexpr char gFractalTurbulentSmoothSkSL[] =
195 "float fractal(float n) {"
196 "n = 2*abs(0.5 - n);"
200static constexpr char gFractalTurbulentSharpSkSL[] =
201 "float fractal(float n) {"
202 "return sqrt(2*abs(0.5 - n));"
205enum class NoiseFilter {
212enum class NoiseFractal {
223 return std::move(
result.effect);
227 static constexpr char const* gFilters[] = {
230 gFilterSoftLinearSkSL
233 static constexpr char const* gFractals[] = {
235 gFractalTurbulentBasicSkSL,
236 gFractalTurbulentSmoothSkSL,
237 gFractalTurbulentSharpSkSL
249 static constexpr BinInfo kLoopBins[] = {
258 auto bin_index = [](
float octaves) {
262 if (octaves > kLoopBins[
i].threshold) {
273 const size_t bin = bin_index(octaves);
275 auto& effect = kEffectCache[bin]
276 [
static_cast<size_t>(filter)]
277 [
static_cast<size_t>(fractal)];
279 effect = make_noise_effect(kLoopBins[bin].loops,
280 gFilters[
static_cast<size_t>(filter)],
281 gFractals[
static_cast<size_t>(fractal)])
306 case NoiseFractal::kBasic:
307 return noise_effect(fOctaves, filter, NoiseFractal::kBasic);
308 case NoiseFractal::kTurbulentBasic:
309 return noise_effect(fOctaves, filter, NoiseFractal::kTurbulentBasic);
310 case NoiseFractal::kTurbulentSmooth:
311 return noise_effect(fOctaves, filter, NoiseFractal::kTurbulentSmooth);
312 case NoiseFractal::kTurbulentSharp:
313 return noise_effect(fOctaves, filter, NoiseFractal::kTurbulentSharp);
320 case NoiseFilter::kNearest :
return this->getEffect(NoiseFilter::kNearest);
322 case NoiseFilter::kSoftLinear:
return this->getEffect(NoiseFilter::kSoftLinear);
330 builder.uniform(
"u_noise_planes") = fNoisePlanes;
331 builder.uniform(
"u_noise_weight") = fNoiseWeight;
332 builder.uniform(
"u_octaves" ) = fOctaves;
333 builder.uniform(
"u_persistence" ) = fPersistence;
334 builder.uniform(
"u_submatrix" ) = std::array<float,9>{
335 fSubMatrix.
rc(0,0), fSubMatrix.
rc(1,0), fSubMatrix.
rc(2,0),
336 fSubMatrix.
rc(0,1), fSubMatrix.
rc(1,1), fSubMatrix.
rc(2,1),
337 fSubMatrix.
rc(0,2), fSubMatrix.
rc(1,2), fSubMatrix.
rc(2,2),
344 const auto& child = this->children()[0];
345 const auto bounds = child->revalidate(ic, ctm);
347 fEffectShader = this->buildEffectShader();
352 void onRender(
SkCanvas* canvas,
const RenderContext* ctx)
const override {
354 const auto local_ctx = ScopedRenderContext(canvas, ctx)
358 this->children()[0]->render(canvas, local_ctx);
367 const RenderNode* onNodeAt(
const SkPoint&)
const override {
return nullptr; }
373 NoiseFilter fFilter = NoiseFilter::kNearest;
374 NoiseFractal fFractal = NoiseFractal::kBasic;
375 SkV2 fNoisePlanes = {0,0};
376 float fNoiseWeight = 0,
383class FractalNoiseAdapter final :
public DiscardableAdapterBase<FractalNoiseAdapter,
387 const AnimationBuilder* abuilder,
391 EffectBinder(jprops, *abuilder,
this)
392 .bind( 0, fFractalType )
393 .bind( 1, fNoiseType )
395 .bind( 3, fContrast )
396 .bind( 4, fBrightness )
399 .bind( 7, fRotation )
400 .bind( 8, fUniformScaling )
402 .bind(10, fScaleWidth )
403 .bind(11, fScaleHeight )
407 .bind(15, fComplexity )
409 .bind(17, fSubInfluence )
410 .bind(18, fSubScale )
411 .bind(19, fSubRotation )
412 .bind(20, fSubOffset )
415 .bind(23, fEvolution )
417 .bind(25, fCycleEvolution )
418 .bind(26, fCycleRevolutions)
419 .bind(27, fRandomSeed )
421 .bind(29, fOpacity );
426 std::tuple<SkV2, float> noise()
const {
428 static constexpr auto kEvolutionScale = 0.25f;
443 cycle = fCycleEvolution
447 scale = fCycleEvolution
450 offset =
SkRandom(static_cast<uint32_t>(fRandomSeed)).nextRangeU(0, 100),
456 auto glsl_mod = [](
float x,
float y) {
460 const SkV2 noise_planes = {
461 glsl_mod(evo_ + 0, cycle) +
offset,
462 glsl_mod(evo_ + 1, cycle) +
offset,
465 return std::make_tuple(noise_planes, weight);
469 static constexpr float kGridSize = 64;
472 ?
SkV2{fScale, fScale}
473 :
SkV2{fScaleWidth, fScaleHeight};
483 const auto scale = 100 /
SkTPin(fSubScale, 10.0f, 10000.0f);
490 NoiseFilter noiseFilter()
const {
492 case 1:
return NoiseFilter::kNearest;
494 default:
return NoiseFilter::kSoftLinear;
499 NoiseFractal noiseFractal()
const {
501 case 1:
return NoiseFractal::kBasic;
502 case 3:
return NoiseFractal::kTurbulentSmooth;
503 case 4:
return NoiseFractal::kTurbulentBasic;
504 default:
return NoiseFractal::kTurbulentSharp;
509 void onSync()
override {
510 const auto& n = this->node();
512 const auto [noise_planes, noise_weight] = this->noise();
514 n->setOctaves(
SkTPin(fComplexity, 1.0f, 20.0f));
515 n->setPersistence(
SkTPin(fSubInfluence * 0.01f, 0.0f, 100.0f));
516 n->setNoisePlanes(noise_planes);
517 n->setNoiseWeight(noise_weight);
518 n->setNoiseFilter(this->noiseFilter());
519 n->setNoiseFractal(this->noiseFractal());
520 n->setMatrix(this->shaderMatrix());
521 n->setSubMatrix(this->subMatrix());
543 fCycleRevolutions = 0,
551 using INHERITED = DiscardableAdapterBase<FractalNoiseAdapter, FractalNoiseNode>;
558 auto fractal_noise = sk_make_sp<FractalNoiseNode>(std::move(layer));
561 std::move(fractal_noise));
constexpr float SK_FloatPI
#define INHERITED(method,...)
sk_sp< T > sk_ref_sp(T *obj)
#define SG_ATTRIBUTE(attr_name, attr_type, attr_container)
#define SkDegreesToRadians(degrees)
#define SkScalarRoundToInt(x)
#define SkScalarRoundToScalar(x)
SK_API SkString SkStringPrintf(const char *format,...) SK_PRINTF_LIKE(1
Creates a new string and writes into it using a printf()-style format.
static constexpr const T & SkTPin(const T &x, const T &lo, const T &hi)
int saveLayer(const SkRect *bounds, const SkPaint *paint)
void drawPaint(const SkPaint &paint)
SkMatrix getTotalMatrix() const
static SkMatrix Scale(SkScalar sx, SkScalar sy)
static SkMatrix RotateDeg(SkScalar deg)
static SkMatrix Translate(SkScalar dx, SkScalar dy)
SkScalar rc(int r, int c) const
void setShader(sk_sp< SkShader > shader)
void setBlendMode(SkBlendMode mode)
static Result MakeForShader(SkString sksl, const Options &)
void attachDiscardableAdapter(sk_sp< T > adapter) const
static float max(float r, float g, float b)
static constexpr skcms_TransferFunction kLinear
Optional< SkRect > bounds
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
SK_API sk_sp< PrecompileColorFilter > Matrix()
SIN Vec< N, float > floor(const Vec< N, float > &x)