ShaderFunctions.hx 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. package arm.shader;
  2. class ShaderFunctions {
  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, textureArg(snoise256)) {
  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. float tex_brick_noise(int n) { /* fast integer noise */
  152. int nn;
  153. n = (n >> 13) ^ n;
  154. nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff;
  155. return 0.5f * float(nn) / 1073741824.0;
  156. }
  157. vec3 tex_brick(vec3 p, const vec3 c1, const vec3 c2, const vec3 c3) {
  158. vec3 brickSize = vec3(0.9, 0.49, 0.49);
  159. vec3 mortarSize = vec3(0.05, 0.1, 0.1);
  160. p /= brickSize / 2;
  161. if (fract(p.y * 0.5) > 0.5) p.x += 0.5;
  162. float col = floor(p.x / (brickSize.x + (mortarSize.x * 2.0)));
  163. float row = p.y;
  164. p = fract(p);
  165. vec3 b = step(p, 1.0 - mortarSize);
  166. float tint = min(max(tex_brick_noise((int(col) << 16) + (int(row) & 0xFFFF)), 0.0), 1.0);
  167. return mix(c3, mix(c1, c2, tint), b.x * b.y * b.z);
  168. }
  169. float tex_brick_f(vec3 p) {
  170. p /= vec3(0.9, 0.49, 0.49) / 2;
  171. if (fract(p.y * 0.5) > 0.5) p.x += 0.5;
  172. p = fract(p);
  173. vec3 b = step(p, vec3(0.95, 0.9, 0.9));
  174. return mix(1.0, 0.0, b.x * b.y * b.z);
  175. }
  176. ";
  177. public static var str_tex_wave = "
  178. float tex_wave_f(const vec3 p) {
  179. return 1.0 - sin((p.x + p.y) * 10.0);
  180. }
  181. ";
  182. public static var str_brightcontrast = "
  183. vec3 brightcontrast(const vec3 col, const float bright, const float contr) {
  184. float a = 1.0 + contr;
  185. float b = bright - contr * 0.5;
  186. return max(a * col + b, 0.0);
  187. }
  188. ";
  189. //
  190. #if rp_voxels
  191. public static var str_traceAO = '
  192. float traceConeAO(sampler3D voxels, const vec3 origin, vec3 dir, const float aperture, const float maxDist, const float offset) {
  193. const ivec3 voxelgiResolution = ivec3(256, 256, 256);
  194. const float voxelgiStep = 1.0;
  195. const float VOXEL_SIZE = (2.0 / voxelgiResolution.x) * voxelgiStep;
  196. dir = normalize(dir);
  197. float sampleCol = 0.0;
  198. float dist = offset;
  199. float diam = dist * aperture;
  200. vec3 samplePos;
  201. while (sampleCol < 1.0 && dist < maxDist) {
  202. samplePos = dir * dist + origin;
  203. float mip = max(log2(diam * voxelgiResolution.x), 0);
  204. float mipSample = textureLod(voxels, samplePos * 0.5 + vec3(0.5, 0.5, 0.5), mip).r;
  205. sampleCol += (1 - sampleCol) * mipSample;
  206. dist += max(diam / 2, VOXEL_SIZE);
  207. diam = dist * aperture;
  208. }
  209. return sampleCol;
  210. }
  211. vec3 tangent(const vec3 n) {
  212. vec3 t1 = cross(n, vec3(0, 0, 1));
  213. vec3 t2 = cross(n, vec3(0, 1, 0));
  214. if (length(t1) > length(t2)) return normalize(t1);
  215. else return normalize(t2);
  216. }
  217. float traceAO(const vec3 origin, const vec3 normal, const float vrange, const float voffset) {
  218. const float angleMix = 0.5f;
  219. const float aperture = 0.55785173935;
  220. vec3 o1 = normalize(tangent(normal));
  221. vec3 o2 = normalize(cross(o1, normal));
  222. vec3 c1 = 0.5f * (o1 + o2);
  223. vec3 c2 = 0.5f * (o1 - o2);
  224. float MAX_DISTANCE = 1.73205080757 * 2.0 * vrange;
  225. const ivec3 voxelgiResolution = ivec3(256, 256, 256);
  226. const float voxelgiStep = 1.0;
  227. const float VOXEL_SIZE = (2.0 / voxelgiResolution.x) * voxelgiStep;
  228. float offset = 1.5 * VOXEL_SIZE * 2.5 * voffset;
  229. float col = traceConeAO(voxels, origin, normal, aperture, MAX_DISTANCE, offset);
  230. col += traceConeAO(voxels, origin, mix(normal, o1, angleMix), aperture, MAX_DISTANCE, offset);
  231. col += traceConeAO(voxels, origin, mix(normal, o2, angleMix), aperture, MAX_DISTANCE, offset);
  232. col += traceConeAO(voxels, origin, mix(normal, -c1, angleMix), aperture, MAX_DISTANCE, offset);
  233. col += traceConeAO(voxels, origin, mix(normal, -c2, angleMix), aperture, MAX_DISTANCE, offset);
  234. col += traceConeAO(voxels, origin, mix(normal, -o1, angleMix), aperture, MAX_DISTANCE, offset);
  235. col += traceConeAO(voxels, origin, mix(normal, -o2, angleMix), aperture, MAX_DISTANCE, offset);
  236. col += traceConeAO(voxels, origin, mix(normal, c1, angleMix), aperture, MAX_DISTANCE, offset);
  237. col += traceConeAO(voxels, origin, mix(normal, c2, angleMix), aperture, MAX_DISTANCE, offset);
  238. return col / 9.0;
  239. }
  240. ';
  241. #end
  242. public static var str_cotangentFrame = "
  243. mat3 cotangentFrame(const vec3 n, const vec3 p, const vec2 duv1, const vec2 duv2) {
  244. vec3 dp1 = dFdx(p);
  245. vec3 dp2 = dFdy(p);
  246. vec3 dp2perp = cross(dp2, n);
  247. vec3 dp1perp = cross(n, dp1);
  248. vec3 t = dp2perp * duv1.x + dp1perp * duv2.x;
  249. vec3 b = dp2perp * duv1.y + dp1perp * duv2.y;
  250. float invmax = inversesqrt(max(dot(t, t), dot(b, b)));
  251. return mat3(t * invmax, b * invmax, n);
  252. }
  253. mat3 cotangentFrame(const vec3 n, const vec3 p, const vec2 texCoord) {
  254. return cotangentFrame(n, p, dFdx(texCoord), dFdy(texCoord));
  255. }
  256. ";
  257. public static var str_octahedronWrap = "
  258. vec2 octahedronWrap(const vec2 v) {
  259. return (1.0 - abs(v.yx)) * (vec2(v.x >= 0.0 ? 1.0 : -1.0, v.y >= 0.0 ? 1.0 : -1.0));
  260. }
  261. ";
  262. public static var str_packFloatInt16 = "
  263. float packFloatInt16(const float f, const uint i) {
  264. const float prec = float(1 << 16);
  265. const float maxi = float(1 << 4);
  266. const float precMinusOne = prec - 1.0;
  267. const float t1 = ((prec / maxi) - 1.0) / precMinusOne;
  268. const float t2 = (prec / maxi) / precMinusOne;
  269. return t1 * f + t2 * float(i);
  270. }
  271. ";
  272. #if arm_skin
  273. public static var str_getSkinningDualQuat = "
  274. void getSkinningDualQuat(const ivec4 bone, vec4 weight, out vec4 A, inout vec4 B) {
  275. ivec4 bonei = bone * 2;
  276. mat4 matA = mat4(
  277. skinBones[bonei.x],
  278. skinBones[bonei.y],
  279. skinBones[bonei.z],
  280. skinBones[bonei.w]);
  281. mat4 matB = mat4(
  282. skinBones[bonei.x + 1],
  283. skinBones[bonei.y + 1],
  284. skinBones[bonei.z + 1],
  285. skinBones[bonei.w + 1]);
  286. weight.xyz *= sign(mul(matA, matA[3])).xyz;
  287. A = mul(weight, matA);
  288. B = mul(weight, matB);
  289. float invNormA = 1.0 / length(A);
  290. A *= invNormA;
  291. B *= invNormA;
  292. }
  293. ";
  294. #end
  295. public static var str_createBasis = "
  296. void createBasis(vec3 normal, out vec3 tangent, out vec3 binormal) {
  297. tangent = normalize(cameraRight - normal * dot(cameraRight, normal));
  298. binormal = cross(tangent, normal);
  299. }
  300. ";
  301. public static var str_shIrradiance =
  302. #if kha_metal
  303. "vec3 shIrradiance(const vec3 nor, constant vec4 shirr[7]) {
  304. const float c1 = 0.429043;
  305. const float c2 = 0.511664;
  306. const float c3 = 0.743125;
  307. const float c4 = 0.886227;
  308. const float c5 = 0.247708;
  309. vec3 cl00 = vec3(shirr[0].x, shirr[0].y, shirr[0].z);
  310. vec3 cl1m1 = vec3(shirr[0].w, shirr[1].x, shirr[1].y);
  311. vec3 cl10 = vec3(shirr[1].z, shirr[1].w, shirr[2].x);
  312. vec3 cl11 = vec3(shirr[2].y, shirr[2].z, shirr[2].w);
  313. vec3 cl2m2 = vec3(shirr[3].x, shirr[3].y, shirr[3].z);
  314. vec3 cl2m1 = vec3(shirr[3].w, shirr[4].x, shirr[4].y);
  315. vec3 cl20 = vec3(shirr[4].z, shirr[4].w, shirr[5].x);
  316. vec3 cl21 = vec3(shirr[5].y, shirr[5].z, shirr[5].w);
  317. vec3 cl22 = vec3(shirr[6].x, shirr[6].y, shirr[6].z);
  318. return (
  319. c1 * cl22 * (nor.y * nor.y - (-nor.z) * (-nor.z)) +
  320. c3 * cl20 * nor.x * nor.x +
  321. c4 * cl00 -
  322. c5 * cl20 +
  323. 2.0 * c1 * cl2m2 * nor.y * (-nor.z) +
  324. 2.0 * c1 * cl21 * nor.y * nor.x +
  325. 2.0 * c1 * cl2m1 * (-nor.z) * nor.x +
  326. 2.0 * c2 * cl11 * nor.y +
  327. 2.0 * c2 * cl1m1 * (-nor.z) +
  328. 2.0 * c2 * cl10 * nor.x
  329. );
  330. }
  331. ";
  332. #else
  333. "vec3 shIrradiance(const vec3 nor, const vec4 shirr[7]) {
  334. const float c1 = 0.429043;
  335. const float c2 = 0.511664;
  336. const float c3 = 0.743125;
  337. const float c4 = 0.886227;
  338. const float c5 = 0.247708;
  339. vec3 cl00 = vec3(shirr[0].x, shirr[0].y, shirr[0].z);
  340. vec3 cl1m1 = vec3(shirr[0].w, shirr[1].x, shirr[1].y);
  341. vec3 cl10 = vec3(shirr[1].z, shirr[1].w, shirr[2].x);
  342. vec3 cl11 = vec3(shirr[2].y, shirr[2].z, shirr[2].w);
  343. vec3 cl2m2 = vec3(shirr[3].x, shirr[3].y, shirr[3].z);
  344. vec3 cl2m1 = vec3(shirr[3].w, shirr[4].x, shirr[4].y);
  345. vec3 cl20 = vec3(shirr[4].z, shirr[4].w, shirr[5].x);
  346. vec3 cl21 = vec3(shirr[5].y, shirr[5].z, shirr[5].w);
  347. vec3 cl22 = vec3(shirr[6].x, shirr[6].y, shirr[6].z);
  348. return (
  349. c1 * cl22 * (nor.y * nor.y - (-nor.z) * (-nor.z)) +
  350. c3 * cl20 * nor.x * nor.x +
  351. c4 * cl00 -
  352. c5 * cl20 +
  353. 2.0 * c1 * cl2m2 * nor.y * (-nor.z) +
  354. 2.0 * c1 * cl21 * nor.y * nor.x +
  355. 2.0 * c1 * cl2m1 * (-nor.z) * nor.x +
  356. 2.0 * c2 * cl11 * nor.y +
  357. 2.0 * c2 * cl1m1 * (-nor.z) +
  358. 2.0 * c2 * cl10 * nor.x
  359. );
  360. }
  361. ";
  362. #end
  363. public static var str_envMapEquirect = "
  364. vec2 envMapEquirect(const vec3 normal, const float angle) {
  365. const float PI = 3.1415926535;
  366. const float PI2 = PI * 2.0;
  367. float phi = acos(normal.z);
  368. float theta = atan2(-normal.y, normal.x) + PI + angle;
  369. return vec2(theta / PI2, phi / PI);
  370. }
  371. ";
  372. // Linearly Transformed Cosines
  373. // https://eheitzresearch.wordpress.com/415-2/
  374. public static var str_ltcEvaluate = "
  375. float integrateEdge(vec3 v1, vec3 v2) {
  376. float cosTheta = dot(v1, v2);
  377. float theta = acos(cosTheta);
  378. float res = cross(v1, v2).z * ((theta > 0.001) ? theta / sin(theta) : 1.0);
  379. return res;
  380. }
  381. float ltcEvaluate(vec3 N, vec3 V, float dotNV, vec3 P, mat3 Minv, vec3 points0, vec3 points1, vec3 points2, vec3 points3) {
  382. vec3 T1 = normalize(V - N * dotNV);
  383. vec3 T2 = cross(N, T1);
  384. Minv = mul(transpose(mat3(T1, T2, N)), Minv);
  385. vec3 L0 = mul((points0 - P), Minv);
  386. vec3 L1 = mul((points1 - P), Minv);
  387. vec3 L2 = mul((points2 - P), Minv);
  388. vec3 L3 = mul((points3 - P), Minv);
  389. vec3 L4 = vec3(0.0, 0.0, 0.0);
  390. int n = 0;
  391. int config = 0;
  392. if (L0.z > 0.0) config += 1;
  393. if (L1.z > 0.0) config += 2;
  394. if (L2.z > 0.0) config += 4;
  395. if (L3.z > 0.0) config += 8;
  396. if (config == 0) {}
  397. else if (config == 1) {
  398. n = 3;
  399. L1 = -L1.z * L0 + L0.z * L1;
  400. L2 = -L3.z * L0 + L0.z * L3;
  401. }
  402. else if (config == 2) {
  403. n = 3;
  404. L0 = -L0.z * L1 + L1.z * L0;
  405. L2 = -L2.z * L1 + L1.z * L2;
  406. }
  407. else if (config == 3) {
  408. n = 4;
  409. L2 = -L2.z * L1 + L1.z * L2;
  410. L3 = -L3.z * L0 + L0.z * L3;
  411. }
  412. else if (config == 4) {
  413. n = 3;
  414. L0 = -L3.z * L2 + L2.z * L3;
  415. L1 = -L1.z * L2 + L2.z * L1;
  416. }
  417. else if (config == 5) { n = 0; }
  418. else if (config == 6) {
  419. n = 4;
  420. L0 = -L0.z * L1 + L1.z * L0;
  421. L3 = -L3.z * L2 + L2.z * L3;
  422. }
  423. else if (config == 7) {
  424. n = 5;
  425. L4 = -L3.z * L0 + L0.z * L3;
  426. L3 = -L3.z * L2 + L2.z * L3;
  427. }
  428. else if (config == 8) {
  429. n = 3;
  430. L0 = -L0.z * L3 + L3.z * L0;
  431. L1 = -L2.z * L3 + L3.z * L2;
  432. L2 = L3;
  433. }
  434. else if (config == 9) {
  435. n = 4;
  436. L1 = -L1.z * L0 + L0.z * L1;
  437. L2 = -L2.z * L3 + L3.z * L2;
  438. }
  439. else if (config == 10) { n = 0; }
  440. else if (config == 11) {
  441. n = 5;
  442. L4 = L3;
  443. L3 = -L2.z * L3 + L3.z * L2;
  444. L2 = -L2.z * L1 + L1.z * L2;
  445. }
  446. else if (config == 12) {
  447. n = 4;
  448. L1 = -L1.z * L2 + L2.z * L1;
  449. L0 = -L0.z * L3 + L3.z * L0;
  450. }
  451. else if (config == 13) {
  452. n = 5;
  453. L4 = L3;
  454. L3 = L2;
  455. L2 = -L1.z * L2 + L2.z * L1;
  456. L1 = -L1.z * L0 + L0.z * L1;
  457. }
  458. else if (config == 14) {
  459. n = 5;
  460. L4 = -L0.z * L3 + L3.z * L0;
  461. L0 = -L0.z * L1 + L1.z * L0;
  462. }
  463. else if (config == 15) { n = 4; }
  464. if (n == 0) return 0.0;
  465. if (n == 3) L3 = L0;
  466. if (n == 4) L4 = L0;
  467. L0 = normalize(L0);
  468. L1 = normalize(L1);
  469. L2 = normalize(L2);
  470. L3 = normalize(L3);
  471. L4 = normalize(L4);
  472. float sum = 0.0;
  473. sum += integrateEdge(L0, L1);
  474. sum += integrateEdge(L1, L2);
  475. sum += integrateEdge(L2, L3);
  476. if (n >= 4) sum += integrateEdge(L3, L4);
  477. if (n == 5) sum += integrateEdge(L4, L0);
  478. return max(0.0, -sum);
  479. }
  480. ";
  481. public static var str_get_pos_from_depth = "
  482. vec3 get_pos_from_depth(vec2 uv, mat4 invVP, textureArg(gbufferD)) {
  483. #if defined(HLSL) || defined(METAL) || defined(SPIRV)
  484. float depth = textureLod(gbufferD, vec2(uv.x, 1.0 - uv.y), 0.0).r;
  485. #else
  486. float depth = textureLod(gbufferD, uv, 0.0).r;
  487. #endif
  488. vec4 wpos = vec4(uv * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0);
  489. wpos = mul(wpos, invVP);
  490. return wpos.xyz / wpos.w;
  491. }
  492. ";
  493. public static var str_get_nor_from_depth = "
  494. vec3 get_nor_from_depth(vec3 p0, vec2 uv, mat4 invVP, vec2 texStep, textureArg(gbufferD)) {
  495. vec3 p1 = get_pos_from_depth(uv + vec2(texStep.x * 4.0, 0.0), invVP, texturePass(gbufferD));
  496. vec3 p2 = get_pos_from_depth(uv + vec2(0.0, texStep.y * 4.0), invVP, texturePass(gbufferD));
  497. return normalize(cross(p2 - p0, p1 - p0));
  498. }
  499. ";
  500. }