GXS.ProcTextures.pas 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733
  1. //
  2. // The graphics engine GLXEngine. The unit of GXScene for Delphi
  3. //
  4. unit GXS.ProcTextures;
  5. (* Procedural textures *)
  6. interface
  7. uses
  8. Winapi.OpenGL,
  9. System.Classes,
  10. System.SysUtils,
  11. System.Math,
  12. Stage.VectorGeometry,
  13. Stage.Strings,
  14. GXS.Texture,
  15. GXS.Graphics,
  16. Stage.TextureFormat;
  17. const
  18. GRADIENT_TABLE_SIZE = 256;
  19. DAMP_SHIFT = 20;
  20. type
  21. TgxProcTextureNoise = class(TgxTextureImage)
  22. private
  23. FNoiseMap: TgxBitmap32;
  24. FWidth, FHeight: Integer;
  25. FMinCut: Byte;
  26. //FMaxCut : Byte;
  27. FNoiseSharpness: Single;
  28. FNoiseAnimate: Single;
  29. FSeamless: Boolean;
  30. FNoiseRandSeed: Longint;
  31. protected
  32. FGradients: array[0..GRADIENT_TABLE_SIZE * 3 - 1] of Single;
  33. PERM: array[0..GRADIENT_TABLE_SIZE - 1] of Byte;
  34. function GetWidth: Integer; override;
  35. function GetHeight: Integer; override;
  36. function GetDepth: Integer; override;
  37. function GetTextureTarget: TglTextureTarget; override;
  38. function Noise(x, y: Single): Single;
  39. procedure SetMinCut(const val: Byte);
  40. procedure SetSeamless(const val: Boolean);
  41. procedure SetWidth(const val: Integer);
  42. procedure SetHeight(const val: Integer);
  43. procedure SetNoiseSharpness(const val: Single);
  44. procedure SetNoiseRandSeed(const val: Longint);
  45. procedure UpdateNoise;
  46. public
  47. constructor Create(AOwner: TPersistent); override;
  48. destructor Destroy; override;
  49. class function FriendlyName: string; override;
  50. class function FriendlyDescription: string; override;
  51. procedure Assign(Source: TPersistent); override;
  52. function GetBitmap32: TgxBitmap32; override;
  53. procedure ReleaseBitmap32; override;
  54. procedure SaveToFile(const fileName: string); override;
  55. procedure LoadFromFile(const fileName: string); override;
  56. procedure NoiseAnimate(speed: Single);
  57. procedure SetPermFromData(inPERM: array of Byte);
  58. procedure SetPermToDefault;
  59. published
  60. property Width: Integer read GetWidth write SetWidth default 128;
  61. property Height: Integer read GetHeight write SetHeight default 128;
  62. property Depth: Integer read GetDepth;
  63. property MinCut: Byte read FMinCut write SetMinCut;
  64. property NoiseSharpness: Single read FNoiseSharpness write
  65. SetNoiseSharpness;
  66. property Seamless: Boolean read FSeamless write SetSeamless;
  67. property NoiseRandSeed: Longint read FNoiseRandSeed write SetNoiseRandSeed;
  68. end;
  69. // ------------------------------------------------------------------
  70. implementation
  71. // ------------------------------------------------------------------
  72. constructor TgxProcTextureNoise.Create(AOwner: TPersistent);
  73. (* PERM array Borrowed from Darwyn Peachey.
  74. The gradient table is indexed with an XYZ triplet, which is first turned
  75. into a single random index using a lookup in PERM array. The PERM array simply
  76. contains all numbers in [0..255] in random order. *)
  77. //Can now be set to a different set of Random arrangement
  78. var
  79. i: Integer;
  80. seedBackup: Longint;
  81. z, r, theta: Single;
  82. begin
  83. inherited;
  84. FWidth := 128;
  85. FHeight := 128;
  86. FMinCut := 0;
  87. FNoiseSharpness := 0.99;
  88. FSeamless := False;
  89. seedBackup := RandSeed;
  90. Randomize;
  91. FNoiseRandSeed := Random(2147483647); //Random(10000);
  92. RandSeed := FNoiseRandSeed;
  93. SetPermToDefault;
  94. // Generate random gradient vectors.
  95. for i := 0 to GRADIENT_TABLE_SIZE - 1 do
  96. begin
  97. z := 1 - 2 * Random;
  98. r := sqrt(1 - z * z);
  99. theta := 2 * PI * Random;
  100. FGradients[i * 3] := r * cos(theta);
  101. FGradients[i * 3 + 1] := r * sin(theta);
  102. FGradients[i * 3 + 2] := z;
  103. end;
  104. RandSeed := seedBackup;
  105. end;
  106. destructor TgxProcTextureNoise.Destroy;
  107. begin
  108. ReleaseBitmap32;
  109. inherited;
  110. end;
  111. procedure TgxProcTextureNoise.UpdateNoise;
  112. var
  113. X, Y, C: Integer;
  114. Line: PgxPixel32Array;
  115. nf: Single;
  116. n: Byte;
  117. function NoiseSeamless(Scale: Single): Single;
  118. begin
  119. Result := (Noise(x / Scale, y / Scale) * (Width - x) * (Height - y)
  120. + Noise((x - width) / Scale, y / Scale) * x * (Height - y)
  121. + Noise((x - width) / Scale, (y - Height) / Scale) * x * y
  122. + Noise(x / Scale, (y - Height) / Scale) * (Width - x) * y)
  123. / (Width * Height);
  124. end;
  125. begin
  126. // Update the noise texture.
  127. for y := 0 to FNoiseMap.Height - 1 do
  128. begin
  129. Line := FNoiseMap.ScanLine[y];
  130. for x := 0 to FNoiseMap.Width - 1 do
  131. begin
  132. nf := 0;
  133. case FSeamless of
  134. // Take 4 octaves of noise and add them weighted for seamless.
  135. // uses much Ghz
  136. True:
  137. begin
  138. nf := NoiseSeamless(16)
  139. + NoiseSeamless(8) / 2
  140. + NoiseSeamless(4) / 4
  141. + NoiseSeamless(2) / 8;
  142. end;
  143. // Take 4 octaves of noise and add them.
  144. False:
  145. begin
  146. nf := Noise(x / 16, y / 16)
  147. + Noise(x / 8, y / 8) / 2
  148. + Noise(x / 4, y / 4) / 4
  149. + Noise(x / 2, y / 2) / 8;
  150. end;
  151. end;
  152. // Range between 0 and 255
  153. n := Round(255 * (nf + 1) / 2);
  154. if MinCut > 0 then
  155. begin
  156. // Min Cut
  157. C := n - FMinCut;
  158. if C < 0 then
  159. n := 0
  160. else
  161. // Noise Sharpness
  162. n := 255 - Round(IntPower(FNoiseSharpness, C) * 255);
  163. end;
  164. //if n < 13 then n:=13;
  165. // Write the result to the texture image.
  166. Line^[x].r := n;
  167. Line^[x].g := n;
  168. Line^[x].b := n;
  169. Line^[x].a := n;
  170. end;
  171. end;
  172. end;
  173. function TgxProcTextureNoise.GetBitmap32: TgxBitmap32;
  174. begin
  175. if not Assigned(FNoiseMap) then
  176. begin
  177. FNoiseMap := TgxBitmap32.Create;
  178. FNoiseMap.Width := FWidth;
  179. FNoiseMap.Height := FHeight;
  180. FNoiseMap.Blank := false;
  181. UpdateNoise;
  182. end;
  183. Result := FNoiseMap;
  184. end;
  185. class function TgxProcTextureNoise.FriendlyName: string;
  186. begin
  187. Result := 'Procedural Noise';
  188. end;
  189. class function TgxProcTextureNoise.FriendlyDescription: string;
  190. begin
  191. Result := 'Procedural Noise (Animated)';
  192. end;
  193. procedure TgxProcTextureNoise.SetSeamless(const val: Boolean);
  194. begin
  195. if val <> FSeamless then
  196. begin
  197. FSeamless := val;
  198. Invalidate;
  199. end;
  200. end;
  201. procedure TgxProcTextureNoise.LoadFromFile(const fileName: string);
  202. begin
  203. Assert(False, 'TgxProcTextureNoise.LoadFromFile not implemented');
  204. end;
  205. procedure TgxProcTextureNoise.ReleaseBitmap32;
  206. begin
  207. if Assigned(FNoiseMap) then
  208. begin
  209. FNoiseMap.Free;
  210. FNoiseMap := nil;
  211. end;
  212. end;
  213. procedure TgxProcTextureNoise.SaveToFile(const fileName: string);
  214. begin
  215. // Nothing here
  216. end;
  217. function TgxProcTextureNoise.GetHeight: Integer;
  218. begin
  219. Result := FHeight;
  220. end;
  221. function TgxProcTextureNoise.GetWidth: Integer;
  222. begin
  223. Result := FWidth;
  224. end;
  225. function TgxProcTextureNoise.GetDepth: Integer;
  226. begin
  227. Result := 1;
  228. end;
  229. function TgxProcTextureNoise.GetTextureTarget: TglTextureTarget;
  230. begin
  231. Result := ttTexture2D;
  232. end;
  233. procedure TgxProcTextureNoise.SetHeight(const val: Integer);
  234. begin
  235. if val <> FHeight then
  236. begin
  237. FHeight := val;
  238. if FHeight < 1 then
  239. FHeight := 1;
  240. Invalidate;
  241. end;
  242. end;
  243. procedure TgxProcTextureNoise.SetWidth(const val: Integer);
  244. begin
  245. if val <> FWidth then
  246. begin
  247. FWidth := val;
  248. if FWidth < 1 then
  249. FWidth := 1;
  250. Invalidate;
  251. end;
  252. end;
  253. procedure TgxProcTextureNoise.SetMinCut(const val: Byte);
  254. begin
  255. if val <> FMinCut then
  256. begin
  257. FMinCut := val;
  258. Invalidate;
  259. end;
  260. end;
  261. procedure TgxProcTextureNoise.SetNoiseSharpness(const val: Single);
  262. begin
  263. if val <> FNoiseSharpness then
  264. begin
  265. FNoiseSharpness := val;
  266. if FNoiseSharpness > 1 then
  267. FNoiseSharpness := 1;
  268. Invalidate;
  269. end;
  270. end;
  271. procedure TgxProcTextureNoise.SetNoiseRandSeed(const val: Longint);
  272. var
  273. i: Integer;
  274. seedBackup: Longint;
  275. z, r, theta: Single;
  276. begin
  277. if val <> FNoiseRandSeed then
  278. begin
  279. seedBackup := RandSeed;
  280. FNoiseRandSeed := val;
  281. //Dunno, might be ok to be negative
  282. if FNoiseRandSeed < 1 then
  283. FNoiseRandSeed := 1;
  284. RandSeed := FNoiseRandSeed;
  285. //didnt change so added/copied FGradients here... to get Seed to work
  286. // Generate random gradient vectors.
  287. for i := 0 to GRADIENT_TABLE_SIZE - 1 do
  288. begin
  289. z := 1 - 2 * Random;
  290. r := sqrt(1 - z * z);
  291. theta := 2 * PI * Random;
  292. FGradients[i * 3] := r * cos(theta);
  293. FGradients[i * 3 + 1] := r * sin(theta);
  294. FGradients[i * 3 + 2] := z;
  295. end;
  296. RandSeed := seedBackup;
  297. Invalidate;
  298. end;
  299. end;
  300. procedure TgxProcTextureNoise.Assign(Source: TPersistent);
  301. begin
  302. if Assigned(Source) and (Source is TgxProcTextureNoise) then
  303. begin
  304. FWidth := TgxProcTextureNoise(Source).FWidth;
  305. FHeight := TgxProcTextureNoise(Source).FHeight;
  306. FMinCut := TgxProcTextureNoise(Source).FMinCut;
  307. FNoiseSharpness := TgxProcTextureNoise(Source).FNoiseSharpness;
  308. FNoiseRandSeed := TgxProcTextureNoise(Source).FNoiseRandSeed;
  309. Invalidate;
  310. end
  311. else
  312. inherited;
  313. end;
  314. procedure TgxProcTextureNoise.NoiseAnimate(speed: Single);
  315. begin
  316. FNoiseAnimate := FNoiseAnimate + speed;
  317. Invalidate;
  318. end;
  319. function TgxProcTextureNoise.Noise(x, y: Single): Single;
  320. var
  321. ix, iy, iz: Integer;
  322. fx0, fx1, fy0, fy1, fz0, fz1: Single;
  323. wx, wy, wz: Single;
  324. vx0, vx1, vy0, vy1, vz0, vz1: Single;
  325. function Smooth(x: Single): Single;
  326. begin
  327. (* Smoothing curve. This is used to calculate interpolants so that the noise
  328. doesn't look blocky when the frequency is low. *)
  329. Result := x * x * (3 - 2 * x);
  330. end;
  331. function Permutate(x: Integer): Integer;
  332. const
  333. MASK = GRADIENT_TABLE_SIZE - 1;
  334. begin
  335. // Do a lookup in the permutation table.
  336. Result := PERM[x and MASK];
  337. end;
  338. function Index(ix, iy, iz: Integer): Integer;
  339. begin
  340. // Turn an XYZ triplet into a single gradient table index.
  341. Result := Permutate(ix + Permutate(iy + Permutate(iz)));
  342. end;
  343. function Lattice(lx, ly, lz: Integer; fx, fy, fz: Single): Single;
  344. var
  345. g: Integer;
  346. begin
  347. // Look up a random gradient at [ix,iy,iz] and dot it with the [fx,fy,fz] vector.
  348. g := Index(lx, ly, lz) * 3;
  349. Result := FGradients[g] * fx + FGradients[g + 1] * fy + FGradients[g + 2] *
  350. fz;
  351. end;
  352. function Lerp(t, x0, x1: Single): Single;
  353. begin
  354. // Simple linear interpolation.
  355. Result := x0 + t * (x1 - x0);
  356. end;
  357. begin
  358. (* The main noise function. Looks up the pseudorandom gradients at the nearest
  359. lattice points, dots them with the input vector, and interpolates the
  360. results to produce a single output value in [0, 1] range. *)
  361. ix := Floor(x);
  362. fx0 := x - ix;
  363. fx1 := fx0 - 1;
  364. wx := Smooth(fx0);
  365. iy := Floor(y);
  366. fy0 := y - iy;
  367. fy1 := fy0 - 1;
  368. wy := Smooth(fy0);
  369. iz := Floor(FNoiseAnimate);
  370. fz0 := FNoiseAnimate - iz;
  371. fz1 := fz0 - 1;
  372. wz := Smooth(fz0);
  373. vx0 := Lattice(ix, iy, iz, fx0, fy0, fz0);
  374. vx1 := Lattice(ix + 1, iy, iz, fx1, fy0, fz0);
  375. vy0 := Lerp(wx, vx0, vx1);
  376. vx0 := Lattice(ix, iy + 1, iz, fx0, fy1, fz0);
  377. vx1 := Lattice(ix + 1, iy + 1, iz, fx1, fy1, fz0);
  378. vy1 := Lerp(wx, vx0, vx1);
  379. vz0 := Lerp(wy, vy0, vy1);
  380. vx0 := Lattice(ix, iy, iz + 1, fx0, fy0, fz1);
  381. vx1 := Lattice(ix + 1, iy, iz + 1, fx1, fy0, fz1);
  382. vy0 := Lerp(wx, vx0, vx1);
  383. vx0 := Lattice(ix, iy + 1, iz + 1, fx0, fy1, fz1);
  384. vx1 := Lattice(ix + 1, iy + 1, iz + 1, fx1, fy1, fz1);
  385. vy1 := Lerp(wx, vx0, vx1);
  386. vz1 := Lerp(wy, vy0, vy1);
  387. Result := Lerp(wz, vz0, vz1);
  388. end;
  389. procedure TgxProcTextureNoise.SetPermFromData(inPERM: array of Byte);
  390. var
  391. I: Integer;
  392. begin
  393. for I := 0 to 255 do
  394. PERM[I] := inPERM[I];
  395. Invalidate;
  396. end;
  397. procedure TgxProcTextureNoise.SetPermToDefault;
  398. begin
  399. //225,155,210,108,175,199,221,144,203,116, 70,213, 69,158, 33,252,
  400. PERM[0] := 225;
  401. PERM[1] := 155;
  402. PERM[2] := 210;
  403. PERM[3] := 108;
  404. PERM[4] := 175;
  405. PERM[5] := 199;
  406. PERM[6] := 221;
  407. PERM[7] := 144;
  408. PERM[8] := 203;
  409. PERM[9] := 116;
  410. PERM[10] := 70;
  411. PERM[11] := 213;
  412. PERM[12] := 69;
  413. PERM[13] := 158;
  414. PERM[14] := 33;
  415. PERM[15] := 252;
  416. //5, 82,173,133,222,139,174, 27, 9, 71, 90,246, 75,130, 91,191,
  417. PERM[16] := 5;
  418. PERM[17] := 82;
  419. PERM[18] := 173;
  420. PERM[19] := 133;
  421. PERM[20] := 222;
  422. PERM[21] := 139;
  423. PERM[22] := 174;
  424. PERM[23] := 27;
  425. PERM[24] := 9;
  426. PERM[25] := 71;
  427. PERM[26] := 90;
  428. PERM[27] := 246;
  429. PERM[28] := 75;
  430. PERM[29] := 130;
  431. PERM[30] := 91;
  432. PERM[31] := 191;
  433. //169,138, 2,151,194,235, 81, 7, 25,113,228,159,205,253,134,142,
  434. PERM[32] := 169;
  435. PERM[33] := 138;
  436. PERM[34] := 2;
  437. PERM[35] := 151;
  438. PERM[36] := 194;
  439. PERM[37] := 235;
  440. PERM[38] := 81;
  441. PERM[39] := 7;
  442. PERM[40] := 25;
  443. PERM[41] := 113;
  444. PERM[42] := 228;
  445. PERM[43] := 159;
  446. PERM[44] := 205;
  447. PERM[45] := 253;
  448. PERM[46] := 134;
  449. PERM[47] := 142;
  450. //248, 65,224,217, 22,121,229, 63, 89,103, 96,104,156, 17,201,129,
  451. PERM[48] := 248;
  452. PERM[49] := 65;
  453. PERM[50] := 224;
  454. PERM[51] := 217;
  455. PERM[52] := 22;
  456. PERM[53] := 121;
  457. PERM[54] := 229;
  458. PERM[55] := 63;
  459. PERM[56] := 89;
  460. PERM[57] := 103;
  461. PERM[58] := 96;
  462. PERM[59] := 104;
  463. PERM[60] := 156;
  464. PERM[61] := 17;
  465. PERM[62] := 201;
  466. PERM[63] := 129;
  467. //36, 8,165,110,237,117,231, 56,132,211,152, 20,181,111,239,218,
  468. PERM[64] := 36;
  469. PERM[65] := 8;
  470. PERM[66] := 165;
  471. PERM[67] := 110;
  472. PERM[68] := 237;
  473. PERM[69] := 117;
  474. PERM[70] := 231;
  475. PERM[71] := 56;
  476. PERM[72] := 132;
  477. PERM[73] := 211;
  478. PERM[74] := 152;
  479. PERM[75] := 20;
  480. PERM[76] := 181;
  481. PERM[77] := 111;
  482. PERM[78] := 239;
  483. PERM[79] := 218;
  484. // 170,163, 51,172,157, 47, 80,212,176,250, 87, 49, 99,242,136,189,
  485. PERM[80] := 170;
  486. PERM[81] := 163;
  487. PERM[82] := 51;
  488. PERM[83] := 172;
  489. PERM[84] := 157;
  490. PERM[85] := 47;
  491. PERM[86] := 80;
  492. PERM[86] := 212;
  493. PERM[88] := 176;
  494. PERM[89] := 250;
  495. PERM[90] := 87;
  496. PERM[91] := 49;
  497. PERM[92] := 99;
  498. PERM[93] := 242;
  499. PERM[94] := 136;
  500. PERM[95] := 189;
  501. //162,115, 44, 43,124, 94,150, 16,141,247, 32, 10,198,223,255, 72,
  502. PERM[96] := 162;
  503. PERM[97] := 115;
  504. PERM[98] := 44;
  505. PERM[99] := 43;
  506. PERM[100] := 124;
  507. PERM[101] := 94;
  508. PERM[102] := 150;
  509. PERM[103] := 16;
  510. PERM[104] := 141;
  511. PERM[105] := 247;
  512. PERM[106] := 32;
  513. PERM[107] := 10;
  514. PERM[108] := 198;
  515. PERM[109] := 223;
  516. PERM[110] := 255;
  517. PERM[111] := 72;
  518. //53,131, 84, 57,220,197, 58, 50,208, 11,241, 28, 3,192, 62,202,
  519. PERM[112] := 53;
  520. PERM[113] := 131;
  521. PERM[114] := 84;
  522. PERM[115] := 57;
  523. PERM[116] := 220;
  524. PERM[117] := 197;
  525. PERM[118] := 58;
  526. PERM[119] := 50;
  527. PERM[120] := 208;
  528. PERM[121] := 11;
  529. PERM[122] := 241;
  530. PERM[123] := 28;
  531. PERM[124] := 3;
  532. PERM[125] := 192;
  533. PERM[126] := 62;
  534. PERM[127] := 202;
  535. //18,215,153, 24, 76, 41, 15,179, 39, 46, 55, 6,128,167, 23,188,
  536. PERM[128] := 18;
  537. PERM[129] := 215;
  538. PERM[130] := 153;
  539. PERM[131] := 24;
  540. PERM[132] := 76;
  541. PERM[133] := 41;
  542. PERM[134] := 15;
  543. PERM[135] := 179;
  544. PERM[136] := 39;
  545. PERM[137] := 46;
  546. PERM[138] := 55;
  547. PERM[139] := 6;
  548. PERM[140] := 128;
  549. PERM[141] := 167;
  550. PERM[142] := 23;
  551. PERM[143] := 188;
  552. // 106, 34,187,140,164, 73,112,182,244,195,227, 13, 35, 77,196,185,
  553. PERM[144] := 106;
  554. PERM[145] := 34;
  555. PERM[146] := 187;
  556. PERM[147] := 140;
  557. PERM[148] := 164;
  558. PERM[149] := 73;
  559. PERM[150] := 112;
  560. PERM[151] := 182;
  561. PERM[152] := 244;
  562. PERM[153] := 195;
  563. PERM[154] := 227;
  564. PERM[155] := 13;
  565. PERM[156] := 35;
  566. PERM[157] := 77;
  567. PERM[158] := 196;
  568. PERM[159] := 185;
  569. //26,200,226,119, 31,123,168,125,249, 68,183,230,177,135,160,180,
  570. PERM[160] := 26;
  571. PERM[161] := 200;
  572. PERM[162] := 226;
  573. PERM[163] := 119;
  574. PERM[164] := 31;
  575. PERM[165] := 123;
  576. PERM[166] := 168;
  577. PERM[167] := 125;
  578. PERM[168] := 249;
  579. PERM[169] := 68;
  580. PERM[170] := 183;
  581. PERM[171] := 230;
  582. PERM[172] := 177;
  583. PERM[173] := 135;
  584. PERM[174] := 160;
  585. PERM[175] := 180;
  586. // 12, 1,243,148,102,166, 38,238,251, 37,240,126, 64, 74,161, 40,
  587. PERM[176] := 12;
  588. PERM[177] := 1;
  589. PERM[178] := 243;
  590. PERM[179] := 148;
  591. PERM[180] := 102;
  592. PERM[181] := 166;
  593. PERM[182] := 38;
  594. PERM[183] := 238;
  595. PERM[184] := 251;
  596. PERM[185] := 37;
  597. PERM[186] := 240;
  598. PERM[187] := 126;
  599. PERM[188] := 64;
  600. PERM[189] := 74;
  601. PERM[190] := 161;
  602. PERM[191] := 40;
  603. // 184,149,171,178,101, 66, 29, 59,146, 61,254,107, 42, 86,154, 4,
  604. PERM[192] := 184;
  605. PERM[193] := 149;
  606. PERM[194] := 171;
  607. PERM[195] := 178;
  608. PERM[196] := 101;
  609. PERM[197] := 66;
  610. PERM[198] := 29;
  611. PERM[199] := 59;
  612. PERM[200] := 146;
  613. PERM[201] := 61;
  614. PERM[202] := 254;
  615. PERM[203] := 107;
  616. PERM[204] := 42;
  617. PERM[205] := 86;
  618. PERM[206] := 154;
  619. PERM[207] := 4;
  620. // 236,232,120, 21,233,209, 45, 98,193,114, 78, 19,206, 14,118,127,
  621. PERM[208] := 236;
  622. PERM[209] := 232;
  623. PERM[210] := 120;
  624. PERM[211] := 21;
  625. PERM[212] := 233;
  626. PERM[213] := 209;
  627. PERM[214] := 45;
  628. PERM[215] := 98;
  629. PERM[216] := 193;
  630. PERM[217] := 114;
  631. PERM[218] := 78;
  632. PERM[219] := 19;
  633. PERM[220] := 206;
  634. PERM[221] := 14;
  635. PERM[222] := 118;
  636. PERM[223] := 127;
  637. // 48, 79,147, 85, 30,207,219, 54, 88,234,190,122, 95, 67,143,109,
  638. PERM[224] := 48;
  639. PERM[225] := 79;
  640. PERM[226] := 147;
  641. PERM[227] := 85;
  642. PERM[228] := 30;
  643. PERM[229] := 207;
  644. PERM[230] := 219;
  645. PERM[231] := 54;
  646. PERM[232] := 88;
  647. PERM[233] := 234;
  648. PERM[234] := 190;
  649. PERM[235] := 122;
  650. PERM[236] := 95;
  651. PERM[237] := 67;
  652. PERM[238] := 143;
  653. PERM[239] := 109;
  654. // 137,214,145, 93, 92,100,245, 0,216,186, 60, 83,105, 97,204, 52
  655. PERM[240] := 137;
  656. PERM[241] := 214;
  657. PERM[242] := 145;
  658. PERM[243] := 93;
  659. PERM[244] := 92;
  660. PERM[245] := 100;
  661. PERM[246] := 245;
  662. PERM[247] := 0;
  663. PERM[248] := 216;
  664. PERM[249] := 186;
  665. PERM[250] := 60;
  666. PERM[251] := 83;
  667. PERM[252] := 105;
  668. PERM[253] := 97;
  669. PERM[254] := 204;
  670. PERM[255] := 52;
  671. end;
  672. // ------------------------------------------------------------------
  673. initialization
  674. // ------------------------------------------------------------------
  675. RegisterTextureImageClass(TgxProcTextureNoise);
  676. finalization
  677. end.