MaterialFunctions.hx 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. package arm.node;
  2. class MaterialFunctions {
  3. public static var str_tex_checker = "
  4. vec3 tex_checker(const vec3 co, const vec3 col1, const vec3 col2, const float scale) {
  5. // Prevent precision issues on unit coordinates
  6. vec3 p = (co + 0.000001 * 0.999999) * scale;
  7. float xi = abs(floor(p.x));
  8. float yi = abs(floor(p.y));
  9. float zi = abs(floor(p.z));
  10. bool check = ((mod(xi, 2.0) == mod(yi, 2.0)) == bool(mod(zi, 2.0)));
  11. return check ? col1 : col2;
  12. }
  13. float tex_checker_f(const vec3 co, const float scale) {
  14. vec3 p = (co + 0.000001 * 0.999999) * scale;
  15. float xi = abs(floor(p.x));
  16. float yi = abs(floor(p.y));
  17. float zi = abs(floor(p.z));
  18. return float((mod(xi, 2.0) == mod(yi, 2.0)) == bool(mod(zi, 2.0)));
  19. }
  20. ";
  21. // Created by inigo quilez - iq/2013
  22. // License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
  23. public static var str_tex_voronoi = "
  24. vec4 tex_voronoi(const vec3 x) {
  25. vec3 p = floor(x);
  26. vec3 f = fract(x);
  27. float id = 0.0;
  28. float res = 100.0;
  29. for (int k = -1; k <= 1; k++)
  30. for (int j = -1; j <= 1; j++)
  31. for (int i = -1; i <= 1; i++) {
  32. vec3 b = vec3(float(i), float(j), float(k));
  33. vec3 pb = p + b;
  34. vec3 r = vec3(b) - f + texture(snoise256, (pb.xy + vec2(3.0, 1.0) * pb.z + 0.5) / 256.0).xyz;
  35. float d = dot(r, r);
  36. if (d < res) {
  37. id = dot(p + b, vec3(1.0, 57.0, 113.0));
  38. res = d;
  39. }
  40. }
  41. vec3 col = 0.5 + 0.5 * cos(id * 0.35 + vec3(0.0, 1.0, 2.0));
  42. return vec4(col, sqrt(res));
  43. }
  44. ";
  45. // By Morgan McGuire @morgan3d, http://graphicscodex.com Reuse permitted under the BSD license.
  46. // https://www.shadertoy.com/view/4dS3Wd
  47. public static var str_tex_noise = "
  48. float hash(float n) { return fract(sin(n) * 1e4); }
  49. float tex_noise_f(vec3 x) {
  50. const vec3 step = vec3(110, 241, 171);
  51. vec3 i = floor(x);
  52. vec3 f = fract(x);
  53. float n = dot(i, step);
  54. vec3 u = f * f * (3.0 - 2.0 * f);
  55. return mix(mix(mix(hash(n + dot(step, vec3(0, 0, 0))), hash(n + dot(step, vec3(1, 0, 0))), u.x),
  56. mix(hash(n + dot(step, vec3(0, 1, 0))), hash(n + dot(step, vec3(1, 1, 0))), u.x), u.y),
  57. mix(mix(hash(n + dot(step, vec3(0, 0, 1))), hash(n + dot(step, vec3(1, 0, 1))), u.x),
  58. mix(hash(n + dot(step, vec3(0, 1, 1))), hash(n + dot(step, vec3(1, 1, 1))), u.x), u.y), u.z);
  59. }
  60. float tex_noise(vec3 p) {
  61. p *= 1.25;
  62. float f = 0.5 * tex_noise_f(p); p *= 2.01;
  63. f += 0.25 * tex_noise_f(p); p *= 2.02;
  64. f += 0.125 * tex_noise_f(p); p *= 2.03;
  65. f += 0.0625 * tex_noise_f(p);
  66. return 1.0 - f;
  67. }
  68. ";
  69. // Based on noise created by Nikita Miropolskiy, nikat/2013
  70. // Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
  71. public static var str_tex_musgrave = "
  72. vec3 random3(const vec3 c) {
  73. float j = 4096.0 * sin(dot(c, vec3(17.0, 59.4, 15.0)));
  74. vec3 r;
  75. r.z = fract(512.0 * j);
  76. j *= 0.125;
  77. r.x = fract(512.0 * j);
  78. j *= 0.125;
  79. r.y = fract(512.0 * j);
  80. return r - 0.5;
  81. }
  82. float tex_musgrave_f(const vec3 p) {
  83. const float F3 = 0.3333333;
  84. const float G3 = 0.1666667;
  85. vec3 s = floor(p + dot(p, vec3(F3, F3, F3)));
  86. vec3 x = p - s + dot(s, vec3(G3, G3, G3));
  87. vec3 e = step(vec3(0.0, 0.0, 0.0), x - x.yzx);
  88. vec3 i1 = e*(1.0 - e.zxy);
  89. vec3 i2 = 1.0 - e.zxy*(1.0 - e);
  90. vec3 x1 = x - i1 + G3;
  91. vec3 x2 = x - i2 + 2.0*G3;
  92. vec3 x3 = x - 1.0 + 3.0*G3;
  93. vec4 w, d;
  94. w.x = dot(x, x);
  95. w.y = dot(x1, x1);
  96. w.z = dot(x2, x2);
  97. w.w = dot(x3, x3);
  98. w = max(0.6 - w, 0.0);
  99. d.x = dot(random3(s), x);
  100. d.y = dot(random3(s + i1), x1);
  101. d.z = dot(random3(s + i2), x2);
  102. d.w = dot(random3(s + 1.0), x3);
  103. w *= w;
  104. w *= w;
  105. d *= w;
  106. return clamp(dot(d, vec4(52.0, 52.0, 52.0, 52.0)), 0.0, 1.0);
  107. }
  108. ";
  109. public static var str_hue_sat = "
  110. vec3 hsv_to_rgb(const vec3 c) {
  111. const vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
  112. vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
  113. return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
  114. }
  115. vec3 rgb_to_hsv(const vec3 c) {
  116. const vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
  117. vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
  118. vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
  119. float d = q.x - min(q.w, q.y);
  120. float e = 1.0e-10;
  121. return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
  122. }
  123. vec3 hue_sat(const vec3 col, const vec4 shift) {
  124. vec3 hsv = rgb_to_hsv(col);
  125. hsv.x += shift.x;
  126. hsv.y *= shift.y;
  127. hsv.z *= shift.z;
  128. return mix(hsv_to_rgb(hsv), col, shift.w);
  129. }
  130. ";
  131. // https://twitter.com/Donzanoid/status/903424376707657730
  132. public static var str_wavelength_to_rgb = "
  133. vec3 wavelength_to_rgb(const float t) {
  134. vec3 r = t * 2.1 - vec3(1.8, 1.14, 0.3);
  135. return 1.0 - r * r;
  136. }
  137. ";
  138. public static var str_tex_magic = "
  139. vec3 tex_magic(const vec3 p) {
  140. float a = 1.0 - (sin(p.x) + sin(p.y));
  141. float b = 1.0 - sin(p.x - p.y);
  142. float c = 1.0 - sin(p.x + p.y);
  143. return vec3(a, b, c);
  144. }
  145. float tex_magic_f(const vec3 p) {
  146. vec3 c = tex_magic(p);
  147. return (c.x + c.y + c.z) / 3.0;
  148. }
  149. ";
  150. public static var str_tex_brick = "
  151. vec3 tex_brick(vec3 p, const vec3 c1, const vec3 c2, const vec3 c3) {
  152. p /= vec3(0.9, 0.49, 0.49) / 2;
  153. if (fract(p.y * 0.5) > 0.5) p.x += 0.5;
  154. p = fract(p);
  155. vec3 b = step(p, vec3(0.95, 0.9, 0.9));
  156. return mix(c3, c1, b.x * b.y * b.z);
  157. }
  158. float tex_brick_f(vec3 p) {
  159. p /= vec3(0.9, 0.49, 0.49) / 2;
  160. if (fract(p.y * 0.5) > 0.5) p.x += 0.5;
  161. p = fract(p);
  162. vec3 b = step(p, vec3(0.95, 0.9, 0.9));
  163. return mix(1.0, 0.0, b.x * b.y * b.z);
  164. }
  165. ";
  166. public static var str_tex_wave = "
  167. float tex_wave_f(const vec3 p) {
  168. return 1.0 - sin((p.x + p.y) * 10.0);
  169. }
  170. ";
  171. public static var str_brightcontrast = "
  172. vec3 brightcontrast(const vec3 col, const float bright, const float contr) {
  173. float a = 1.0 + contr;
  174. float b = bright - contr * 0.5;
  175. return max(a * col + b, 0.0);
  176. }
  177. ";
  178. //
  179. public static var str_traceAO = "
  180. float traceConeAO(sampler3D voxels, const vec3 origin, vec3 dir, const float aperture, const float maxDist, const float offset) {
  181. const ivec3 voxelgiResolution = ivec3(256, 256, 256);
  182. const float voxelgiStep = 1.0;
  183. const float VOXEL_SIZE = (2.0 / voxelgiResolution.x) * voxelgiStep;
  184. dir = normalize(dir);
  185. float sampleCol = 0.0;
  186. float dist = offset;
  187. float diam = dist * aperture;
  188. vec3 samplePos;
  189. while (sampleCol < 1.0 && dist < maxDist) {
  190. samplePos = dir * dist + origin;
  191. float mip = max(log2(diam * voxelgiResolution.x), 0);
  192. float mipSample = textureLod(voxels, samplePos * 0.5 + vec3(0.5, 0.5, 0.5), mip).r;
  193. sampleCol += (1 - sampleCol) * mipSample;
  194. dist += max(diam / 2, VOXEL_SIZE);
  195. diam = dist * aperture;
  196. }
  197. return sampleCol;
  198. }
  199. vec3 tangent(const vec3 n) {
  200. vec3 t1 = cross(n, vec3(0, 0, 1));
  201. vec3 t2 = cross(n, vec3(0, 1, 0));
  202. if (length(t1) > length(t2)) return normalize(t1);
  203. else return normalize(t2);
  204. }
  205. float traceAO(const vec3 origin, const vec3 normal, const float vrange, const float voffset) {
  206. const float angleMix = 0.5f;
  207. const float aperture = 0.55785173935;
  208. vec3 o1 = normalize(tangent(normal));
  209. vec3 o2 = normalize(cross(o1, normal));
  210. vec3 c1 = 0.5f * (o1 + o2);
  211. vec3 c2 = 0.5f * (o1 - o2);
  212. float MAX_DISTANCE = 1.73205080757 * 2.0 * vrange;
  213. const ivec3 voxelgiResolution = ivec3(256, 256, 256);
  214. const float voxelgiStep = 1.0;
  215. const float VOXEL_SIZE = (2.0 / voxelgiResolution.x) * voxelgiStep;
  216. float offset = 1.5 * VOXEL_SIZE * 2.5 * voffset;
  217. float col = traceConeAO(voxels, origin, normal, aperture, MAX_DISTANCE, offset);
  218. col += traceConeAO(voxels, origin, mix(normal, o1, angleMix), aperture, MAX_DISTANCE, offset);
  219. col += traceConeAO(voxels, origin, mix(normal, o2, angleMix), aperture, MAX_DISTANCE, offset);
  220. col += traceConeAO(voxels, origin, mix(normal, -c1, angleMix), aperture, MAX_DISTANCE, offset);
  221. col += traceConeAO(voxels, origin, mix(normal, -c2, angleMix), aperture, MAX_DISTANCE, offset);
  222. col += traceConeAO(voxels, origin, mix(normal, -o1, angleMix), aperture, MAX_DISTANCE, offset);
  223. col += traceConeAO(voxels, origin, mix(normal, -o2, angleMix), aperture, MAX_DISTANCE, offset);
  224. col += traceConeAO(voxels, origin, mix(normal, c1, angleMix), aperture, MAX_DISTANCE, offset);
  225. col += traceConeAO(voxels, origin, mix(normal, c2, angleMix), aperture, MAX_DISTANCE, offset);
  226. return col / 9.0;
  227. }
  228. ";
  229. public static var str_cotangentFrame = "
  230. mat3 cotangentFrame(const vec3 n, const vec3 p, const vec2 duv1, const vec2 duv2) {
  231. vec3 dp1 = dFdx(p);
  232. vec3 dp2 = dFdy(p);
  233. vec3 dp2perp = cross(dp2, n);
  234. vec3 dp1perp = cross(n, dp1);
  235. vec3 t = dp2perp * duv1.x + dp1perp * duv2.x;
  236. vec3 b = dp2perp * duv1.y + dp1perp * duv2.y;
  237. float invmax = inversesqrt(max(dot(t, t), dot(b, b)));
  238. return mat3(t * invmax, b * invmax, n);
  239. }
  240. mat3 cotangentFrame(const vec3 n, const vec3 p, const vec2 texCoord) {
  241. return cotangentFrame(n, p, dFdx(texCoord), dFdy(texCoord));
  242. }
  243. ";
  244. public static var str_octahedronWrap = "
  245. vec2 octahedronWrap(const vec2 v) {
  246. return (1.0 - abs(v.yx)) * (vec2(v.x >= 0.0 ? 1.0 : -1.0, v.y >= 0.0 ? 1.0 : -1.0));
  247. }
  248. ";
  249. public static var str_packFloat2 = "
  250. float packFloat2(const float f1, const float f2) {
  251. return floor(f1 * 255.0) + min(f2, 1.0 - 1.0 / 100.0);
  252. }
  253. ";
  254. public static var str_packFloatInt16 = "
  255. float packFloatInt16(const float f, const uint i) {
  256. const float prec = float(1 << 16);
  257. const float maxi = float(1 << 4);
  258. const float precMinusOne = prec - 1.0;
  259. const float t1 = ((prec / maxi) - 1.0) / precMinusOne;
  260. const float t2 = (prec / maxi) / precMinusOne;
  261. return t1 * f + t2 * float(i);
  262. }
  263. ";
  264. #if arm_skin
  265. public static var str_getSkinningDualQuat = "
  266. void getSkinningDualQuat(const ivec4 bone, vec4 weight, out vec4 A, inout vec4 B) {
  267. ivec4 bonei = bone * 2;
  268. mat4 matA = mat4(
  269. skinBones[bonei.x],
  270. skinBones[bonei.y],
  271. skinBones[bonei.z],
  272. skinBones[bonei.w]);
  273. mat4 matB = mat4(
  274. skinBones[bonei.x + 1],
  275. skinBones[bonei.y + 1],
  276. skinBones[bonei.z + 1],
  277. skinBones[bonei.w + 1]);
  278. weight.xyz *= sign(mul(matA, matA[3])).xyz;
  279. A = mul(weight, matA);
  280. B = mul(weight, matB);
  281. float invNormA = 1.0 / length(A);
  282. A *= invNormA;
  283. B *= invNormA;
  284. }
  285. ";
  286. #end
  287. }