MakeBake.hx 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. package arm.node;
  2. import arm.ui.UISidebar;
  3. import arm.shader.NodeShader;
  4. import arm.shader.NodeShaderContext;
  5. import arm.shader.NodeShaderData;
  6. import arm.shader.ShaderFunctions;
  7. import arm.shader.MaterialParser;
  8. import arm.Enums;
  9. class MakeBake {
  10. public static function run(con: NodeShaderContext, vert: NodeShader, frag: NodeShader) {
  11. if (Context.bakeType == BakeAO) { // Voxel
  12. #if rp_voxelao
  13. // Apply normal channel
  14. frag.wposition = true;
  15. frag.n = true;
  16. frag.vVec = true;
  17. frag.add_function(ShaderFunctions.str_cotangentFrame);
  18. #if kha_direct3d11
  19. frag.write('mat3 TBN = cotangentFrame(n, vVec, texCoord);');
  20. #else
  21. frag.write('mat3 TBN = cotangentFrame(n, -vVec, texCoord);');
  22. #end
  23. frag.write('n = nortan * 2.0 - 1.0;');
  24. frag.write('n.y = -n.y;');
  25. frag.write('n = normalize(mul(n, TBN));');
  26. frag.write(MakeMaterial.voxelgiHalfExtents());
  27. frag.write('vec3 voxpos = wposition / voxelgiHalfExtents;');
  28. frag.add_uniform('sampler3D voxels');
  29. frag.add_function(ShaderFunctions.str_traceAO);
  30. frag.n = true;
  31. var strength = Context.bakeAoStrength;
  32. var radius = Context.bakeAoRadius;
  33. var offset = Context.bakeAoOffset;
  34. frag.write('float ao = traceAO(voxpos, n, $radius, $offset) * $strength;');
  35. if (Context.bakeAxis != BakeXYZ) {
  36. var axis = axisString(Context.bakeAxis);
  37. frag.write('ao *= dot(n, $axis);');
  38. }
  39. frag.write('ao = 1.0 - ao;');
  40. frag.write('fragColor[0] = vec4(ao, ao, ao, 1.0);');
  41. #end
  42. }
  43. else if (Context.bakeType == BakeCurvature) {
  44. var pass = MaterialParser.bake_passthrough;
  45. var strength = pass ? MaterialParser.bake_passthrough_strength : Context.bakeCurvStrength + "";
  46. var radius = pass ? MaterialParser.bake_passthrough_radius : Context.bakeCurvRadius + "";
  47. var offset = pass ? MaterialParser.bake_passthrough_offset : Context.bakeCurvOffset + "";
  48. frag.n = true;
  49. frag.write('vec3 dx = dFdx(n);');
  50. frag.write('vec3 dy = dFdy(n);');
  51. frag.write('float curvature = max(dot(dx, dx), dot(dy, dy));');
  52. frag.write('curvature = clamp(pow(curvature, (1.0 / ' + radius + ') * 0.25) * ' + strength + ' * 2.0 + ' + offset + ' / 10.0, 0.0, 1.0);');
  53. if (Context.bakeAxis != BakeXYZ) {
  54. var axis = axisString(Context.bakeAxis);
  55. frag.write('curvature *= dot(n, $axis);');
  56. }
  57. frag.write('fragColor[0] = vec4(curvature, curvature, curvature, 1.0);');
  58. }
  59. else if (Context.bakeType == BakeNormal) { // Tangent
  60. frag.n = true;
  61. frag.add_uniform('sampler2D texpaint_undo', '_texpaint_undo'); // Baked high-poly normals
  62. frag.write('vec3 n0 = textureLod(texpaint_undo, texCoord, 0.0).rgb * vec3(2.0, 2.0, 2.0) - vec3(1.0, 1.0, 1.0);');
  63. frag.add_function(ShaderFunctions.str_cotangentFrame);
  64. frag.write('mat3 invTBN = transpose(cotangentFrame(n, n, texCoord));');
  65. frag.write('vec3 res = normalize(mul(n0, invTBN)) * vec3(0.5, 0.5, 0.5) + vec3(0.5, 0.5, 0.5);');
  66. frag.write('fragColor[0] = vec4(res, 1.0);');
  67. }
  68. else if (Context.bakeType == BakeNormalObject) {
  69. frag.n = true;
  70. frag.write('fragColor[0] = vec4(n * vec3(0.5, 0.5, 0.5) + vec3(0.5, 0.5, 0.5), 1.0);');
  71. if (Context.bakeUpAxis == BakeUpY) {
  72. frag.write('fragColor[0].rgb = vec3(fragColor[0].r, fragColor[0].b, 1.0 - fragColor[0].g);');
  73. }
  74. }
  75. else if (Context.bakeType == BakeHeight) {
  76. frag.wposition = true;
  77. frag.add_uniform('sampler2D texpaint_undo', '_texpaint_undo'); // Baked high-poly positions
  78. frag.write('vec3 wpos0 = textureLod(texpaint_undo, texCoord, 0.0).rgb * vec3(2.0, 2.0, 2.0) - vec3(1.0, 1.0, 1.0);');
  79. frag.write('float res = distance(wpos0, wposition) * 10.0;');
  80. frag.write('fragColor[0] = vec4(res, res, res, 1.0);');
  81. }
  82. else if (Context.bakeType == BakeDerivative) {
  83. frag.add_uniform('sampler2D texpaint_undo', '_texpaint_undo'); // Baked height
  84. frag.write('vec2 texDx = dFdx(texCoord);');
  85. frag.write('vec2 texDy = dFdy(texCoord);');
  86. frag.write('float h0 = textureLod(texpaint_undo, texCoord, 0.0).r * 100;');
  87. frag.write('float h1 = textureLod(texpaint_undo, texCoord + texDx, 0.0).r * 100;');
  88. frag.write('float h2 = textureLod(texpaint_undo, texCoord + texDy, 0.0).r * 100;');
  89. frag.write('fragColor[0] = vec4((h1 - h0) * 0.5 + 0.5, (h2 - h0) * 0.5 + 0.5, 0.0, 1.0);');
  90. }
  91. else if (Context.bakeType == BakePosition) {
  92. frag.wposition = true;
  93. frag.write('fragColor[0] = vec4(wposition * vec3(0.5, 0.5, 0.5) + vec3(0.5, 0.5, 0.5), 1.0);');
  94. if (Context.bakeUpAxis == BakeUpY) {
  95. frag.write('fragColor[0].rgb = vec3(fragColor[0].r, fragColor[0].b, 1.0 - fragColor[0].g);');
  96. }
  97. }
  98. else if (Context.bakeType == BakeTexCoord) {
  99. frag.write('fragColor[0] = vec4(texCoord.xy, 0.0, 1.0);');
  100. }
  101. else if (Context.bakeType == BakeMaterialID) {
  102. frag.add_uniform('sampler2D texpaint_nor_undo', '_texpaint_nor_undo');
  103. frag.write('float sample_matid = textureLod(texpaint_nor_undo, texCoord, 0.0).a + 1.0 / 255.0;');
  104. frag.write('float matid_r = fract(sin(dot(vec2(sample_matid, sample_matid * 20.0), vec2(12.9898, 78.233))) * 43758.5453);');
  105. frag.write('float matid_g = fract(sin(dot(vec2(sample_matid * 20.0, sample_matid), vec2(12.9898, 78.233))) * 43758.5453);');
  106. frag.write('float matid_b = fract(sin(dot(vec2(sample_matid, sample_matid * 40.0), vec2(12.9898, 78.233))) * 43758.5453);');
  107. frag.write('fragColor[0] = vec4(matid_r, matid_g, matid_b, 1.0);');
  108. }
  109. else if (Context.bakeType == BakeObjectID) {
  110. frag.add_uniform('float objectId', '_objectId');
  111. frag.write('float obid = objectId + 1.0 / 255.0;');
  112. frag.write('float id_r = fract(sin(dot(vec2(obid, obid * 20.0), vec2(12.9898, 78.233))) * 43758.5453);');
  113. frag.write('float id_g = fract(sin(dot(vec2(obid * 20.0, obid), vec2(12.9898, 78.233))) * 43758.5453);');
  114. frag.write('float id_b = fract(sin(dot(vec2(obid, obid * 40.0), vec2(12.9898, 78.233))) * 43758.5453);');
  115. frag.write('fragColor[0] = vec4(id_r, id_g, id_b, 1.0);');
  116. }
  117. else if (Context.bakeType == BakeVertexColor) {
  118. if (con.allow_vcols) {
  119. con.add_elem("col", "short4norm");
  120. frag.write('fragColor[0] = vec4(vcolor.r, vcolor.g, vcolor.b, 1.0);');
  121. }
  122. else {
  123. frag.write('fragColor[0] = vec4(1.0, 1.0, 1.0, 1.0);');
  124. }
  125. }
  126. }
  127. public static function positionAndNormal(vert: NodeShader, frag: NodeShader) {
  128. vert.add_out('vec3 position');
  129. vert.add_out('vec3 normal');
  130. vert.add_uniform('mat4 W', '_worldMatrix');
  131. vert.write('position = vec4(mul(vec4(pos.xyz, 1.0), W)).xyz;');
  132. vert.write('normal = vec3(nor.xy, pos.w);');
  133. vert.write('vec2 tpos = vec2(tex.x * 2.0 - 1.0, (1.0 - tex.y) * 2.0 - 1.0);');
  134. vert.write('gl_Position = vec4(tpos, 0.0, 1.0);');
  135. frag.add_out('vec4 fragColor[2]');
  136. frag.write('fragColor[0] = vec4(position, 1.0);');
  137. frag.write('fragColor[1] = vec4(normal, 1.0);');
  138. }
  139. public static function setColorWrites(con_paint: NodeShaderContext) {
  140. // Bake into base color, disable other slots
  141. con_paint.data.color_writes_red[1] = false;
  142. con_paint.data.color_writes_green[1] = false;
  143. con_paint.data.color_writes_blue[1] = false;
  144. con_paint.data.color_writes_alpha[1] = false;
  145. con_paint.data.color_writes_red[2] = false;
  146. con_paint.data.color_writes_green[2] = false;
  147. con_paint.data.color_writes_blue[2] = false;
  148. con_paint.data.color_writes_alpha[2] = false;
  149. }
  150. static function axisString(i:Int):String {
  151. return i == BakeX ? "vec3(1,0,0)" :
  152. i == BakeY ? "vec3(0,1,0)" :
  153. i == BakeZ ? "vec3(0,0,1)" :
  154. i == BakeMX ? "vec3(-1,0,0)" :
  155. i == BakeMY ? "vec3(0,-1,0)" :
  156. "vec3(0,0,-1)";
  157. }
  158. }