TC_Noise2.cginc 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  1. //
  2. // FAST32_hash
  3. // A very fast hashing function. Requires 32bit support.
  4. // http://briansharpe.wordpress.com/2011/11/15/a-fast-and-simple-32bit-floating-point-hash-function/
  5. //
  6. // The hash formula takes the form....
  7. // hash = mod( coord.x * coord.x * coord.y * coord.y, SOMELARGEFLOAT ) / SOMELARGEFLOAT
  8. // We truncate and offset the domain to the most interesting part of the noise.
  9. // SOMELARGEFLOAT should be in the range of 400.0->1000.0 and needs to be hand picked. Only some give good results.
  10. // 3D Noise is achieved by offsetting the SOMELARGEFLOAT value by the Z coordinate
  11. //
  12. // generates 3 random numbers for each of the 8 cell corners
  13. // float h = PerlinDerivedJordan(OUT.pos, _Octaves, _Offset, _Frequency, _Amplitude, _Lacunarity, _Persistence, _Warp0, _Warp, _Damp0, _Damp, _DampScale);
  14. void FAST32_hash_3D(float3 gridcell, out float4 lowz_hash_0, out float4 lowz_hash_1, out float4 lowz_hash_2, out float4 highz_hash_0, out float4 highz_hash_1, out float4 highz_hash_2)
  15. {
  16. // gridcell is assumed to be an integer coordinate
  17. // TODO: these constants need tweaked to find the best possible noise.
  18. // probably requires some kind of brute force computational searching or something....
  19. const float2 OFFSET = float2(50.0, 161.0);
  20. const float DOMAIN = 69.0;
  21. const float3 SOMELARGEFLOATS = float3(635.298681, 682.357502, 668.926525);
  22. const float3 ZINC = float3(48.500388, 65.294118, 63.934599);
  23. // truncate the domain
  24. gridcell.xyz = gridcell.xyz - floor(gridcell.xyz * (1.0 / DOMAIN)) * DOMAIN;
  25. float3 gridcell_inc1 = step(gridcell, float3(DOMAIN - 1.5, DOMAIN - 1.5, DOMAIN - 1.5)) * (gridcell + 1.0);
  26. // calculate the noise
  27. float4 P = float4(gridcell.xy, gridcell_inc1.xy) + OFFSET.xyxy;
  28. P *= P;
  29. P = P.xzxz * P.yyww;
  30. float3 lowz_mod = float3(1.0 / (SOMELARGEFLOATS.xyz + gridcell.zzz * ZINC.xyz));
  31. float3 highz_mod = float3(1.0 / (SOMELARGEFLOATS.xyz + gridcell_inc1.zzz * ZINC.xyz));
  32. lowz_hash_0 = frac(P * lowz_mod.xxxx);
  33. highz_hash_0 = frac(P * highz_mod.xxxx);
  34. lowz_hash_1 = frac(P * lowz_mod.yyyy);
  35. highz_hash_1 = frac(P * highz_mod.yyyy);
  36. lowz_hash_2 = frac(P * lowz_mod.zzzz);
  37. highz_hash_2 = frac(P * highz_mod.zzzz);
  38. }
  39. float4 PerlinSurflet3D_Deriv(float3 P)
  40. {
  41. // establish our grid cell and unit position
  42. float3 Pi = floor(P);
  43. float3 Pf = P - Pi;
  44. float3 Pf_min1 = Pf - 1.0;
  45. // calculate the hash.
  46. // ( various hashing methods listed in order of speed )
  47. float4 hashx0, hashy0, hashz0, hashx1, hashy1, hashz1;
  48. FAST32_hash_3D(Pi, hashx0, hashy0, hashz0, hashx1, hashy1, hashz1);
  49. // calculate the gradients
  50. float4 grad_x0 = hashx0 - 0.49999;
  51. float4 grad_y0 = hashy0 - 0.49999;
  52. float4 grad_z0 = hashz0 - 0.49999;
  53. float4 norm_0 = rsqrt(grad_x0 * grad_x0 + grad_y0 * grad_y0 + grad_z0 * grad_z0);
  54. grad_x0 *= norm_0;
  55. grad_y0 *= norm_0;
  56. grad_z0 *= norm_0;
  57. float4 grad_x1 = hashx1 - 0.49999;
  58. float4 grad_y1 = hashy1 - 0.49999;
  59. float4 grad_z1 = hashz1 - 0.49999;
  60. float4 norm_1 = rsqrt(grad_x1 * grad_x1 + grad_y1 * grad_y1 + grad_z1 * grad_z1);
  61. grad_x1 *= norm_1;
  62. grad_y1 *= norm_1;
  63. grad_z1 *= norm_1;
  64. float4 grad_results_0 = float2(Pf.x, Pf_min1.x).xyxy * grad_x0 + float2(Pf.y, Pf_min1.y).xxyy * grad_y0 + Pf.zzzz * grad_z0;
  65. float4 grad_results_1 = float2(Pf.x, Pf_min1.x).xyxy * grad_x1 + float2(Pf.y, Pf_min1.y).xxyy * grad_y1 + Pf_min1.zzzz * grad_z1;
  66. // get lengths in the x+y plane
  67. float3 Pf_sq = Pf*Pf;
  68. float3 Pf_min1_sq = Pf_min1*Pf_min1;
  69. float4 vecs_len_sq = float2(Pf_sq.x, Pf_min1_sq.x).xyxy + float2(Pf_sq.y, Pf_min1_sq.y).xxyy;
  70. // evaluate the surflet
  71. float4 m_0 = vecs_len_sq + Pf_sq.zzzz;
  72. m_0 = max(1.0 - m_0, 0.0);
  73. float4 m2_0 = m_0*m_0;
  74. float4 m3_0 = m_0*m2_0;
  75. float4 m_1 = vecs_len_sq + Pf_min1_sq.zzzz;
  76. m_1 = max(1.0 - m_1, 0.0);
  77. float4 m2_1 = m_1*m_1;
  78. float4 m3_1 = m_1*m2_1;
  79. // calc the deriv
  80. float4 temp_0 = -6.0 * m2_0 * grad_results_0;
  81. float xderiv_0 = dot(temp_0, float2(Pf.x, Pf_min1.x).xyxy) + dot(m3_0, grad_x0);
  82. float yderiv_0 = dot(temp_0, float2(Pf.y, Pf_min1.y).xxyy) + dot(m3_0, grad_y0);
  83. float zderiv_0 = dot(temp_0, Pf.zzzz) + dot(m3_0, grad_z0);
  84. float4 temp_1 = -6.0 * m2_1 * grad_results_1;
  85. float xderiv_1 = dot(temp_1, float2(Pf.x, Pf_min1.x).xyxy) + dot(m3_1, grad_x1);
  86. float yderiv_1 = dot(temp_1, float2(Pf.y, Pf_min1.y).xxyy) + dot(m3_1, grad_y1);
  87. float zderiv_1 = dot(temp_1, Pf_min1.zzzz) + dot(m3_1, grad_z1);
  88. const float FINAL_NORMALIZATION = 2.3703703703703703703703703703704; // scales the final result to a strict 1.0->-1.0 range
  89. return float4(dot(m3_0, grad_results_0) + dot(m3_1, grad_results_1), float3(xderiv_0, yderiv_0, zderiv_0) + float3(xderiv_1, yderiv_1, zderiv_1)) * FINAL_NORMALIZATION;
  90. }
  91. void FAST32_hash_3D(float3 gridcell, out float4 lowz_hash, out float4 highz_hash) // generates a random number for each of the 8 cell corners
  92. {
  93. // gridcell is assumed to be an integer coordinate
  94. // TODO: these constants need tweaked to find the best possible noise.
  95. // probably requires some kind of brute force computational searching or something....
  96. const float2 OFFSET = float2(50.0, 161.0);
  97. const float DOMAIN = 69.0;
  98. const float SOMELARGEFLOAT = 635.298681;
  99. const float ZINC = 48.500388;
  100. // truncate the domain
  101. gridcell.xyz = gridcell.xyz - floor(gridcell.xyz * (1.0 / DOMAIN)) * DOMAIN;
  102. float3 gridcell_inc1 = step(gridcell, float3(DOMAIN - 1.5, DOMAIN - 1.5, DOMAIN - 1.5)) * (gridcell + 1.0);
  103. // calculate the noise
  104. float4 P = float4(gridcell.xy, gridcell_inc1.xy) + OFFSET.xyxy;
  105. P *= P;
  106. P = P.xzxz * P.yyww;
  107. highz_hash.xy = float2(1.0 / (SOMELARGEFLOAT + float2(gridcell.z, gridcell_inc1.z) * ZINC));
  108. lowz_hash = frac(P * highz_hash.xxxx);
  109. highz_hash = frac(P * highz_hash.yyyy);
  110. }
  111. //
  112. // Interpolation functions
  113. // ( smoothly increase from 0.0 to 1.0 as x increases linearly from 0.0 to 1.0 )
  114. // http://briansharpe.wordpress.com/2011/11/14/two-useful-interpolation-functions-for-noise-development/
  115. //
  116. float3 Interpolation_C2(float3 x) { return x * x * x * (x * (x * 6.0 - 15.0) + 10.0); }
  117. float3 Interpolation_C2_Deriv(float3 x) { return x * x * (x * (x * 30.0 - 60.0) + 30.0); }
  118. //
  119. // Value3D_Deriv
  120. // Value3D noise with derivatives
  121. // returns float3( value, xderiv, yderiv, zderiv )
  122. //
  123. float4 Value3D_Deriv(float3 P)
  124. {
  125. // establish our grid cell and unit position
  126. float3 Pi = floor(P);
  127. float3 Pf = P - Pi;
  128. // calculate the hash.
  129. // ( various hashing methods listed in order of speed )
  130. float4 hash_lowz, hash_highz;
  131. FAST32_hash_3D(Pi, hash_lowz, hash_highz);
  132. // blend the results and return
  133. float3 blend = Interpolation_C2(Pf);
  134. float4 res0 = lerp(hash_lowz, hash_highz, blend.z);
  135. float4 res1 = lerp(res0.xyxz, res0.zwyw, blend.yyxx);
  136. float4 res3 = lerp(float4(hash_lowz.xy, hash_highz.xy), float4(hash_lowz.zw, hash_highz.zw), blend.y);
  137. float2 res4 = lerp(res3.xz, res3.yw, blend.x);
  138. return float4(res1.x, 0.0, 0.0, 0.0) + (float4(res1.yyw, res4.y) - float4(res1.xxz, res4.x)) * float4(blend.x, Interpolation_C2_Deriv(Pf));
  139. }
  140. void FAST32_hash_3D(float3 gridcell, float3 v1_mask, float3 v2_mask, out float4 hash_0, out float4 hash_1, out float4 hash_2) // generates 3 random numbers for each of the 4 3D cell corners. cell corners: v0=0,0,0 v3=1,1,1 the other two are user definable
  141. {
  142. // gridcell is assumed to be an integer coordinate
  143. // TODO: these constants need tweaked to find the best possible noise.
  144. // probably requires some kind of brute force computational searching or something....
  145. const float2 OFFSET = float2(50.0, 161.0);
  146. const float DOMAIN = 69.0;
  147. const float3 SOMELARGEFLOATS = float3(635.298681, 682.357502, 668.926525);
  148. const float3 ZINC = float3(48.500388, 65.294118, 63.934599);
  149. // truncate the domain
  150. gridcell.xyz = gridcell.xyz - floor(gridcell.xyz * (1.0 / DOMAIN)) * DOMAIN;
  151. float3 gridcell_inc1 = step(gridcell, float3(DOMAIN - 1.5, DOMAIN - 1.5, DOMAIN - 1.5)) * (gridcell + 1.0);
  152. // compute x*x*y*y for the 4 corners
  153. float4 P = float4(gridcell.xy, gridcell_inc1.xy) + OFFSET.xyxy;
  154. P *= P;
  155. float4 V1xy_V2xy = lerp(P.xyxy, P.zwzw, float4(v1_mask.xy, v2_mask.xy)); // apply mask for v1 and v2
  156. P = float4(P.x, V1xy_V2xy.xz, P.z) * float4(P.y, V1xy_V2xy.yw, P.w);
  157. // get the lowz and highz mods
  158. float3 lowz_mods = float3(1.0 / (SOMELARGEFLOATS.xyz + gridcell.zzz * ZINC.xyz));
  159. float3 highz_mods = float3(1.0 / (SOMELARGEFLOATS.xyz + gridcell_inc1.zzz * ZINC.xyz));
  160. // apply mask for v1 and v2 mod values
  161. v1_mask = (v1_mask.z < 0.5) ? lowz_mods : highz_mods;
  162. v2_mask = (v2_mask.z < 0.5) ? lowz_mods : highz_mods;
  163. // compute the final hash
  164. hash_0 = frac(P * float4(lowz_mods.x, v1_mask.x, v2_mask.x, highz_mods.x));
  165. hash_1 = frac(P * float4(lowz_mods.y, v1_mask.y, v2_mask.y, highz_mods.y));
  166. hash_2 = frac(P * float4(lowz_mods.z, v1_mask.z, v2_mask.z, highz_mods.z));
  167. }
  168. //
  169. // Given an arbitrary 3D point this calculates the 4 vectors from the corners of the simplex pyramid to the point
  170. // It also returns the integer grid index information for the corners
  171. //
  172. void Simplex3D_GetCornerVectors(float3 P, // input point
  173. out float3 Pi, // integer grid index for the origin
  174. out float3 Pi_1, // offsets for the 2nd and 3rd corners. ( the 4th = Pi + 1.0 )
  175. out float3 Pi_2,
  176. out float4 v1234_x, // vectors from the 4 corners to the intput point
  177. out float4 v1234_y,
  178. out float4 v1234_z)
  179. {
  180. //
  181. // Simplex math from Stefan Gustavson's and Ian McEwan's work at...
  182. // http://github.com/ashima/webgl-noise
  183. //
  184. // simplex math constants
  185. const float SKEWFACTOR = 1.0 / 3.0;
  186. const float UNSKEWFACTOR = 1.0 / 6.0;
  187. const float SIMPLEX_CORNER_POS = 0.5;
  188. const float SIMPLEX_PYRAMID_HEIGHT = 0.70710678118654752440084436210485; // sqrt( 0.5 ) height of simplex pyramid.
  189. P *= SIMPLEX_PYRAMID_HEIGHT; // scale space so we can have an approx feature size of 1.0 ( optional )
  190. // Find the vectors to the corners of our simplex pyramid
  191. Pi = floor(P + dot(P, float3(SKEWFACTOR, SKEWFACTOR, SKEWFACTOR)));
  192. float3 x0 = P - Pi + dot(Pi, float3(UNSKEWFACTOR, UNSKEWFACTOR, UNSKEWFACTOR));
  193. float3 g = step(x0.yzx, x0.xyz);
  194. float3 l = 1.0 - g;
  195. Pi_1 = min(g.xyz, l.zxy);
  196. Pi_2 = max(g.xyz, l.zxy);
  197. float3 x1 = x0 - Pi_1 + UNSKEWFACTOR;
  198. float3 x2 = x0 - Pi_2 + SKEWFACTOR;
  199. float3 x3 = x0 - SIMPLEX_CORNER_POS;
  200. // pack them into a parallel-friendly arrangement
  201. v1234_x = float4(x0.x, x1.x, x2.x, x3.x);
  202. v1234_y = float4(x0.y, x1.y, x2.y, x3.y);
  203. v1234_z = float4(x0.z, x1.z, x2.z, x3.z);
  204. }
  205. //
  206. // SimplexPerlin3D_Deriv
  207. // SimplexPerlin3D noise with derivatives
  208. // returns float3( value, xderiv, yderiv, zderiv )
  209. //
  210. float4 SimplexPerlin3D_Deriv(float3 P)
  211. {
  212. // calculate the simplex vector and index math
  213. float3 Pi;
  214. float3 Pi_1;
  215. float3 Pi_2;
  216. float4 v1234_x;
  217. float4 v1234_y;
  218. float4 v1234_z;
  219. Simplex3D_GetCornerVectors(P, Pi, Pi_1, Pi_2, v1234_x, v1234_y, v1234_z);
  220. // generate the random vectors
  221. // ( various hashing methods listed in order of speed )
  222. float4 hash_0;
  223. float4 hash_1;
  224. float4 hash_2;
  225. FAST32_hash_3D(Pi, Pi_1, Pi_2, hash_0, hash_1, hash_2);
  226. hash_0 -= 0.49999;
  227. hash_1 -= 0.49999;
  228. hash_2 -= 0.49999;
  229. // normalize random gradient vectors
  230. float4 norm = rsqrt(hash_0 * hash_0 + hash_1 * hash_1 + hash_2 * hash_2);
  231. hash_0 *= norm;
  232. hash_1 *= norm;
  233. hash_2 *= norm;
  234. // evaluate gradients
  235. float4 grad_results = hash_0 * v1234_x + hash_1 * v1234_y + hash_2 * v1234_z;
  236. // evaluate the surflet f(x)=(0.5-x*x)^3
  237. float4 m = v1234_x * v1234_x + v1234_y * v1234_y + v1234_z * v1234_z;
  238. m = max(0.5 - m, 0.0); // The 0.5 here is SIMPLEX_PYRAMID_HEIGHT^2
  239. float4 m2 = m*m;
  240. float4 m3 = m*m2;
  241. // calc the deriv
  242. float4 temp = -6.0 * m2 * grad_results;
  243. float xderiv = dot(temp, v1234_x) + dot(m3, hash_0);
  244. float yderiv = dot(temp, v1234_y) + dot(m3, hash_1);
  245. float zderiv = dot(temp, v1234_z) + dot(m3, hash_2);
  246. const float FINAL_NORMALIZATION = 37.837227241611314102871574478976; // scales the final result to a strict 1.0->-1.0 range
  247. // sum with the surflet and return
  248. return float4(dot(m3, grad_results), xderiv, yderiv, zderiv) * FINAL_NORMALIZATION;
  249. }
  250. float Perlin3D(float3 P)
  251. {
  252. // establish our grid cell and unit position
  253. float3 Pi = floor(P);
  254. float3 Pf = P - Pi;
  255. float3 Pf_min1 = Pf - 1.0;
  256. //
  257. // classic noise.
  258. // requires 3 random values per point. with an efficent hash function will run faster than improved noise
  259. //
  260. // calculate the hash.
  261. // ( various hashing methods listed in order of speed )
  262. float4 hashx0, hashy0, hashz0, hashx1, hashy1, hashz1;
  263. FAST32_hash_3D(Pi, hashx0, hashy0, hashz0, hashx1, hashy1, hashz1);
  264. // calculate the gradients
  265. float4 grad_x0 = hashx0 - 0.49999;
  266. float4 grad_y0 = hashy0 - 0.49999;
  267. float4 grad_z0 = hashz0 - 0.49999;
  268. float4 grad_x1 = hashx1 - 0.49999;
  269. float4 grad_y1 = hashy1 - 0.49999;
  270. float4 grad_z1 = hashz1 - 0.49999;
  271. float4 grad_results_0 = rsqrt(grad_x0 * grad_x0 + grad_y0 * grad_y0 + grad_z0 * grad_z0) * (float2(Pf.x, Pf_min1.x).xyxy * grad_x0 + float2(Pf.y, Pf_min1.y).xxyy * grad_y0 + Pf.zzzz * grad_z0);
  272. float4 grad_results_1 = rsqrt(grad_x1 * grad_x1 + grad_y1 * grad_y1 + grad_z1 * grad_z1) * (float2(Pf.x, Pf_min1.x).xyxy * grad_x1 + float2(Pf.y, Pf_min1.y).xxyy * grad_y1 + Pf_min1.zzzz * grad_z1);
  273. // Classic Perlin Interpolation
  274. float3 blend = Interpolation_C2(Pf);
  275. float4 res0 = lerp(grad_results_0, grad_results_1, blend.z);
  276. float2 res1 = lerp(res0.xy, res0.zw, blend.y);
  277. float final = lerp(res1.x, res1.y, blend.x);
  278. final *= 1.1547005383792515290182975610039; // (optionally) scale things to a strict -1.0->1.0 range *= 1.0/sqrt(0.75)
  279. return final;
  280. }
  281. float4 Simplex3D_GetSurfletWeights(float4 v1234_x, float4 v1234_y, float4 v1234_z)
  282. {
  283. // perlins original implementation uses the surlet falloff formula of (0.6-x*x)^4.
  284. // This is buggy as it can cause discontinuities along simplex faces. (0.5-x*x)^3 solves this and gives an almost identical curve
  285. // evaluate surflet. f(x)=(0.5-x*x)^3
  286. float4 surflet_weights = v1234_x * v1234_x + v1234_y * v1234_y + v1234_z * v1234_z;
  287. surflet_weights = max(0.5 - surflet_weights, 0.0); // 0.5 here represents the closest distance (squared) of any simplex pyramid corner to any of its planes. ie, SIMPLEX_PYRAMID_HEIGHT^2
  288. return surflet_weights*surflet_weights*surflet_weights;
  289. }
  290. float SimplexPerlin3D(float3 P)
  291. {
  292. // calculate the simplex vector and index math
  293. float3 Pi;
  294. float3 Pi_1;
  295. float3 Pi_2;
  296. float4 v1234_x;
  297. float4 v1234_y;
  298. float4 v1234_z;
  299. Simplex3D_GetCornerVectors(P, Pi, Pi_1, Pi_2, v1234_x, v1234_y, v1234_z);
  300. // generate the random vectors
  301. // ( various hashing methods listed in order of speed )
  302. float4 hash_0;
  303. float4 hash_1;
  304. float4 hash_2;
  305. FAST32_hash_3D(Pi, Pi_1, Pi_2, hash_0, hash_1, hash_2);
  306. hash_0 -= 0.49999;
  307. hash_1 -= 0.49999;
  308. hash_2 -= 0.49999;
  309. // evaluate gradients
  310. float4 grad_results = rsqrt(hash_0 * hash_0 + hash_1 * hash_1 + hash_2 * hash_2) * (hash_0 * v1234_x + hash_1 * v1234_y + hash_2 * v1234_z);
  311. // Normalization factor to scale the final result to a strict 1.0->-1.0 range
  312. // x = sqrt( 0.75 ) * 0.5
  313. // NF = 1.0 / ( x * ( ( 0.5 ? x*x ) ^ 3 ) * 2.0 )
  314. // http://briansharpe.wordpress.com/2012/01/13/simplex-noise/#comment-36
  315. const float FINAL_NORMALIZATION = 37.837227241611314102871574478976;
  316. // sum with the surflet and return
  317. return dot(Simplex3D_GetSurfletWeights(v1234_x, v1234_y, v1234_z), grad_results) * FINAL_NORMALIZATION;
  318. }
  319. float Value3D(float3 P)
  320. {
  321. // establish our grid cell and unit position
  322. float3 Pi = floor(P);
  323. float3 Pf = P - Pi;
  324. // calculate the hash.
  325. // ( various hashing methods listed in order of speed )
  326. float4 hash_lowz, hash_highz;
  327. FAST32_hash_3D(Pi, hash_lowz, hash_highz);
  328. // blend the results and return
  329. float3 blend = Interpolation_C2(Pf);
  330. float4 res0 = lerp(hash_lowz, hash_highz, blend.z);
  331. float2 res1 = lerp(res0.xy, res0.zw, blend.y);
  332. return lerp(res1.x, res1.y, blend.x);
  333. }
  334. float4 FAST32_hash_3D_Cell(float3 gridcell) // generates 4 different random numbers for the single given cell point
  335. {
  336. // gridcell is assumed to be an integer coordinate
  337. // TODO: these constants need tweaked to find the best possible noise.
  338. // probably requires some kind of brute force computational searching or something....
  339. const float2 OFFSET = float2(50.0, 161.0);
  340. const float DOMAIN = 69.0;
  341. const float4 SOMELARGEFLOATS = float4(635.298681, 682.357502, 668.926525, 588.255119);
  342. const float4 ZINC = float4(48.500388, 65.294118, 63.934599, 63.279683);
  343. // truncate the domain
  344. gridcell.xyz = gridcell - floor(gridcell * (1.0 / DOMAIN)) * DOMAIN;
  345. gridcell.xy += OFFSET.xy;
  346. gridcell.xy *= gridcell.xy;
  347. return frac((gridcell.x * gridcell.y) * (1.0 / (SOMELARGEFLOATS + gridcell.zzzz * ZINC)));
  348. }
  349. static const int MinVal = -1;
  350. static const int MaxVal = 1;
  351. float Cellular3D(float3 xyz, int cellType, int distanceFunction)
  352. {
  353. int xi = int(floor(xyz.x));
  354. int yi = int(floor(xyz.y));
  355. int zi = int(floor(xyz.z));
  356. float xf = xyz.x - float(xi);
  357. float yf = xyz.y - float(yi);
  358. float zf = xyz.z - float(zi);
  359. float dist1 = 9999999.0;
  360. float dist2 = 9999999.0;
  361. float dist3 = 9999999.0;
  362. float dist4 = 9999999.0;
  363. float3 cell;
  364. for (int z = MinVal; z <= MaxVal; z++) {
  365. for (int y = MinVal; y <= MaxVal; y++) {
  366. for (int x = MinVal; x <= MaxVal; x++) {
  367. cell = FAST32_hash_3D_Cell(float3(xi + x, yi + y, zi + z)).xyz;
  368. cell.x += (float(x) - xf);
  369. cell.y += (float(y) - yf);
  370. cell.z += (float(z) - zf);
  371. float dist = 0.0;
  372. if (distanceFunction == 1)
  373. {
  374. dist = sqrt(dot(cell, cell));
  375. }
  376. else if (distanceFunction == 2)
  377. {
  378. dist = dot(cell, cell);
  379. }
  380. else if (distanceFunction == 3)
  381. {
  382. dist = abs(cell.x) + abs(cell.y) + abs(cell.z);
  383. dist *= 0.5;
  384. dist *= dist;
  385. }
  386. else if (distanceFunction == 4)
  387. {
  388. dist = max(abs(cell.x), max(abs(cell.y), abs(cell.z)));
  389. dist *= dist;
  390. }
  391. else if (distanceFunction == 5)
  392. {
  393. dist = dot(cell, cell) + cell.x*cell.y + cell.x*cell.z + cell.y*cell.z;
  394. }
  395. else if (distanceFunction == 6)
  396. {
  397. dist = pow(abs(cell.x*cell.x*cell.x*cell.x + cell.y*cell.y*cell.y*cell.y + cell.z*cell.z*cell.z*cell.z), 0.25);
  398. }
  399. else if (distanceFunction == 7)
  400. {
  401. dist = sqrt(abs(cell.x)) + sqrt(abs(cell.y)) + sqrt(abs(cell.z));
  402. dist *= 0.5;
  403. dist *= dist;
  404. }
  405. if (dist < dist1)
  406. {
  407. dist4 = dist3;
  408. dist3 = dist2;
  409. dist2 = dist1;
  410. dist1 = dist;
  411. }
  412. else if (dist < dist2)
  413. {
  414. dist4 = dist3;
  415. dist3 = dist2;
  416. dist2 = dist;
  417. }
  418. else if (dist < dist3)
  419. {
  420. dist4 = dist3;
  421. dist3 = dist;
  422. }
  423. else if (dist < dist4)
  424. {
  425. dist4 = dist;
  426. }
  427. }
  428. }
  429. }
  430. if (cellType == 1) // F1
  431. return dist1 / 2; // scale return value from 0.0->1.333333 to 0.0->1.0 (2/3)^2 * 3 == (12/9) == 1.333333
  432. else if (cellType == 2) // F2
  433. return dist2 / 2.5;
  434. else if (cellType == 3) // F3
  435. return dist3 / 3;
  436. else if (cellType == 4) // F4
  437. return dist4 / 4;
  438. else if (cellType == 5) // F2 - F1
  439. return dist2 - dist1;
  440. else if (cellType == 6) // F3 - F2
  441. return dist3 - dist2;
  442. else if (cellType == 7) // F1 + F2/2
  443. return (dist1 + dist2) / 4.0;
  444. else if (cellType == 8) // F1 * F2
  445. return (dist1 * dist2) / 2.0;
  446. else if (cellType == 9) // Crackle
  447. return max(1.0, 10 * (dist2 - dist1)) * 0.10;
  448. else return dist1;
  449. }
  450. float4 Cellular_weight_samples(float4 samples)
  451. {
  452. samples = samples * 2.0 - 1.0;
  453. //return (1.0 - samples * samples) * sign(samples); // square
  454. return (samples * samples * samples) - sign(samples); // cubic (even more variance)
  455. }
  456. float Cellular3D(float3 P)
  457. {
  458. // establish our grid cell and unit position
  459. float3 Pi = floor(P);
  460. float3 Pf = P - Pi;
  461. // calculate the hash.
  462. // ( various hashing methods listed in order of speed )
  463. float4 hash_x0, hash_y0, hash_z0, hash_x1, hash_y1, hash_z1;
  464. FAST32_hash_3D(Pi, hash_x0, hash_y0, hash_z0, hash_x1, hash_y1, hash_z1);
  465. // generate the 8 random points
  466. // restrict the random point offset to eliminate artifacts
  467. // we'll improve the variance of the noise by pushing the points to the extremes of the jitter window
  468. const float JITTER_WINDOW = 0.166666666; // 0.166666666 will guarentee no artifacts. It is the intersection on x of graphs f(x)=( (0.5 + (0.5-x))^2 + 2*((0.5-x)^2) ) and f(x)=( 2 * (( 0.5 + x )^2) + x * x )
  469. hash_x0 = Cellular_weight_samples(hash_x0) * JITTER_WINDOW + float4(0.0, 1.0, 0.0, 1.0);
  470. hash_y0 = Cellular_weight_samples(hash_y0) * JITTER_WINDOW + float4(0.0, 0.0, 1.0, 1.0);
  471. hash_x1 = Cellular_weight_samples(hash_x1) * JITTER_WINDOW + float4(0.0, 1.0, 0.0, 1.0);
  472. hash_y1 = Cellular_weight_samples(hash_y1) * JITTER_WINDOW + float4(0.0, 0.0, 1.0, 1.0);
  473. hash_z0 = Cellular_weight_samples(hash_z0) * JITTER_WINDOW + float4(0.0, 0.0, 0.0, 0.0);
  474. hash_z1 = Cellular_weight_samples(hash_z1) * JITTER_WINDOW + float4(1.0, 1.0, 1.0, 1.0);
  475. // return the closest squared distance
  476. float4 dx1 = Pf.xxxx - hash_x0;
  477. float4 dy1 = Pf.yyyy - hash_y0;
  478. float4 dz1 = Pf.zzzz - hash_z0;
  479. float4 dx2 = Pf.xxxx - hash_x1;
  480. float4 dy2 = Pf.yyyy - hash_y1;
  481. float4 dz2 = Pf.zzzz - hash_z1;
  482. float4 d1 = dx1 * dx1 + dy1 * dy1 + dz1 * dz1;
  483. float4 d2 = dx2 * dx2 + dy2 * dy2 + dz2 * dz2;
  484. d1 = min(d1, d2);
  485. d1.xy = min(d1.xy, d1.wz);
  486. return min(d1.x, d1.y) * (9.0 / 12.0); // scale return value from 0.0->1.333333 to 0.0->1.0 (2/3)^2 * 3 == (12/9) == 1.333333
  487. }