MakeBake.hx 6.9 KB

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