17839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger/* 27839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Copyright 2013 Google Inc. 37839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * 47839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Use of this source code is governed by a BSD-style license that can be 57839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * found in the LICENSE file. 67839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger */ 77839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 87839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#ifndef SkPerlinNoiseShader_DEFINED 97839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#define SkPerlinNoiseShader_DEFINED 107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkShader.h" 127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger/** \class SkPerlinNoiseShader 147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkPerlinNoiseShader creates an image using the Perlin turbulence function. 167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger It can produce tileable noise if asked to stitch tiles and provided a tile size. 187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger In order to fill a large area with repeating noise, set the stitchTiles flag to 197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger true, and render exactly a single tile of noise. Without this flag, the result 207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger will contain visible seams between tiles. 217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger The algorithm used is described here : 237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger http://www.w3.org/TR/SVG/filters.html#feTurbulenceElement 247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger*/ 257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerclass SK_API SkPerlinNoiseShader : public SkShader { 267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger struct PaintingData; 277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerpublic: 287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger struct StitchData; 297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger /** 317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * About the noise types : the difference between the 2 is just minor tweaks to the algorithm, 327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * they're not 2 entirely different noises. The output looks different, but once the noise is 337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * generated in the [1, -1] range, the output is brought back in the [0, 1] range by doing : 347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * kFractalNoise_Type : noise * 0.5 + 0.5 357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * kTurbulence_Type : abs(noise) 367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Very little differences between the 2 types, although you can tell the difference visually. 377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger */ 387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger enum Type { 397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger kFractalNoise_Type, 407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger kTurbulence_Type, 417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger kFirstType = kFractalNoise_Type, 427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger kLastType = kTurbulence_Type 437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger }; 447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger /** 457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * This will construct Perlin noise of the given type (Fractal Noise or Turbulence). 467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * 477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Both base frequencies (X and Y) have a usual range of (0..1). 487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * 497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * The number of octaves provided should be fairly small, although no limit is enforced. 507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Each octave doubles the frequency, so 10 octaves would produce noise from 517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * baseFrequency * 1, * 2, * 4, ..., * 512, which quickly yields insignificantly small 527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * periods and resembles regular unstructured noise rather than Perlin noise. 537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * 547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * If tileSize isn't NULL or an empty size, the tileSize parameter will be used to modify 557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * the frequencies so that the noise will be tileable for the given tile size. If tileSize 567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * is NULL or an empty size, the frequencies will be used as is without modification. 577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger */ 587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger static SkShader* CreateFractalNoise(SkScalar baseFrequencyX, SkScalar baseFrequencyY, 597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int numOctaves, SkScalar seed, 607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkISize* tileSize = NULL); 617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger static SkShader* CreateTubulence(SkScalar baseFrequencyX, SkScalar baseFrequencyY, 627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int numOctaves, SkScalar seed, 637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkISize* tileSize = NULL); 647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger virtual bool setContext(const SkBitmap& device, const SkPaint& paint, 667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkMatrix& matrix); 677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger virtual void shadeSpan(int x, int y, SkPMColor[], int count) SK_OVERRIDE; 687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger virtual void shadeSpan16(int x, int y, uint16_t[], int count) SK_OVERRIDE; 697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE; 717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SK_DEVELOPER_TO_STRING() 737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPerlinNoiseShader) 747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprotected: 767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkPerlinNoiseShader(SkFlattenableReadBuffer&); 777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; 787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprivate: 807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkPerlinNoiseShader(SkPerlinNoiseShader::Type type, SkScalar baseFrequencyX, 817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkScalar baseFrequencyY, int numOctaves, SkScalar seed, 827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkISize* tileSize = NULL); 837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger virtual ~SkPerlinNoiseShader(); 847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger void setTileSize(const SkISize&); 867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger void initPaint(PaintingData& paintingData); 887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkScalar noise2D(int channel, const PaintingData& paintingData, 907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const StitchData& stitchData, const SkPoint& noiseVector); 917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkScalar calculateTurbulenceValueForPoint(int channel, const PaintingData& paintingData, 937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger StitchData& stitchData, const SkPoint& point); 947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkPMColor shade(const SkPoint& point, StitchData& stitchData); 967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkPerlinNoiseShader::Type fType; 987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkScalar fBaseFrequencyX; 997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkScalar fBaseFrequencyY; 1007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int fNumOctaves; 1017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkScalar fSeed; 1027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkISize fTileSize; 1037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger bool fStitchTiles; 1047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkMatrix fMatrix; 1057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger PaintingData* fPaintingData; 1077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger typedef SkShader INHERITED; 1097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}; 1107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif 112