1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/include/effects/SkPerlinNoiseShader.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,111 @@ 1.4 +/* 1.5 + * Copyright 2013 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#ifndef SkPerlinNoiseShader_DEFINED 1.12 +#define SkPerlinNoiseShader_DEFINED 1.13 + 1.14 +#include "SkShader.h" 1.15 + 1.16 +/** \class SkPerlinNoiseShader 1.17 + 1.18 + SkPerlinNoiseShader creates an image using the Perlin turbulence function. 1.19 + 1.20 + It can produce tileable noise if asked to stitch tiles and provided a tile size. 1.21 + In order to fill a large area with repeating noise, set the stitchTiles flag to 1.22 + true, and render exactly a single tile of noise. Without this flag, the result 1.23 + will contain visible seams between tiles. 1.24 + 1.25 + The algorithm used is described here : 1.26 + http://www.w3.org/TR/SVG/filters.html#feTurbulenceElement 1.27 +*/ 1.28 +class SK_API SkPerlinNoiseShader : public SkShader { 1.29 + struct PaintingData; 1.30 +public: 1.31 + struct StitchData; 1.32 + 1.33 + /** 1.34 + * About the noise types : the difference between the 2 is just minor tweaks to the algorithm, 1.35 + * they're not 2 entirely different noises. The output looks different, but once the noise is 1.36 + * generated in the [1, -1] range, the output is brought back in the [0, 1] range by doing : 1.37 + * kFractalNoise_Type : noise * 0.5 + 0.5 1.38 + * kTurbulence_Type : abs(noise) 1.39 + * Very little differences between the 2 types, although you can tell the difference visually. 1.40 + */ 1.41 + enum Type { 1.42 + kFractalNoise_Type, 1.43 + kTurbulence_Type, 1.44 + kFirstType = kFractalNoise_Type, 1.45 + kLastType = kTurbulence_Type 1.46 + }; 1.47 + /** 1.48 + * This will construct Perlin noise of the given type (Fractal Noise or Turbulence). 1.49 + * 1.50 + * Both base frequencies (X and Y) have a usual range of (0..1). 1.51 + * 1.52 + * The number of octaves provided should be fairly small, although no limit is enforced. 1.53 + * Each octave doubles the frequency, so 10 octaves would produce noise from 1.54 + * baseFrequency * 1, * 2, * 4, ..., * 512, which quickly yields insignificantly small 1.55 + * periods and resembles regular unstructured noise rather than Perlin noise. 1.56 + * 1.57 + * If tileSize isn't NULL or an empty size, the tileSize parameter will be used to modify 1.58 + * the frequencies so that the noise will be tileable for the given tile size. If tileSize 1.59 + * is NULL or an empty size, the frequencies will be used as is without modification. 1.60 + */ 1.61 + static SkShader* CreateFractalNoise(SkScalar baseFrequencyX, SkScalar baseFrequencyY, 1.62 + int numOctaves, SkScalar seed, 1.63 + const SkISize* tileSize = NULL); 1.64 + static SkShader* CreateTubulence(SkScalar baseFrequencyX, SkScalar baseFrequencyY, 1.65 + int numOctaves, SkScalar seed, 1.66 + const SkISize* tileSize = NULL); 1.67 + 1.68 + virtual bool setContext(const SkBitmap& device, const SkPaint& paint, 1.69 + const SkMatrix& matrix); 1.70 + virtual void shadeSpan(int x, int y, SkPMColor[], int count) SK_OVERRIDE; 1.71 + virtual void shadeSpan16(int x, int y, uint16_t[], int count) SK_OVERRIDE; 1.72 + 1.73 + virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE; 1.74 + 1.75 + SK_TO_STRING_OVERRIDE() 1.76 + SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPerlinNoiseShader) 1.77 + 1.78 +protected: 1.79 + SkPerlinNoiseShader(SkReadBuffer&); 1.80 + virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; 1.81 + 1.82 +private: 1.83 + SkPerlinNoiseShader(SkPerlinNoiseShader::Type type, SkScalar baseFrequencyX, 1.84 + SkScalar baseFrequencyY, int numOctaves, SkScalar seed, 1.85 + const SkISize* tileSize); 1.86 + virtual ~SkPerlinNoiseShader(); 1.87 + 1.88 + SkScalar noise2D(int channel, const PaintingData& paintingData, 1.89 + const StitchData& stitchData, const SkPoint& noiseVector) const; 1.90 + 1.91 + SkScalar calculateTurbulenceValueForPoint(int channel, const PaintingData& paintingData, 1.92 + StitchData& stitchData, const SkPoint& point) const; 1.93 + 1.94 + SkPMColor shade(const SkPoint& point, StitchData& stitchData) const; 1.95 + 1.96 + // TODO (scroggo): Once all SkShaders are created from a factory, and we have removed the 1.97 + // constructor that creates SkPerlinNoiseShader from an SkReadBuffer, several fields can 1.98 + // be made constant. 1.99 + /*const*/ SkPerlinNoiseShader::Type fType; 1.100 + /*const*/ SkScalar fBaseFrequencyX; 1.101 + /*const*/ SkScalar fBaseFrequencyY; 1.102 + /*const*/ int fNumOctaves; 1.103 + /*const*/ SkScalar fSeed; 1.104 + /*const*/ SkISize fTileSize; 1.105 + /*const*/ bool fStitchTiles; 1.106 + // TODO (scroggo): Once setContext creates a new object, place this on that object. 1.107 + SkMatrix fMatrix; 1.108 + 1.109 + PaintingData* fPaintingData; 1.110 + 1.111 + typedef SkShader INHERITED; 1.112 +}; 1.113 + 1.114 +#endif