make_mesh.ts 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. let make_mesh_layer_pass_count: i32 = 1;
  2. function make_mesh_run(data: material_t, layer_pass: i32 = 0): node_shader_context_t {
  3. let context_id: string = layer_pass == 0 ? "mesh" : "mesh" + layer_pass;
  4. let props: shader_context_t = {
  5. name: context_id,
  6. depth_write: layer_pass == 0 ? true : false,
  7. compare_mode: layer_pass == 0 ? "less" : "equal",
  8. cull_mode: (context_raw.cull_backfaces || layer_pass > 0) ? "clockwise" : "none",
  9. vertex_elements: [
  10. {
  11. name: "pos",
  12. data: "short4norm"
  13. },
  14. {
  15. name: "nor",
  16. data: "short2norm"
  17. },
  18. {
  19. name: "tex",
  20. data: "short2norm"
  21. }
  22. ],
  23. color_attachments: ["RGBA64", "RGBA64", "RGBA64"],
  24. depth_attachment: "DEPTH32"
  25. };
  26. let con_mesh: node_shader_context_t = node_shader_context_create(data, props);
  27. let vert: node_shader_t = node_shader_context_make_vert(con_mesh);
  28. let frag: node_shader_t = node_shader_context_make_frag(con_mesh);
  29. frag.ins = vert.outs;
  30. node_shader_add_out(vert, "vec2 texCoord");
  31. frag.wvpposition = true;
  32. node_shader_add_out(vert, "vec4 prevwvpposition");
  33. node_shader_add_uniform(vert, "mat4 VP", "_view_proj_matrix");
  34. node_shader_add_uniform(vert, "mat4 prevWVP", "_prev_world_view_proj_matrix");
  35. vert.wposition = true;
  36. let texture_count: i32 = 0;
  37. let displace_strength: f32 = make_material_get_displace_strength();
  38. if (make_material_height_used && displace_strength > 0.0) {
  39. vert.n = true;
  40. node_shader_write(vert, "float height = 0.0;");
  41. let num_layers: i32 = 0;
  42. for (let i: i32 = 0; i < project_layers.length; ++i) {
  43. let l: slot_layer_t = project_layers[i];
  44. if (!slot_layer_is_visible(l) || !l.paint_height || !slot_layer_is_layer(l)) {
  45. continue;
  46. }
  47. if (num_layers > 16) {
  48. break;
  49. }
  50. num_layers++;
  51. texture_count++;
  52. node_shader_add_uniform(vert, "sampler2D texpaint_pack_vert" + l.id, "_texpaint_pack_vert" + l.id);
  53. node_shader_write(vert, "height += textureLod(texpaint_pack_vert" + l.id + ", tex, 0.0).a;");
  54. let masks: slot_layer_t[] = slot_layer_get_masks(l);
  55. if (masks != null) {
  56. for (let i: i32 = 0; i < masks.length; ++i) {
  57. let m: slot_layer_t = masks[i];
  58. if (!slot_layer_is_visible(m)) {
  59. continue;
  60. }
  61. texture_count++;
  62. node_shader_add_uniform(vert, "sampler2D texpaint_vert" + m.id, "_texpaint_vert" + m.id);
  63. node_shader_write(vert, "height *= textureLod(texpaint_vert" + m.id + ", tex, 0.0).r;");
  64. }
  65. }
  66. }
  67. node_shader_write(vert, "wposition += wnormal * vec3(height, height, height) * vec3(" + displace_strength + ", " + displace_strength + ", " + displace_strength + ");");
  68. }
  69. node_shader_write(vert, "gl_Position = mul(vec4(wposition.xyz, 1.0), VP);");
  70. node_shader_write(vert, "texCoord = tex;");
  71. if (make_material_height_used && displace_strength > 0) {
  72. node_shader_add_uniform(vert, "mat4 invW", "_inv_world_matrix");
  73. node_shader_write(vert, "prevwvpposition = mul(mul(vec4(wposition, 1.0), invW), prevWVP);");
  74. }
  75. else {
  76. node_shader_write(vert, "prevwvpposition = mul(vec4(pos.xyz, 1.0), prevWVP);");
  77. }
  78. node_shader_add_out(frag, "vec4 fragColor[3]");
  79. frag.n = true;
  80. node_shader_add_function(frag, str_pack_float_int16);
  81. if (context_raw.tool == workspace_tool_t.COLORID) {
  82. texture_count++;
  83. node_shader_add_uniform(frag, "sampler2D texcolorid", "_texcolorid");
  84. node_shader_write(frag, "fragColor[0] = vec4(n.xy, 1.0, packFloatInt16(0.0, uint(0)));");
  85. node_shader_write(frag, "vec3 idcol = pow(textureLod(texcolorid, texCoord, 0.0).rgb, vec3(2.2, 2.2, 2.2));");
  86. node_shader_write(frag, "fragColor[1] = vec4(idcol.rgb, 1.0);"); // occ
  87. }
  88. else {
  89. node_shader_add_function(frag, str_octahedron_wrap);
  90. node_shader_add_function(frag, str_cotangent_frame);
  91. if (layer_pass > 0) {
  92. node_shader_add_uniform(frag, "sampler2D gbuffer0");
  93. node_shader_add_uniform(frag, "sampler2D gbuffer1");
  94. node_shader_add_uniform(frag, "sampler2D gbuffer2");
  95. node_shader_write(frag, "vec2 fragcoord = (wvpposition.xy / wvpposition.w) * 0.5 + 0.5;");
  96. ///if (krom_direct3d11 || krom_direct3d12 || krom_metal || krom_vulkan)
  97. node_shader_write(frag, "fragcoord.y = 1.0 - fragcoord.y;");
  98. ///end
  99. node_shader_write(frag, "vec4 gbuffer0_sample = textureLod(gbuffer0, fragcoord, 0.0);");
  100. node_shader_write(frag, "vec4 gbuffer1_sample = textureLod(gbuffer1, fragcoord, 0.0);");
  101. node_shader_write(frag, "vec4 gbuffer2_sample = textureLod(gbuffer2, fragcoord, 0.0);");
  102. node_shader_write(frag, "vec3 basecol = gbuffer0_sample.rgb;");
  103. node_shader_write(frag, "float roughness = gbuffer2_sample.g;");
  104. node_shader_write(frag, "float metallic = gbuffer2_sample.b;");
  105. node_shader_write(frag, "float occlusion = gbuffer2_sample.r;");
  106. node_shader_write(frag, "float opacity = 1.0;//gbuffer0_sample.a;");
  107. node_shader_write(frag, "float matid = gbuffer1_sample.a;");
  108. node_shader_write(frag, "vec3 ntex = gbuffer1_sample.rgb;");
  109. node_shader_write(frag, "float height = gbuffer2_sample.a;");
  110. }
  111. else {
  112. node_shader_write(frag, "vec3 basecol = vec3(0.0, 0.0, 0.0);");
  113. node_shader_write(frag, "float roughness = 0.0;");
  114. node_shader_write(frag, "float metallic = 0.0;");
  115. node_shader_write(frag, "float occlusion = 1.0;");
  116. node_shader_write(frag, "float opacity = 1.0;");
  117. node_shader_write(frag, "float matid = 0.0;");
  118. node_shader_write(frag, "vec3 ntex = vec3(0.5, 0.5, 1.0);");
  119. node_shader_write(frag, "float height = 0.0;");
  120. }
  121. node_shader_write(frag, "vec4 texpaint_sample = vec4(0.0, 0.0, 0.0, 1.0);");
  122. node_shader_write(frag, "vec4 texpaint_nor_sample;");
  123. node_shader_write(frag, "vec4 texpaint_pack_sample;");
  124. node_shader_write(frag, "float texpaint_opac;");
  125. if (make_material_height_used) {
  126. node_shader_write(frag, "float height0 = 0.0;");
  127. node_shader_write(frag, "float height1 = 0.0;");
  128. node_shader_write(frag, "float height2 = 0.0;");
  129. node_shader_write(frag, "float height3 = 0.0;");
  130. }
  131. if (context_raw.draw_wireframe) {
  132. texture_count++;
  133. node_shader_add_uniform(frag, "sampler2D texuvmap", "_texuvmap");
  134. }
  135. if (context_raw.viewport_mode == viewport_mode_t.MASK && slot_layer_get_masks(context_raw.layer) != null) {
  136. for (let i: i32 = 0; i < slot_layer_get_masks(context_raw.layer).length; ++i) {
  137. let m: slot_layer_t = slot_layer_get_masks(context_raw.layer)[i];
  138. if (!slot_layer_is_visible(m)) {
  139. continue;
  140. }
  141. texture_count++;
  142. node_shader_add_uniform(frag, "sampler2D texpaint_view_mask" + m.id, "_texpaint" + array_index_of(project_layers, m));
  143. }
  144. }
  145. if (context_raw.viewport_mode == viewport_mode_t.LIT && context_raw.render_mode == render_mode_t.FORWARD) {
  146. texture_count += 4;
  147. node_shader_add_uniform(frag, "sampler2D senvmapBrdf", "$brdf.k");
  148. node_shader_add_uniform(frag, "sampler2D senvmapRadiance", "_envmap_radiance");
  149. node_shader_add_uniform(frag, "sampler2D sltcMat", "_ltcMat");
  150. node_shader_add_uniform(frag, "sampler2D sltcMag", "_ltcMag");
  151. }
  152. // Get layers for this pass
  153. make_mesh_layer_pass_count = 1;
  154. let layers: slot_layer_t[] = [];
  155. let start_count: i32 = texture_count;
  156. let is_material_tool: bool = context_raw.tool == workspace_tool_t.MATERIAL;
  157. for (let i: i32 = 0; i < project_layers.length; ++i) {
  158. let l: slot_layer_t = project_layers[i];
  159. if (is_material_tool && l != context_raw.layer) {
  160. continue;
  161. }
  162. if (!slot_layer_is_layer(l) || !slot_layer_is_visible(l)) {
  163. continue;
  164. }
  165. let count: i32 = 3;
  166. let masks: slot_layer_t[] = slot_layer_get_masks(l);
  167. if (masks != null) {
  168. count += masks.length;
  169. }
  170. texture_count += count;
  171. if (texture_count >= make_mesh_get_max_textures()) {
  172. texture_count = start_count + count + 3; // gbuffer0_copy, gbuffer1_copy, gbuffer2_copy
  173. make_mesh_layer_pass_count++;
  174. }
  175. if (layer_pass == make_mesh_layer_pass_count - 1) {
  176. array_push(layers, l);
  177. }
  178. }
  179. let last_pass: bool = layer_pass == make_mesh_layer_pass_count - 1;
  180. for (let i: i32 = 0; i < layers.length; ++i) {
  181. let l: slot_layer_t = layers[i];
  182. if (slot_layer_get_object_mask(l) > 0) {
  183. node_shader_add_uniform(frag, "int uid", "_uid");
  184. if (slot_layer_get_object_mask(l) > project_paint_objects.length) { // Atlas
  185. let visibles: mesh_object_t[] = project_get_atlas_objects(slot_layer_get_object_mask(l));
  186. node_shader_write(frag, "if (");
  187. for (let i: i32 = 0; i < visibles.length; ++i) {
  188. if (i > 0) {
  189. node_shader_write(frag, " || ");
  190. }
  191. node_shader_write(frag, visibles[i].base.uid + " == uid");
  192. }
  193. node_shader_write(frag, ") {");
  194. }
  195. else { // Object mask
  196. let uid: i32 = project_paint_objects[slot_layer_get_object_mask(l) - 1].base.uid;
  197. node_shader_write(frag, "if (" + uid + " == uid) {");
  198. }
  199. }
  200. node_shader_add_shared_sampler(frag, "sampler2D texpaint" + l.id);
  201. node_shader_write(frag, "texpaint_sample = textureLodShared(texpaint" + l.id + ", texCoord, 0.0);");
  202. node_shader_write(frag, "texpaint_opac = texpaint_sample.a;");
  203. // ///if (krom_direct3d12 || krom_vulkan)
  204. // if (raw.viewportMode == ViewLit) {
  205. // write(frag, "if (texpaint_opac < 0.1) discard;");
  206. // }
  207. // ///end
  208. let masks: slot_layer_t[] = slot_layer_get_masks(l);
  209. if (masks != null) {
  210. let has_visible: bool = false;
  211. for (let i: i32 = 0; i < masks.length; ++i) {
  212. let m: slot_layer_t = masks[i];
  213. if (slot_layer_is_visible(m)) {
  214. has_visible = true;
  215. break;
  216. }
  217. }
  218. if (has_visible) {
  219. let texpaint_mask: string = "texpaint_mask" + l.id;
  220. node_shader_write(frag, "float " + texpaint_mask + " = 0.0;");
  221. for (let i: i32 = 0; i < masks.length; ++i) {
  222. let m: slot_layer_t = masks[i];
  223. if (!slot_layer_is_visible(m)) {
  224. continue;
  225. }
  226. node_shader_add_shared_sampler(frag, "sampler2D texpaint" + m.id);
  227. node_shader_write(frag, "{"); // Group mask is sampled across multiple layers
  228. node_shader_write(frag, "float texpaint_mask_sample" + m.id + " = textureLodShared(texpaint" + m.id + ", texCoord, 0.0).r;");
  229. node_shader_write(frag, texpaint_mask + " = " + make_material_blend_mode_mask(frag, m.blending, texpaint_mask, "texpaint_mask_sample" + m.id, "float(" + slot_layer_get_opacity(m) + ")") + ";");
  230. node_shader_write(frag, "}");
  231. }
  232. node_shader_write(frag, "texpaint_opac *= clamp(" + texpaint_mask + ", 0.0, 1.0);");
  233. }
  234. }
  235. if (slot_layer_get_opacity(l) < 1) {
  236. node_shader_write(frag, "texpaint_opac *= " + slot_layer_get_opacity(l) + ";");
  237. }
  238. if (l.paint_base) {
  239. if (l == project_layers[0]) {
  240. node_shader_write(frag, "basecol = texpaint_sample.rgb * texpaint_opac;");
  241. }
  242. else {
  243. node_shader_write(frag, "basecol = " + make_material_blend_mode(frag, l.blending, "basecol", "texpaint_sample.rgb", "texpaint_opac") + ";");
  244. }
  245. }
  246. if (l.paint_nor || make_material_emis_used) {
  247. node_shader_add_shared_sampler(frag, "sampler2D texpaint_nor" + l.id);
  248. node_shader_write(frag, "texpaint_nor_sample = textureLodShared(texpaint_nor" + l.id + ", texCoord, 0.0);");
  249. if (make_material_emis_used) {
  250. node_shader_write(frag, "if (texpaint_opac > 0.0) matid = texpaint_nor_sample.a;");
  251. }
  252. if (l.paint_nor) {
  253. if (l.paint_nor_blend) {
  254. // Whiteout blend
  255. node_shader_write(frag, "{");
  256. node_shader_write(frag, "vec3 n1 = ntex * vec3(2.0, 2.0, 2.0) - vec3(1.0, 1.0, 1.0);");
  257. node_shader_write(frag, "vec3 n2 = mix(vec3(0.5, 0.5, 1.0), texpaint_nor_sample.rgb, texpaint_opac) * vec3(2.0, 2.0, 2.0) - vec3(1.0, 1.0, 1.0);");
  258. node_shader_write(frag, "ntex = normalize(vec3(n1.xy + n2.xy, n1.z * n2.z)) * vec3(0.5, 0.5, 0.5) + vec3(0.5, 0.5, 0.5);");
  259. node_shader_write(frag, "}");
  260. }
  261. else {
  262. node_shader_write(frag, "ntex = mix(ntex, texpaint_nor_sample.rgb, texpaint_opac);");
  263. }
  264. }
  265. }
  266. if (l.paint_occ || l.paint_rough || l.paint_met || (l.paint_height && make_material_height_used)) {
  267. node_shader_add_shared_sampler(frag, "sampler2D texpaint_pack" + l.id);
  268. node_shader_write(frag, "texpaint_pack_sample = textureLodShared(texpaint_pack" + l.id + ", texCoord, 0.0);");
  269. if (l.paint_occ) {
  270. node_shader_write(frag, "occlusion = mix(occlusion, texpaint_pack_sample.r, texpaint_opac);");
  271. }
  272. if (l.paint_rough) {
  273. node_shader_write(frag, "roughness = mix(roughness, texpaint_pack_sample.g, texpaint_opac);");
  274. }
  275. if (l.paint_met) {
  276. node_shader_write(frag, "metallic = mix(metallic, texpaint_pack_sample.b, texpaint_opac);");
  277. }
  278. if (l.paint_height && make_material_height_used) {
  279. let assign: string = l.paint_height_blend ? "+=" : "=";
  280. node_shader_write(frag, "height " + assign + " texpaint_pack_sample.a * texpaint_opac;");
  281. node_shader_write(frag, "{");
  282. node_shader_add_uniform(frag, "vec2 texpaintSize", "_texpaintSize");
  283. node_shader_write(frag, "float tex_step = 1.0 / texpaintSize.x;");
  284. node_shader_write(frag, "height0 " + assign + " textureLodShared(texpaint_pack" + l.id + ", vec2(texCoord.x - tex_step, texCoord.y), 0.0).a * texpaint_opac;");
  285. node_shader_write(frag, "height1 " + assign + " textureLodShared(texpaint_pack" + l.id + ", vec2(texCoord.x + tex_step, texCoord.y), 0.0).a * texpaint_opac;");
  286. node_shader_write(frag, "height2 " + assign + " textureLodShared(texpaint_pack" + l.id + ", vec2(texCoord.x, texCoord.y - tex_step), 0.0).a * texpaint_opac;");
  287. node_shader_write(frag, "height3 " + assign + " textureLodShared(texpaint_pack" + l.id + ", vec2(texCoord.x, texCoord.y + tex_step), 0.0).a * texpaint_opac;");
  288. node_shader_write(frag, "}");
  289. }
  290. }
  291. if (slot_layer_get_object_mask(l) > 0) {
  292. node_shader_write(frag, "}");
  293. }
  294. }
  295. if (last_pass && context_raw.draw_texels) {
  296. node_shader_add_uniform(frag, "vec2 texpaintSize", "_texpaintSize");
  297. node_shader_write(frag, "vec2 texel0 = texCoord * texpaintSize * 0.01;");
  298. node_shader_write(frag, "vec2 texel1 = texCoord * texpaintSize * 0.1;");
  299. node_shader_write(frag, "vec2 texel2 = texCoord * texpaintSize;");
  300. node_shader_write(frag, "basecol *= max(float(mod(int(texel0.x), 2.0) == mod(int(texel0.y), 2.0)), 0.9);");
  301. node_shader_write(frag, "basecol *= max(float(mod(int(texel1.x), 2.0) == mod(int(texel1.y), 2.0)), 0.9);");
  302. node_shader_write(frag, "basecol *= max(float(mod(int(texel2.x), 2.0) == mod(int(texel2.y), 2.0)), 0.9);");
  303. }
  304. if (last_pass && context_raw.draw_wireframe) {
  305. node_shader_write(frag, "basecol *= 1.0 - textureLod(texuvmap, texCoord, 0.0).r;");
  306. }
  307. if (make_material_height_used) {
  308. node_shader_write(frag, "if (height > 0.0) {");
  309. // write(frag, "float height_dx = dFdx(height * 16.0);");
  310. // write(frag, "float height_dy = dFdy(height * 16.0);");
  311. node_shader_write(frag, "float height_dx = height0 - height1;");
  312. node_shader_write(frag, "float height_dy = height2 - height3;");
  313. // Whiteout blend
  314. node_shader_write(frag, "vec3 n1 = ntex * vec3(2.0, 2.0, 2.0) - vec3(1.0, 1.0, 1.0);");
  315. node_shader_write(frag, "vec3 n2 = normalize(vec3(height_dx * 16.0, height_dy * 16.0, 1.0));");
  316. node_shader_write(frag, "ntex = normalize(vec3(n1.xy + n2.xy, n1.z * n2.z)) * vec3(0.5, 0.5, 0.5) + vec3(0.5, 0.5, 0.5);");
  317. node_shader_write(frag, "}");
  318. }
  319. if (!last_pass) {
  320. node_shader_write(frag, "fragColor[0] = vec4(basecol, opacity);");
  321. node_shader_write(frag, "fragColor[1] = vec4(ntex, matid);");
  322. node_shader_write(frag, "fragColor[2] = vec4(occlusion, roughness, metallic, height);");
  323. parser_material_finalize(con_mesh);
  324. con_mesh.data.shader_from_source = true;
  325. con_mesh.data.vertex_shader = node_shader_get(vert);
  326. con_mesh.data.fragment_shader = node_shader_get(frag);
  327. return con_mesh;
  328. }
  329. frag.vvec = true;
  330. ///if (krom_direct3d11 || krom_direct3d12 || krom_metal || krom_vulkan)
  331. node_shader_write(frag, "mat3 TBN = cotangentFrame(n, vVec, texCoord);");
  332. ///else
  333. node_shader_write(frag, "mat3 TBN = cotangentFrame(n, -vVec, texCoord);");
  334. ///end
  335. node_shader_write(frag, "n = ntex * 2.0 - 1.0;");
  336. node_shader_write(frag, "n.y = -n.y;");
  337. node_shader_write(frag, "n = normalize(mul(n, TBN));");
  338. if (context_raw.viewport_mode == viewport_mode_t.LIT || context_raw.viewport_mode == viewport_mode_t.PATH_TRACE) {
  339. node_shader_write(frag, "basecol = pow(basecol, vec3(2.2, 2.2, 2.2));");
  340. if (context_raw.viewport_shader != null) {
  341. let color: string = context_raw.viewport_shader(frag);
  342. node_shader_write(frag, "fragColor[1] = vec4(" + color + ", 1.0);");
  343. }
  344. else if (context_raw.render_mode == render_mode_t.FORWARD && context_raw.viewport_mode != viewport_mode_t.PATH_TRACE) {
  345. frag.wposition = true;
  346. node_shader_write(frag, "vec3 albedo = mix(basecol, vec3(0.0, 0.0, 0.0), metallic);");
  347. node_shader_write(frag, "vec3 f0 = mix(vec3(0.04, 0.04, 0.04), basecol, metallic);");
  348. frag.vvec = true;
  349. node_shader_write(frag, "float dotNV = max(0.0, dot(n, vVec));");
  350. node_shader_write(frag, "vec2 envBRDF = texelFetch(senvmapBrdf, ivec2(vec2(roughness, 1.0 - dotNV) * 256.0), 0).xy;");
  351. node_shader_add_uniform(frag, "int envmapNumMipmaps", "_envmap_num_mipmaps");
  352. node_shader_add_uniform(frag, "vec4 envmapData", "_envmapData"); // angle, sin(angle), cos(angle), strength
  353. node_shader_write(frag, "vec3 wreflect = reflect(-vVec, n);");
  354. node_shader_write(frag, "float envlod = roughness * float(envmapNumMipmaps);");
  355. node_shader_add_function(frag, str_envmap_equirect);
  356. node_shader_write(frag, "vec3 prefilteredColor = textureLod(senvmapRadiance, envMapEquirect(wreflect, envmapData.x), envlod).rgb;");
  357. node_shader_add_uniform(frag, "vec3 lightArea0", "_light_area0");
  358. node_shader_add_uniform(frag, "vec3 lightArea1", "_light_area1");
  359. node_shader_add_uniform(frag, "vec3 lightArea2", "_light_area2");
  360. node_shader_add_uniform(frag, "vec3 lightArea3", "_light_area3");
  361. node_shader_add_function(frag, str_ltc_evaluate);
  362. node_shader_add_uniform(frag, "vec3 lightPos", "_point_pos");
  363. node_shader_add_uniform(frag, "vec3 lightColor", "_point_color");
  364. // write(frag, "float dotNL = max(dot(n, normalize(lightPos - wposition)), 0.0);");
  365. // write(frag, "vec3 direct = albedo * dotNL;");
  366. node_shader_write(frag, "float ldist = distance(wposition, lightPos);");
  367. node_shader_write(frag, "const float LUT_SIZE = 64.0;");
  368. node_shader_write(frag, "const float LUT_SCALE = (LUT_SIZE - 1.0) / LUT_SIZE;");
  369. node_shader_write(frag, "const float LUT_BIAS = 0.5 / LUT_SIZE;");
  370. node_shader_write(frag, "float theta = acos(dotNV);");
  371. node_shader_write(frag, "vec2 tuv = vec2(roughness, theta / (0.5 * 3.14159265));");
  372. node_shader_write(frag, "tuv = tuv * LUT_SCALE + LUT_BIAS;");
  373. node_shader_write(frag, "vec4 t = textureLod(sltcMat, tuv, 0.0);");
  374. node_shader_write(frag, "mat3 minv = mat3(vec3(1.0, 0.0, t.y), vec3(0.0, t.z, 0.0), vec3(t.w, 0.0, t.x));");
  375. node_shader_write(frag, "float ltcspec = ltcEvaluate(n, vVec, dotNV, wposition, minv, lightArea0, lightArea1, lightArea2, lightArea3);");
  376. node_shader_write(frag, "ltcspec *= textureLod(sltcMag, tuv, 0.0).a;");
  377. node_shader_write(frag, "mat3 mident = mat3(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0);");
  378. node_shader_write(frag, "float ltcdiff = ltcEvaluate(n, vVec, dotNV, wposition, mident, lightArea0, lightArea1, lightArea2, lightArea3);");
  379. node_shader_write(frag, "vec3 direct = albedo * ltcdiff + ltcspec * 0.05;");
  380. node_shader_write(frag, "direct *= lightColor * (1.0 / (ldist * ldist));");
  381. node_shader_add_uniform(frag, "vec4 shirr[7]", "_envmap_irradiance");
  382. node_shader_add_function(frag, str_sh_irradiance());
  383. node_shader_write(frag, "vec3 indirect = albedo * (shIrradiance(vec3(n.x * envmapData.z - n.y * envmapData.y, n.x * envmapData.y + n.y * envmapData.z, n.z), shirr) / 3.14159265);");
  384. node_shader_write(frag, "indirect += prefilteredColor * (f0 * envBRDF.x + envBRDF.y) * 1.5;");
  385. node_shader_write(frag, "indirect *= envmapData.w * occlusion;");
  386. node_shader_write(frag, "fragColor[1] = vec4(direct + indirect, 1.0);");
  387. }
  388. else { // Deferred, Pathtraced
  389. if (make_material_emis_used) {
  390. node_shader_write(frag, "if (int(matid * 255.0) % 3 == 1) basecol *= 10.0;"); // Boost for bloom
  391. }
  392. node_shader_write(frag, "fragColor[1] = vec4(basecol, occlusion);");
  393. }
  394. }
  395. else if (context_raw.viewport_mode == viewport_mode_t.BASE_COLOR && context_raw.layer.paint_base) {
  396. node_shader_write(frag, "fragColor[1] = vec4(basecol, 1.0);");
  397. }
  398. else if (context_raw.viewport_mode == viewport_mode_t.NORMAL_MAP && context_raw.layer.paint_nor) {
  399. node_shader_write(frag, "fragColor[1] = vec4(ntex.rgb, 1.0);");
  400. }
  401. else if (context_raw.viewport_mode == viewport_mode_t.OCCLUSION && context_raw.layer.paint_occ) {
  402. node_shader_write(frag, "fragColor[1] = vec4(vec3(occlusion, occlusion, occlusion), 1.0);");
  403. }
  404. else if (context_raw.viewport_mode == viewport_mode_t.ROUGHNESS && context_raw.layer.paint_rough) {
  405. node_shader_write(frag, "fragColor[1] = vec4(vec3(roughness, roughness, roughness), 1.0);");
  406. }
  407. else if (context_raw.viewport_mode == viewport_mode_t.METALLIC && context_raw.layer.paint_met) {
  408. node_shader_write(frag, "fragColor[1] = vec4(vec3(metallic, metallic, metallic), 1.0);");
  409. }
  410. else if (context_raw.viewport_mode == viewport_mode_t.OPACITY && context_raw.layer.paint_opac) {
  411. node_shader_write(frag, "fragColor[1] = vec4(vec3(texpaint_sample.a, texpaint_sample.a, texpaint_sample.a), 1.0);");
  412. }
  413. else if (context_raw.viewport_mode == viewport_mode_t.HEIGHT && context_raw.layer.paint_height) {
  414. node_shader_write(frag, "fragColor[1] = vec4(vec3(height, height, height), 1.0);");
  415. }
  416. else if (context_raw.viewport_mode == viewport_mode_t.EMISSION) {
  417. node_shader_write(frag, "float emis = int(matid * 255.0) % 3 == 1 ? 1.0 : 0.0;");
  418. node_shader_write(frag, "fragColor[1] = vec4(vec3(emis, emis, emis), 1.0);");
  419. }
  420. else if (context_raw.viewport_mode == viewport_mode_t.SUBSURFACE) {
  421. node_shader_write(frag, "float subs = int(matid * 255.0) % 3 == 2 ? 1.0 : 0.0;");
  422. node_shader_write(frag, "fragColor[1] = vec4(vec3(subs, subs, subs), 1.0);");
  423. }
  424. else if (context_raw.viewport_mode == viewport_mode_t.TEXCOORD) {
  425. node_shader_write(frag, "fragColor[1] = vec4(texCoord, 0.0, 1.0);");
  426. }
  427. else if (context_raw.viewport_mode == viewport_mode_t.OBJECT_NORMAL) {
  428. frag.nattr = true;
  429. node_shader_write(frag, "fragColor[1] = vec4(nAttr, 1.0);");
  430. }
  431. else if (context_raw.viewport_mode == viewport_mode_t.MATERIAL_ID) {
  432. node_shader_add_shared_sampler(frag, "sampler2D texpaint_nor" + context_raw.layer.id);
  433. node_shader_add_uniform(frag, "vec2 texpaintSize", "_texpaintSize");
  434. node_shader_write(frag, "float sample_matid = texelFetch(texpaint_nor" + context_raw.layer.id + ", ivec2(texCoord * texpaintSize), 0).a + 1.0 / 255.0;");
  435. node_shader_write(frag, "float matid_r = fract(sin(dot(vec2(sample_matid, sample_matid * 20.0), vec2(12.9898, 78.233))) * 43758.5453);");
  436. node_shader_write(frag, "float matid_g = fract(sin(dot(vec2(sample_matid * 20.0, sample_matid), vec2(12.9898, 78.233))) * 43758.5453);");
  437. node_shader_write(frag, "float matid_b = fract(sin(dot(vec2(sample_matid, sample_matid * 40.0), vec2(12.9898, 78.233))) * 43758.5453);");
  438. node_shader_write(frag, "fragColor[1] = vec4(matid_r, matid_g, matid_b, 1.0);");
  439. }
  440. else if (context_raw.viewport_mode == viewport_mode_t.OBJECT_ID) {
  441. node_shader_add_uniform(frag, "float objectId", "_objectId");
  442. node_shader_write(frag, "float obid = objectId + 1.0 / 255.0;");
  443. node_shader_write(frag, "float id_r = fract(sin(dot(vec2(obid, obid * 20.0), vec2(12.9898, 78.233))) * 43758.5453);");
  444. node_shader_write(frag, "float id_g = fract(sin(dot(vec2(obid * 20.0, obid), vec2(12.9898, 78.233))) * 43758.5453);");
  445. node_shader_write(frag, "float id_b = fract(sin(dot(vec2(obid, obid * 40.0), vec2(12.9898, 78.233))) * 43758.5453);");
  446. node_shader_write(frag, "fragColor[1] = vec4(id_r, id_g, id_b, 1.0);");
  447. }
  448. else if (context_raw.viewport_mode == viewport_mode_t.MASK && (slot_layer_get_masks(context_raw.layer) != null || slot_layer_is_mask(context_raw.layer))) {
  449. if (slot_layer_is_mask(context_raw.layer)) {
  450. node_shader_write(frag, "float mask_view = textureLodShared(texpaint" + context_raw.layer.id + ", texCoord, 0.0).r;");
  451. }
  452. else {
  453. node_shader_write(frag, "float mask_view = 0.0;");
  454. for (let i: i32 = 0; i < slot_layer_get_masks(context_raw.layer).length; ++i) {
  455. let m: slot_layer_t = slot_layer_get_masks(context_raw.layer)[i];
  456. if (!slot_layer_is_visible(m)) continue;
  457. node_shader_write(frag, "float mask_sample" + m.id + " = textureLodShared(texpaint_view_mask" + m.id + ", texCoord, 0.0).r;");
  458. node_shader_write(frag, "mask_view = " + make_material_blend_mode_mask(frag, m.blending, "mask_view", "mask_sample" + m.id, "float(" + slot_layer_get_opacity(m) + ")") + ";");
  459. }
  460. }
  461. node_shader_write(frag, "fragColor[1] = vec4(mask_view, mask_view, mask_view, 1.0);");
  462. }
  463. else {
  464. node_shader_write(frag, "fragColor[1] = vec4(1.0, 0.0, 1.0, 1.0);"); // Pink
  465. }
  466. if (context_raw.viewport_mode != viewport_mode_t.LIT && context_raw.viewport_mode != viewport_mode_t.PATH_TRACE) {
  467. node_shader_write(frag, "fragColor[1].rgb = pow(fragColor[1].rgb, vec3(2.2, 2.2, 2.2));");
  468. }
  469. node_shader_write(frag, "n /= (abs(n.x) + abs(n.y) + abs(n.z));");
  470. node_shader_write(frag, "n.xy = n.z >= 0.0 ? n.xy : octahedronWrap(n.xy);");
  471. node_shader_write(frag, "fragColor[0] = vec4(n.xy, roughness, packFloatInt16(metallic, uint(int(matid * 255.0) % 3)));");
  472. }
  473. node_shader_write(frag, "vec2 posa = (wvpposition.xy / wvpposition.w) * 0.5 + 0.5;");
  474. node_shader_write(frag, "vec2 posb = (prevwvpposition.xy / prevwvpposition.w) * 0.5 + 0.5;");
  475. node_shader_write(frag, "fragColor[2] = vec4(posa - posb, texCoord.xy);");
  476. parser_material_finalize(con_mesh);
  477. con_mesh.data.shader_from_source = true;
  478. con_mesh.data.vertex_shader = node_shader_get(vert);
  479. con_mesh.data.fragment_shader = node_shader_get(frag);
  480. return con_mesh;
  481. }
  482. function make_mesh_get_max_textures(): i32 {
  483. ///if krom_direct3d11
  484. return 128 - 66;
  485. ///else
  486. return 16 - 3; // G4onG5/G4.c.h MAX_TEXTURES
  487. ///end
  488. }