OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkDither.h" | 8 #include "SkDither.h" |
9 #include "SkPerlinNoiseShader.h" | 9 #include "SkPerlinNoiseShader.h" |
10 #include "SkColorFilter.h" | 10 #include "SkColorFilter.h" |
(...skipping 21 matching lines...) Expand all Loading... |
32 // noiseValue is the color component's value (or color) | 32 // noiseValue is the color component's value (or color) |
33 // limitValue is the maximum perlin noise array index value allowed | 33 // limitValue is the maximum perlin noise array index value allowed |
34 // newValue is the current noise dimension (either width or height) | 34 // newValue is the current noise dimension (either width or height) |
35 inline int checkNoise(int noiseValue, int limitValue, int newValue) { | 35 inline int checkNoise(int noiseValue, int limitValue, int newValue) { |
36 // If the noise value would bring us out of bounds of the current noise arra
y while we are | 36 // If the noise value would bring us out of bounds of the current noise arra
y while we are |
37 // stiching noise tiles together, wrap the noise around the current dimensio
n of the noise to | 37 // stiching noise tiles together, wrap the noise around the current dimensio
n of the noise to |
38 // stay within the array bounds in a continuous fashion (so that tiling line
s are not visible) | 38 // stay within the array bounds in a continuous fashion (so that tiling line
s are not visible) |
39 if (noiseValue >= limitValue) { | 39 if (noiseValue >= limitValue) { |
40 noiseValue -= newValue; | 40 noiseValue -= newValue; |
41 } | 41 } |
42 if (noiseValue >= limitValue - 1) { | |
43 noiseValue -= newValue - 1; | |
44 } | |
45 return noiseValue; | 42 return noiseValue; |
46 } | 43 } |
47 | 44 |
48 inline SkScalar smoothCurve(SkScalar t) { | 45 inline SkScalar smoothCurve(SkScalar t) { |
49 static const SkScalar SK_Scalar3 = 3.0f; | 46 static const SkScalar SK_Scalar3 = 3.0f; |
50 | 47 |
51 // returns t * t * (3 - 2 * t) | 48 // returns t * t * (3 - 2 * t) |
52 return SkScalarMul(SkScalarSquare(t), SK_Scalar3 - 2 * t); | 49 return SkScalarMul(SkScalarSquare(t), SK_Scalar3 - 2 * t); |
53 } | 50 } |
54 | 51 |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 buffer.writeBool(fStitchTiles); | 310 buffer.writeBool(fStitchTiles); |
314 buffer.writeInt(fTileSize.fWidth); | 311 buffer.writeInt(fTileSize.fWidth); |
315 buffer.writeInt(fTileSize.fHeight); | 312 buffer.writeInt(fTileSize.fHeight); |
316 } | 313 } |
317 | 314 |
318 SkScalar SkPerlinNoiseShader::PerlinNoiseShaderContext::noise2D( | 315 SkScalar SkPerlinNoiseShader::PerlinNoiseShaderContext::noise2D( |
319 int channel, const PaintingData& paintingData, | 316 int channel, const PaintingData& paintingData, |
320 const StitchData& stitchData, const SkPoint& noiseVector) const { | 317 const StitchData& stitchData, const SkPoint& noiseVector) const { |
321 struct Noise { | 318 struct Noise { |
322 int noisePositionIntegerValue; | 319 int noisePositionIntegerValue; |
| 320 int nextNoisePositionIntegerValue; |
323 SkScalar noisePositionFractionValue; | 321 SkScalar noisePositionFractionValue; |
324 Noise(SkScalar component) | 322 Noise(SkScalar component) |
325 { | 323 { |
326 SkScalar position = component + kPerlinNoise; | 324 SkScalar position = component + kPerlinNoise; |
327 noisePositionIntegerValue = SkScalarFloorToInt(position); | 325 noisePositionIntegerValue = SkScalarFloorToInt(position); |
328 noisePositionFractionValue = position - SkIntToScalar(noisePositionI
ntegerValue); | 326 noisePositionFractionValue = position - SkIntToScalar(noisePositionI
ntegerValue); |
| 327 nextNoisePositionIntegerValue = noisePositionIntegerValue + 1; |
329 } | 328 } |
330 }; | 329 }; |
331 Noise noiseX(noiseVector.x()); | 330 Noise noiseX(noiseVector.x()); |
332 Noise noiseY(noiseVector.y()); | 331 Noise noiseY(noiseVector.y()); |
333 SkScalar u, v; | 332 SkScalar u, v; |
334 const SkPerlinNoiseShader& perlinNoiseShader = static_cast<const SkPerlinNoi
seShader&>(fShader); | 333 const SkPerlinNoiseShader& perlinNoiseShader = static_cast<const SkPerlinNoi
seShader&>(fShader); |
335 // If stitching, adjust lattice points accordingly. | 334 // If stitching, adjust lattice points accordingly. |
336 if (perlinNoiseShader.fStitchTiles) { | 335 if (perlinNoiseShader.fStitchTiles) { |
337 noiseX.noisePositionIntegerValue = | 336 noiseX.noisePositionIntegerValue = |
338 checkNoise(noiseX.noisePositionIntegerValue, stitchData.fWrapX, stit
chData.fWidth); | 337 checkNoise(noiseX.noisePositionIntegerValue, stitchData.fWrapX, stit
chData.fWidth); |
339 noiseY.noisePositionIntegerValue = | 338 noiseY.noisePositionIntegerValue = |
340 checkNoise(noiseY.noisePositionIntegerValue, stitchData.fWrapY, stit
chData.fHeight); | 339 checkNoise(noiseY.noisePositionIntegerValue, stitchData.fWrapY, stit
chData.fHeight); |
| 340 noiseX.nextNoisePositionIntegerValue = |
| 341 checkNoise(noiseX.nextNoisePositionIntegerValue, stitchData.fWrapX,
stitchData.fWidth); |
| 342 noiseY.nextNoisePositionIntegerValue = |
| 343 checkNoise(noiseY.nextNoisePositionIntegerValue, stitchData.fWrapY,
stitchData.fHeight); |
341 } | 344 } |
342 noiseX.noisePositionIntegerValue &= kBlockMask; | 345 noiseX.noisePositionIntegerValue &= kBlockMask; |
343 noiseY.noisePositionIntegerValue &= kBlockMask; | 346 noiseY.noisePositionIntegerValue &= kBlockMask; |
344 int latticeIndex = | 347 noiseX.nextNoisePositionIntegerValue &= kBlockMask; |
345 paintingData.fLatticeSelector[noiseX.noisePositionIntegerValue] + | 348 noiseY.nextNoisePositionIntegerValue &= kBlockMask; |
346 noiseY.noisePositionIntegerValue; | 349 int i = |
347 int nextLatticeIndex = | 350 paintingData.fLatticeSelector[noiseX.noisePositionIntegerValue]; |
348 paintingData.fLatticeSelector[(noiseX.noisePositionIntegerValue + 1) & k
BlockMask] + | 351 int j = |
349 noiseY.noisePositionIntegerValue; | 352 paintingData.fLatticeSelector[noiseX.nextNoisePositionIntegerValue]; |
| 353 int b00 = (i + noiseY.noisePositionIntegerValue) & kBlockMask; |
| 354 int b10 = (j + noiseY.noisePositionIntegerValue) & kBlockMask; |
| 355 int b01 = (i + noiseY.nextNoisePositionIntegerValue) & kBlockMask; |
| 356 int b11 = (j + noiseY.nextNoisePositionIntegerValue) & kBlockMask; |
350 SkScalar sx = smoothCurve(noiseX.noisePositionFractionValue); | 357 SkScalar sx = smoothCurve(noiseX.noisePositionFractionValue); |
351 SkScalar sy = smoothCurve(noiseY.noisePositionFractionValue); | 358 SkScalar sy = smoothCurve(noiseY.noisePositionFractionValue); |
352 // This is taken 1:1 from SVG spec: http://www.w3.org/TR/SVG11/filters.html#
feTurbulenceElement | 359 // This is taken 1:1 from SVG spec: http://www.w3.org/TR/SVG11/filters.html#
feTurbulenceElement |
353 SkPoint fractionValue = SkPoint::Make(noiseX.noisePositionFractionValue, | 360 SkPoint fractionValue = SkPoint::Make(noiseX.noisePositionFractionValue, |
354 noiseY.noisePositionFractionValue); //
Offset (0,0) | 361 noiseY.noisePositionFractionValue); //
Offset (0,0) |
355 u = paintingData.fGradient[channel][latticeIndex & kBlockMask].dot(fractionV
alue); | 362 u = paintingData.fGradient[channel][b00].dot(fractionValue); |
356 fractionValue.fX -= SK_Scalar1; // Offset (-1,0) | 363 fractionValue.fX -= SK_Scalar1; // Offset (-1,0) |
357 v = paintingData.fGradient[channel][nextLatticeIndex & kBlockMask].dot(fract
ionValue); | 364 v = paintingData.fGradient[channel][b10].dot(fractionValue); |
358 SkScalar a = SkScalarInterp(u, v, sx); | 365 SkScalar a = SkScalarInterp(u, v, sx); |
359 fractionValue.fY -= SK_Scalar1; // Offset (-1,-1) | 366 fractionValue.fY -= SK_Scalar1; // Offset (-1,-1) |
360 v = paintingData.fGradient[channel][(nextLatticeIndex + 1) & kBlockMask].dot
(fractionValue); | 367 v = paintingData.fGradient[channel][b11].dot(fractionValue); |
361 fractionValue.fX = noiseX.noisePositionFractionValue; // Offset (0,-1) | 368 fractionValue.fX = noiseX.noisePositionFractionValue; // Offset (0,-1) |
362 u = paintingData.fGradient[channel][(latticeIndex + 1) & kBlockMask].dot(fra
ctionValue); | 369 u = paintingData.fGradient[channel][b01].dot(fractionValue); |
363 SkScalar b = SkScalarInterp(u, v, sx); | 370 SkScalar b = SkScalarInterp(u, v, sx); |
364 return SkScalarInterp(a, b, sy); | 371 return SkScalarInterp(a, b, sy); |
365 } | 372 } |
366 | 373 |
367 SkScalar SkPerlinNoiseShader::PerlinNoiseShaderContext::calculateTurbulenceValue
ForPoint( | 374 SkScalar SkPerlinNoiseShader::PerlinNoiseShaderContext::calculateTurbulenceValue
ForPoint( |
368 int channel, const PaintingData& paintingData, | 375 int channel, const PaintingData& paintingData, |
369 StitchData& stitchData, const SkPoint& point) const { | 376 StitchData& stitchData, const SkPoint& point) const { |
370 const SkPerlinNoiseShader& perlinNoiseShader = static_cast<const SkPerlinNoi
seShader&>(fShader); | 377 const SkPerlinNoiseShader& perlinNoiseShader = static_cast<const SkPerlinNoi
seShader&>(fShader); |
371 if (perlinNoiseShader.fStitchTiles) { | 378 if (perlinNoiseShader.fStitchTiles) { |
372 // Set up TurbulenceInitial stitch values. | 379 // Set up TurbulenceInitial stitch values. |
(...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
982 } | 989 } |
983 | 990 |
984 // There are 4 lines, so the center of each line is 1/8, 3/8, 5/8 and 7/8 | 991 // There are 4 lines, so the center of each line is 1/8, 3/8, 5/8 and 7/8 |
985 const char* chanCoordR = "0.125"; | 992 const char* chanCoordR = "0.125"; |
986 const char* chanCoordG = "0.375"; | 993 const char* chanCoordG = "0.375"; |
987 const char* chanCoordB = "0.625"; | 994 const char* chanCoordB = "0.625"; |
988 const char* chanCoordA = "0.875"; | 995 const char* chanCoordA = "0.875"; |
989 const char* chanCoord = "chanCoord"; | 996 const char* chanCoord = "chanCoord"; |
990 const char* stitchData = "stitchData"; | 997 const char* stitchData = "stitchData"; |
991 const char* ratio = "ratio"; | 998 const char* ratio = "ratio"; |
992 const char* noiseXY = "noiseXY"; | |
993 const char* noiseVec = "noiseVec"; | 999 const char* noiseVec = "noiseVec"; |
994 const char* noiseSmooth = "noiseSmooth"; | 1000 const char* noiseSmooth = "noiseSmooth"; |
| 1001 const char* floorVal = "floorVal"; |
995 const char* fractVal = "fractVal"; | 1002 const char* fractVal = "fractVal"; |
996 const char* uv = "uv"; | 1003 const char* uv = "uv"; |
997 const char* ab = "ab"; | 1004 const char* ab = "ab"; |
998 const char* latticeIdx = "latticeIdx"; | 1005 const char* latticeIdx = "latticeIdx"; |
| 1006 const char* bcoords = "bcoords"; |
999 const char* lattice = "lattice"; | 1007 const char* lattice = "lattice"; |
1000 const char* inc8bit = "0.00390625"; // 1.0 / 256.0 | 1008 const char* inc8bit = "0.00390625"; // 1.0 / 256.0 |
1001 // This is the math to convert the two 16bit integer packed into rgba 8 bit
input into a | 1009 // This is the math to convert the two 16bit integer packed into rgba 8 bit
input into a |
1002 // [-1,1] vector and perform a dot product between that vector and the provi
ded vector. | 1010 // [-1,1] vector and perform a dot product between that vector and the provi
ded vector. |
1003 const char* dotLattice = "dot(((%s.ga + %s.rb * vec2(%s)) * vec2(2.0) - vec
2(1.0)), %s);"; | 1011 const char* dotLattice = "dot(((%s.ga + %s.rb * vec2(%s)) * vec2(2.0) - vec
2(1.0)), %s);"; |
1004 | 1012 |
1005 // Add noise function | 1013 // Add noise function |
1006 static const GrGLShaderVar gPerlinNoiseArgs[] = { | 1014 static const GrGLShaderVar gPerlinNoiseArgs[] = { |
1007 GrGLShaderVar(chanCoord, kFloat_GrSLType), | 1015 GrGLShaderVar(chanCoord, kFloat_GrSLType), |
1008 GrGLShaderVar(noiseVec, kVec2f_GrSLType) | 1016 GrGLShaderVar(noiseVec, kVec2f_GrSLType) |
1009 }; | 1017 }; |
1010 | 1018 |
1011 static const GrGLShaderVar gPerlinNoiseStitchArgs[] = { | 1019 static const GrGLShaderVar gPerlinNoiseStitchArgs[] = { |
1012 GrGLShaderVar(chanCoord, kFloat_GrSLType), | 1020 GrGLShaderVar(chanCoord, kFloat_GrSLType), |
1013 GrGLShaderVar(noiseVec, kVec2f_GrSLType), | 1021 GrGLShaderVar(noiseVec, kVec2f_GrSLType), |
1014 GrGLShaderVar(stitchData, kVec2f_GrSLType) | 1022 GrGLShaderVar(stitchData, kVec2f_GrSLType) |
1015 }; | 1023 }; |
1016 | 1024 |
1017 SkString noiseCode; | 1025 SkString noiseCode; |
1018 | 1026 |
1019 noiseCode.appendf("\tvec4 %s = vec4(floor(%s), fract(%s));", noiseXY, noiseV
ec, noiseVec); | 1027 noiseCode.appendf("\tvec4 %s;\n", floorVal); |
| 1028 noiseCode.appendf("\t%s.xy = floor(%s);\n", floorVal, noiseVec); |
| 1029 noiseCode.appendf("\t%s.zw = %s.xy + vec2(1.0);\n", floorVal, floorVal); |
| 1030 noiseCode.appendf("\tvec2 %s = fract(%s);\n", fractVal, noiseVec); |
1020 | 1031 |
1021 // smooth curve : t * t * (3 - 2 * t) | 1032 // smooth curve : t * t * (3 - 2 * t) |
1022 noiseCode.appendf("\n\tvec2 %s = %s.zw * %s.zw * (vec2(3.0) - vec2(2.0) * %s
.zw);", | 1033 noiseCode.appendf("\n\tvec2 %s = %s * %s * (vec2(3.0) - vec2(2.0) * %s);", |
1023 noiseSmooth, noiseXY, noiseXY, noiseXY); | 1034 noiseSmooth, fractVal, fractVal, fractVal); |
1024 | 1035 |
1025 // Adjust frequencies if we're stitching tiles | 1036 // Adjust frequencies if we're stitching tiles |
1026 if (fStitchTiles) { | 1037 if (fStitchTiles) { |
1027 noiseCode.appendf("\n\tif(%s.x >= %s.x) { %s.x -= %s.x; }", | 1038 noiseCode.appendf("\n\tif(%s.x >= %s.x) { %s.x -= %s.x; }", |
1028 noiseXY, stitchData, noiseXY, stitchData); | 1039 floorVal, stitchData, floorVal, stitchData); |
1029 noiseCode.appendf("\n\tif(%s.x >= (%s.x - 1.0)) { %s.x -= (%s.x - 1.0);
}", | |
1030 noiseXY, stitchData, noiseXY, stitchData); | |
1031 noiseCode.appendf("\n\tif(%s.y >= %s.y) { %s.y -= %s.y; }", | 1040 noiseCode.appendf("\n\tif(%s.y >= %s.y) { %s.y -= %s.y; }", |
1032 noiseXY, stitchData, noiseXY, stitchData); | 1041 floorVal, stitchData, floorVal, stitchData); |
1033 noiseCode.appendf("\n\tif(%s.y >= (%s.y - 1.0)) { %s.y -= (%s.y - 1.0);
}", | 1042 noiseCode.appendf("\n\tif(%s.z >= %s.x) { %s.z -= %s.x; }", |
1034 noiseXY, stitchData, noiseXY, stitchData); | 1043 floorVal, stitchData, floorVal, stitchData); |
| 1044 noiseCode.appendf("\n\tif(%s.w >= %s.y) { %s.w -= %s.y; }", |
| 1045 floorVal, stitchData, floorVal, stitchData); |
1035 } | 1046 } |
1036 | 1047 |
1037 // Get texture coordinates and normalize | 1048 // Get texture coordinates and normalize |
1038 noiseCode.appendf("\n\t%s.xy = fract(floor(mod(%s.xy, 256.0)) / vec2(256.0))
;\n", | 1049 noiseCode.appendf("\n\t%s = fract(floor(mod(%s, 256.0)) / vec4(256.0));\n", |
1039 noiseXY, noiseXY); | 1050 floorVal, floorVal); |
1040 | 1051 |
1041 // Get permutation for x | 1052 // Get permutation for x |
1042 { | 1053 { |
1043 SkString xCoords(""); | 1054 SkString xCoords(""); |
1044 xCoords.appendf("vec2(%s.x, 0.5)", noiseXY); | 1055 xCoords.appendf("vec2(%s.x, 0.5)", floorVal); |
1045 | 1056 |
1046 noiseCode.appendf("\n\tvec2 %s;\n\t%s.x = ", latticeIdx, latticeIdx); | 1057 noiseCode.appendf("\n\tvec2 %s;\n\t%s.x = ", latticeIdx, latticeIdx); |
1047 builder->appendTextureLookup(&noiseCode, samplers[0], xCoords.c_str(), k
Vec2f_GrSLType); | 1058 builder->appendTextureLookup(&noiseCode, samplers[0], xCoords.c_str(), k
Vec2f_GrSLType); |
1048 noiseCode.append(".r;"); | 1059 noiseCode.append(".r;"); |
1049 } | 1060 } |
1050 | 1061 |
1051 // Get permutation for x + 1 | 1062 // Get permutation for x + 1 |
1052 { | 1063 { |
1053 SkString xCoords(""); | 1064 SkString xCoords(""); |
1054 xCoords.appendf("vec2(fract(%s.x + %s), 0.5)", noiseXY, inc8bit); | 1065 xCoords.appendf("vec2(%s.z, 0.5)", floorVal); |
1055 | 1066 |
1056 noiseCode.appendf("\n\t%s.y = ", latticeIdx); | 1067 noiseCode.appendf("\n\t%s.y = ", latticeIdx); |
1057 builder->appendTextureLookup(&noiseCode, samplers[0], xCoords.c_str(), k
Vec2f_GrSLType); | 1068 builder->appendTextureLookup(&noiseCode, samplers[0], xCoords.c_str(), k
Vec2f_GrSLType); |
1058 noiseCode.append(".r;"); | 1069 noiseCode.append(".r;"); |
1059 } | 1070 } |
1060 | 1071 |
1061 #if defined(SK_BUILD_FOR_ANDROID) | 1072 #if defined(SK_BUILD_FOR_ANDROID) |
1062 // Android rounding for Tegra devices, like, for example: Xoom (Tegra 2), Ne
xus 7 (Tegra 3). | 1073 // Android rounding for Tegra devices, like, for example: Xoom (Tegra 2), Ne
xus 7 (Tegra 3). |
1063 // The issue is that colors aren't accurate enough on Tegra devices. For exa
mple, if an 8 bit | 1074 // The issue is that colors aren't accurate enough on Tegra devices. For exa
mple, if an 8 bit |
1064 // value of 124 (or 0.486275 here) is entered, we can get a texture value of
123.513725 | 1075 // value of 124 (or 0.486275 here) is entered, we can get a texture value of
123.513725 |
1065 // (or 0.484368 here). The following rounding operation prevents these preci
sion issues from | 1076 // (or 0.484368 here). The following rounding operation prevents these preci
sion issues from |
1066 // affecting the result of the noise by making sure that we only have multip
les of 1/255. | 1077 // affecting the result of the noise by making sure that we only have multip
les of 1/255. |
1067 // (Note that 1/255 is about 0.003921569, which is the value used here). | 1078 // (Note that 1/255 is about 0.003921569, which is the value used here). |
1068 noiseCode.appendf("\n\t%s = floor(%s * vec2(255.0) + vec2(0.5)) * vec2(0.003
921569);", | 1079 noiseCode.appendf("\n\t%s = floor(%s * vec2(255.0) + vec2(0.5)) * vec2(0.003
921569);", |
1069 latticeIdx, latticeIdx); | 1080 latticeIdx, latticeIdx); |
1070 #endif | 1081 #endif |
1071 | 1082 |
1072 // Get (x,y) coordinates with the permutated x | 1083 // Get (x,y) coordinates with the permutated x |
1073 noiseCode.appendf("\n\t%s = fract(%s + %s.yy);", latticeIdx, latticeIdx, noi
seXY); | 1084 noiseCode.appendf("\n\tvec4 %s = fract(%s.xyxy + %s.yyww);", bcoords, lattic
eIdx, floorVal); |
1074 | |
1075 noiseCode.appendf("\n\tvec2 %s = %s.zw;", fractVal, noiseXY); | |
1076 | 1085 |
1077 noiseCode.appendf("\n\n\tvec2 %s;", uv); | 1086 noiseCode.appendf("\n\n\tvec2 %s;", uv); |
1078 // Compute u, at offset (0,0) | 1087 // Compute u, at offset (0,0) |
1079 { | 1088 { |
1080 SkString latticeCoords(""); | 1089 SkString latticeCoords(""); |
1081 latticeCoords.appendf("vec2(%s.x, %s)", latticeIdx, chanCoord); | 1090 latticeCoords.appendf("vec2(%s.x, %s)", bcoords, chanCoord); |
1082 noiseCode.appendf("\n\tvec4 %s = ", lattice); | 1091 noiseCode.appendf("\n\tvec4 %s = ", lattice); |
1083 builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_st
r(), | 1092 builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_st
r(), |
1084 kVec2f_GrSLType); | 1093 kVec2f_GrSLType); |
1085 noiseCode.appendf(".bgra;\n\t%s.x = ", uv); | 1094 noiseCode.appendf(".bgra;\n\t%s.x = ", uv); |
1086 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); | 1095 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); |
1087 } | 1096 } |
1088 | 1097 |
1089 noiseCode.appendf("\n\t%s.x -= 1.0;", fractVal); | 1098 noiseCode.appendf("\n\t%s.x -= 1.0;", fractVal); |
1090 // Compute v, at offset (-1,0) | 1099 // Compute v, at offset (-1,0) |
1091 { | 1100 { |
1092 SkString latticeCoords(""); | 1101 SkString latticeCoords(""); |
1093 latticeCoords.appendf("vec2(%s.y, %s)", latticeIdx, chanCoord); | 1102 latticeCoords.appendf("vec2(%s.y, %s)", bcoords, chanCoord); |
1094 noiseCode.append("\n\tlattice = "); | 1103 noiseCode.append("\n\tlattice = "); |
1095 builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_st
r(), | 1104 builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_st
r(), |
1096 kVec2f_GrSLType); | 1105 kVec2f_GrSLType); |
1097 noiseCode.appendf(".bgra;\n\t%s.y = ", uv); | 1106 noiseCode.appendf(".bgra;\n\t%s.y = ", uv); |
1098 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); | 1107 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); |
1099 } | 1108 } |
1100 | 1109 |
1101 // Compute 'a' as a linear interpolation of 'u' and 'v' | 1110 // Compute 'a' as a linear interpolation of 'u' and 'v' |
1102 noiseCode.appendf("\n\tvec2 %s;", ab); | 1111 noiseCode.appendf("\n\tvec2 %s;", ab); |
1103 noiseCode.appendf("\n\t%s.x = mix(%s.x, %s.y, %s.x);", ab, uv, uv, noiseSmoo
th); | 1112 noiseCode.appendf("\n\t%s.x = mix(%s.x, %s.y, %s.x);", ab, uv, uv, noiseSmoo
th); |
1104 | 1113 |
1105 noiseCode.appendf("\n\t%s.y -= 1.0;", fractVal); | 1114 noiseCode.appendf("\n\t%s.y -= 1.0;", fractVal); |
1106 // Compute v, at offset (-1,-1) | 1115 // Compute v, at offset (-1,-1) |
1107 { | 1116 { |
1108 SkString latticeCoords(""); | 1117 SkString latticeCoords(""); |
1109 latticeCoords.appendf("vec2(fract(%s.y + %s), %s)", latticeIdx, inc8bit,
chanCoord); | 1118 latticeCoords.appendf("vec2(%s.w, %s)", bcoords, chanCoord); |
1110 noiseCode.append("\n\tlattice = "); | 1119 noiseCode.append("\n\tlattice = "); |
1111 builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_st
r(), | 1120 builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_st
r(), |
1112 kVec2f_GrSLType); | 1121 kVec2f_GrSLType); |
1113 noiseCode.appendf(".bgra;\n\t%s.y = ", uv); | 1122 noiseCode.appendf(".bgra;\n\t%s.y = ", uv); |
1114 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); | 1123 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); |
1115 } | 1124 } |
1116 | 1125 |
1117 noiseCode.appendf("\n\t%s.x += 1.0;", fractVal); | 1126 noiseCode.appendf("\n\t%s.x += 1.0;", fractVal); |
1118 // Compute u, at offset (0,-1) | 1127 // Compute u, at offset (0,-1) |
1119 { | 1128 { |
1120 SkString latticeCoords(""); | 1129 SkString latticeCoords(""); |
1121 latticeCoords.appendf("vec2(fract(%s.x + %s), %s)", latticeIdx, inc8bit,
chanCoord); | 1130 latticeCoords.appendf("vec2(%s.z, %s)", bcoords, chanCoord); |
1122 noiseCode.append("\n\tlattice = "); | 1131 noiseCode.append("\n\tlattice = "); |
1123 builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_st
r(), | 1132 builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_st
r(), |
1124 kVec2f_GrSLType); | 1133 kVec2f_GrSLType); |
1125 noiseCode.appendf(".bgra;\n\t%s.x = ", uv); | 1134 noiseCode.appendf(".bgra;\n\t%s.x = ", uv); |
1126 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); | 1135 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); |
1127 } | 1136 } |
1128 | 1137 |
1129 // Compute 'b' as a linear interpolation of 'u' and 'v' | 1138 // Compute 'b' as a linear interpolation of 'u' and 'v' |
1130 noiseCode.appendf("\n\t%s.y = mix(%s.x, %s.y, %s.x);", ab, uv, uv, noiseSmoo
th); | 1139 noiseCode.appendf("\n\t%s.y = mix(%s.x, %s.y, %s.x);", ab, uv, uv, noiseSmoo
th); |
1131 // Compute the noise as a linear interpolation of 'a' and 'b' | 1140 // Compute the noise as a linear interpolation of 'a' and 'b' |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1377 str->append(" seed: "); | 1386 str->append(" seed: "); |
1378 str->appendScalar(fSeed); | 1387 str->appendScalar(fSeed); |
1379 str->append(" stitch tiles: "); | 1388 str->append(" stitch tiles: "); |
1380 str->append(fStitchTiles ? "true " : "false "); | 1389 str->append(fStitchTiles ? "true " : "false "); |
1381 | 1390 |
1382 this->INHERITED::toString(str); | 1391 this->INHERITED::toString(str); |
1383 | 1392 |
1384 str->append(")"); | 1393 str->append(")"); |
1385 } | 1394 } |
1386 #endif | 1395 #endif |
OLD | NEW |