diff --git a/Assets/painter/metal/clear_color_depth_pass.arm b/Assets/painter/metal/clear_color_depth_pass.arm deleted file mode 100644 index cb2ce586..00000000 Binary files a/Assets/painter/metal/clear_color_depth_pass.arm and /dev/null differ diff --git a/Assets/painter/metal/clear_pass.arm b/Assets/painter/metal/clear_pass.arm new file mode 100644 index 00000000..766d95f6 Binary files /dev/null and b/Assets/painter/metal/clear_pass.arm differ diff --git a/Libraries/nodelib/Sources/arm/node/Material.hx b/Libraries/nodelib/Sources/arm/node/Material.hx index 91860b27..b1941077 100644 --- a/Libraries/nodelib/Sources/arm/node/Material.hx +++ b/Libraries/nodelib/Sources/arm/node/Material.hx @@ -940,7 +940,7 @@ class Material { frag.add_function(MaterialFunctions.str_cotangentFrame); } frag.n = true; - #if (kha_direct3d11 || kha_direct3d12) + #if (kha_direct3d11 || kha_direct3d12 || kha_metal) frag.write('mat3 TBN = cotangentFrame(n, vVec, texCoord);'); #else frag.write('mat3 TBN = cotangentFrame(n, -vVec, texCoord);'); @@ -981,7 +981,7 @@ class Material { else if (node.type == "CAMERA") { if (socket == node.outputs[1]) { // View Z Depth curshader.add_uniform("vec2 cameraProj", "_cameraPlaneProj"); - #if (kha_direct3d11 || kha_direct3d12) + #if (kha_direct3d11 || kha_direct3d12 || kha_metal) curshader.wvpposition = true; return "(cameraProj.y / ((wvpposition.z / wvpposition.w) - cameraProj.x))"; #else @@ -1038,7 +1038,7 @@ class Material { } else if (node.type == "NEW_GEOMETRY") { if (socket == node.outputs[6]) { // Backfacing - #if (kha_direct3d11 || kha_direct3d12) + #if (kha_direct3d11 || kha_direct3d12 || kha_metal) return "0.0"; // SV_IsFrontFace #else return "(1.0 - float(gl_FrontFacing))"; @@ -1474,7 +1474,7 @@ class Material { } public static inline function to_vec3(s: String): String { - #if (kha_direct3d11 || kha_direct3d12) + #if (kha_direct3d11 || kha_direct3d12 || kha_metal) return '($s).xxx'; #else return 'vec3($s)'; diff --git a/Libraries/shaderlib/Sources/arm/node/MaterialShader.hx b/Libraries/shaderlib/Sources/arm/node/MaterialShader.hx index e245bb2c..09c011ae 100644 --- a/Libraries/shaderlib/Sources/arm/node/MaterialShader.hx +++ b/Libraries/shaderlib/Sources/arm/node/MaterialShader.hx @@ -392,20 +392,16 @@ class MaterialShader { for (a in uniforms) { s += 'uniform ' + a + ';\n'; - #if (kha_direct3d11 || kha_direct3d12) if (StringTools.startsWith(a, 'sampler')) { s += 'SamplerState ' + a.split(' ')[1] + '_sampler;\n'; } - #end } if (sharedSamplers.length > 0) { for (a in sharedSamplers) { s += 'uniform ' + a + ';\n'; } - #if (kha_direct3d11 || kha_direct3d12) s += 'SamplerState $sharedSampler;\n'; - #end } for (f in functions) { diff --git a/Shaders/painter/metal/clear_pass_color.frag.glsl b/Shaders/painter/metal/clear_pass_color.frag.glsl new file mode 100644 index 00000000..090edd4b --- /dev/null +++ b/Shaders/painter/metal/clear_pass_color.frag.glsl @@ -0,0 +1,7 @@ +#version 330 +in vec2 texCoord; +out vec4 fragColor; +uniform vec4 clearColor; +void main() { + fragColor = clearColor; +} diff --git a/Shaders/painter/metal/clear_color_depth_pass.frag.glsl b/Shaders/painter/metal/clear_pass_color_depth.frag.glsl similarity index 63% rename from Shaders/painter/metal/clear_color_depth_pass.frag.glsl rename to Shaders/painter/metal/clear_pass_color_depth.frag.glsl index 03dd5a05..df4224ea 100644 --- a/Shaders/painter/metal/clear_color_depth_pass.frag.glsl +++ b/Shaders/painter/metal/clear_pass_color_depth.frag.glsl @@ -1,7 +1,8 @@ #version 330 in vec2 texCoord; out vec4 fragColor; +uniform vec4 clearColor; void main() { - fragColor = vec4(0.0, 0.0, 0.0, 1.0); + fragColor = clearColor; gl_FragDepth = 1.0; } diff --git a/Shaders/painter/metal/clear_pass_depth.frag.glsl b/Shaders/painter/metal/clear_pass_depth.frag.glsl new file mode 100644 index 00000000..090edd4b --- /dev/null +++ b/Shaders/painter/metal/clear_pass_depth.frag.glsl @@ -0,0 +1,7 @@ +#version 330 +in vec2 texCoord; +out vec4 fragColor; +uniform vec4 clearColor; +void main() { + fragColor = clearColor; +} diff --git a/Sources/arm/App.hx b/Sources/arm/App.hx index 8ee96d66..dd4b75b3 100644 --- a/Sources/arm/App.hx +++ b/Sources/arm/App.hx @@ -150,6 +150,13 @@ class App { new UINodes(); new UIView2D(); new Camera(); + #if kha_metal // TODO: fix first draw flicker + iron.App.notifyOnRender2D(function(g) { + g.drawScaledImage(Res.get("cursor.k"), 0, 0, 0, 0); + }); + #end + iron.App.notifyOnRender2D(UIView2D.inst.render); + iron.App.notifyOnUpdate(UIView2D.inst.update); iron.App.notifyOnRender2D(UISidebar.inst.renderCursor); iron.App.notifyOnUpdate(UINodes.inst.update); iron.App.notifyOnRender2D(UINodes.inst.render); diff --git a/Sources/arm/data/LayerSlot.hx b/Sources/arm/data/LayerSlot.hx index b5112567..0a81b67b 100644 --- a/Sources/arm/data/LayerSlot.hx +++ b/Sources/arm/data/LayerSlot.hx @@ -171,7 +171,7 @@ class LayerSlot { function clearMask(g: kha.graphics4.Graphics) { g.end(); - texpaint_mask.g2.begin(); + texpaint_mask.g2.begin(false); if (createMaskImage != null) { texpaint_mask.g2.drawScaledImage(createMaskImage, 0, 0, texpaint_mask.width, texpaint_mask.height); diff --git a/Sources/arm/node/MakeBlur.hx b/Sources/arm/node/MakeBlur.hx index 314ac3cd..9f2e4dfe 100644 --- a/Sources/arm/node/MakeBlur.hx +++ b/Sources/arm/node/MakeBlur.hx @@ -25,7 +25,7 @@ class MakeBlur { if (Context.material.paintSubs) { frag.write('float subs = 0.0;'); } - #if (kha_direct3d11 || kha_direct3d12) + #if (kha_direct3d11 || kha_direct3d12 || kha_metal) frag.write('const float blur_weight[15] = {0.034619 / 2.0, 0.044859 / 2.0, 0.055857 / 2.0, 0.066833 / 2.0, 0.076841 / 2.0, 0.084894 / 2.0, 0.090126 / 2.0, 0.09194 / 2.0, 0.090126 / 2.0, 0.084894 / 2.0, 0.076841 / 2.0, 0.066833 / 2.0, 0.055857 / 2.0, 0.044859 / 2.0, 0.034619 / 2.0};'); #else frag.write('const float blur_weight[15] = float[](0.034619 / 2.0, 0.044859 / 2.0, 0.055857 / 2.0, 0.066833 / 2.0, 0.076841 / 2.0, 0.084894 / 2.0, 0.090126 / 2.0, 0.09194 / 2.0, 0.090126 / 2.0, 0.084894 / 2.0, 0.076841 / 2.0, 0.066833 / 2.0, 0.055857 / 2.0, 0.044859 / 2.0, 0.034619 / 2.0);'); diff --git a/Sources/arm/node/MakeDiscard.hx b/Sources/arm/node/MakeDiscard.hx index f391f675..2f4c3263 100644 --- a/Sources/arm/node/MakeDiscard.hx +++ b/Sources/arm/node/MakeDiscard.hx @@ -43,7 +43,7 @@ class MakeDiscard { public static function materialId(vert: MaterialShader, frag: MaterialShader) { frag.wvpposition = true; frag.write('vec2 picker_sample_tc = vec2(wvpposition.x / wvpposition.w, wvpposition.y / wvpposition.w) * 0.5 + 0.5;'); - #if (kha_direct3d11 || kha_direct3d12) + #if (kha_direct3d11 || kha_direct3d12 || kha_metal) frag.write('picker_sample_tc.y = 1.0 - picker_sample_tc.y;'); #end frag.add_uniform('sampler2D texpaint_nor_undo', '_texpaint_nor_undo'); diff --git a/Sources/arm/node/MakeMesh.hx b/Sources/arm/node/MakeMesh.hx index 0515e2d8..ce56ee81 100644 --- a/Sources/arm/node/MakeMesh.hx +++ b/Sources/arm/node/MakeMesh.hx @@ -84,7 +84,7 @@ class MakeMesh { frag.vVec = true; frag.add_function(MaterialFunctions.str_cotangentFrame); - #if (kha_direct3d11 || kha_direct3d12) + #if (kha_direct3d11 || kha_direct3d12 || kha_metal) frag.write('mat3 TBN = cotangentFrame(n, vVec, texCoord);'); #else frag.write('mat3 TBN = cotangentFrame(n, -vVec, texCoord);'); @@ -456,7 +456,7 @@ class MakeMesh { } static function getMaxVisibleLayers(): Int { - #if (kha_direct3d11 || kha_direct3d12) + #if (kha_direct3d11 || kha_direct3d12 || kha_metal) // 128 texture slots available // 4 textures per layer (3 + 1 mask) // 32 layers - base + 31 on top diff --git a/Sources/arm/node/MakeMeshPreview.hx b/Sources/arm/node/MakeMeshPreview.hx index a8fd89b4..f8832353 100644 --- a/Sources/arm/node/MakeMeshPreview.hx +++ b/Sources/arm/node/MakeMeshPreview.hx @@ -102,7 +102,7 @@ class MakeMeshPreview { } else { frag.vVec = true; - #if (kha_direct3d11 || kha_direct3d12) + #if (kha_direct3d11 || kha_direct3d12 || kha_metal) frag.write('mat3 TBN = cotangentFrame(n, vVec, texCoord);'); #else frag.write('mat3 TBN = cotangentFrame(n, -vVec, texCoord);'); diff --git a/Sources/arm/node/MakePaint.hx b/Sources/arm/node/MakePaint.hx index c6404bea..a6aa7333 100644 --- a/Sources/arm/node/MakePaint.hx +++ b/Sources/arm/node/MakePaint.hx @@ -65,7 +65,7 @@ class MakePaint { vert.write('vec2 subtex = tex;'); } - #if (kha_direct3d11 || kha_direct3d12) + #if (kha_direct3d11 || kha_direct3d12 || kha_metal) vert.write('vec2 tpos = vec2(subtex.x * 2.0 - 1.0, (1.0 - subtex.y) * 2.0 - 1.0);'); #else vert.write('vec2 tpos = vec2(subtex.xy * 2.0 - 1.0);'); @@ -283,7 +283,7 @@ class MakePaint { // Manual blending to preserve memory frag.wvpposition = true; frag.write('vec2 sample_tc = vec2(wvpposition.x / wvpposition.w, wvpposition.y / wvpposition.w) * 0.5 + 0.5;'); - #if (kha_direct3d11 || kha_direct3d12) + #if (kha_direct3d11 || kha_direct3d12 || kha_metal) frag.write('sample_tc.y = 1.0 - sample_tc.y;'); #end frag.add_uniform('sampler2D paintmask'); diff --git a/Sources/arm/node/MakeVoxel.hx b/Sources/arm/node/MakeVoxel.hx index 77023e4b..320a5e19 100644 --- a/Sources/arm/node/MakeVoxel.hx +++ b/Sources/arm/node/MakeVoxel.hx @@ -26,7 +26,7 @@ class MakeVoxel { var ds = MaterialBuilder.getDisplaceStrength(); pipeState.vertexShader = kha.graphics4.VertexShader.fromSource( - #if (kha_direct3d11 || kha_direct3d12) + #if kha_direct3d11 "#define vec3 float3 uniform float4x4 W; uniform float3x3 N; diff --git a/Sources/arm/node/MaterialBuilder.hx b/Sources/arm/node/MaterialBuilder.hx index 83b1a706..de85e9de 100644 --- a/Sources/arm/node/MaterialBuilder.hx +++ b/Sources/arm/node/MaterialBuilder.hx @@ -59,7 +59,7 @@ class MaterialBuilder { return 'mix($cola, $cola + $colb, $opac)'; } else if (blending == BlendOverlay) { - #if (kha_direct3d11 || kha_direct3d12) + #if (kha_direct3d11 || kha_direct3d12 || kha_metal) return 'mix($cola, ($cola < vec3(0.5, 0.5, 0.5) ? vec3(2.0, 2.0, 2.0) * $cola * $colb : vec3(1.0, 1.0, 1.0) - vec3(2.0, 2.0, 2.0) * (vec3(1.0, 1.0, 1.0) - $colb) * (vec3(1.0, 1.0, 1.0) - $cola)), $opac)'; #else return 'mix($cola, $colb, $opac)'; // TODO diff --git a/Sources/arm/render/RenderPathDeferred.hx b/Sources/arm/render/RenderPathDeferred.hx index a6c853a5..6cc1c2b6 100644 --- a/Sources/arm/render/RenderPathDeferred.hx +++ b/Sources/arm/render/RenderPathDeferred.hx @@ -25,10 +25,16 @@ class RenderPathDeferred { #if kha_metal { - path.loadShader("clear_color_depth_pass/clear_color_depth_pass/clear_color_depth8_pass"); - path.loadShader("clear_color_depth_pass/clear_color_depth_pass/clear_color_depth32_pass"); - path.loadShader("clear_color_depth_pass/clear_color_depth_pass/clear_color_depth64_pass"); - path.clearShader = "clear_color_depth_pass/clear_color_depth_pass/clear_color_depth32_pass"; + path.loadShader("clear_pass/clear_pass/clear_pass_color_depth_r8"); + path.loadShader("clear_pass/clear_pass/clear_pass_color_depth_rgba32"); + path.loadShader("clear_pass/clear_pass/clear_pass_color_depth_rgba64"); + path.loadShader("clear_pass/clear_pass/clear_pass_color_r8"); + path.loadShader("clear_pass/clear_pass/clear_pass_color_rgba32"); + path.loadShader("clear_pass/clear_pass/clear_pass_color_rgba64"); + path.loadShader("clear_pass/clear_pass/clear_pass_depth_r8"); + path.loadShader("clear_pass/clear_pass/clear_pass_depth_rgba32"); + path.loadShader("clear_pass/clear_pass/clear_pass_depth_rgba64"); + path.clearShader = "clear_pass/clear_pass/clear_pass"; } #end @@ -540,9 +546,6 @@ class RenderPathDeferred { var current = taaFrame % 2 == 0 ? "bufa" : "taa2"; var last = taaFrame % 2 == 0 ? "taa2" : "bufa"; - #if kha_metal - path.clearShader = "clear_color_depth_pass/clear_color_depth_pass/clear_color_depth32_pass"; - #end path.setTarget(current); path.clearTarget(0x00000000); path.bindTarget("buf", "colorTex"); @@ -592,9 +595,6 @@ class RenderPathDeferred { } public static function drawGbuffer() { - #if kha_metal - path.clearShader = "clear_color_depth_pass/clear_color_depth_pass/clear_color_depth64_pass"; - #end path.setTarget("gbuffer0"); // Only clear gbuffer0 path.clearTarget(null, 1.0); path.setTarget("gbuffer2"); diff --git a/Sources/arm/render/RenderPathForward.hx b/Sources/arm/render/RenderPathForward.hx index 0b9de131..e4ee51ce 100644 --- a/Sources/arm/render/RenderPathForward.hx +++ b/Sources/arm/render/RenderPathForward.hx @@ -60,9 +60,6 @@ class RenderPathForward { } static function drawGbuffer() { - #if kha_metal - path.clearShader = "clear_color_depth_pass/clear_color_depth_pass/clear_color_depth64_pass"; - #end path.setTarget("gbuffer0"); path.clearTarget(null, 1.0); path.setTarget("gbuffer2"); @@ -98,10 +95,6 @@ class RenderPathForward { var current = taaFrame % 2 == 0 ? "bufa" : "taa2"; var last = taaFrame % 2 == 0 ? "taa2" : "bufa"; - #if kha_metal - path.clearShader = "clear_color_depth_pass/clear_color_depth_pass/clear_color_depth32_pass"; - #end - path.setTarget(current); path.clearTarget(0x00000000); path.bindTarget("buf", "colorTex"); diff --git a/Sources/arm/render/RenderPathPaint.hx b/Sources/arm/render/RenderPathPaint.hx index 895a5e5b..12776c93 100644 --- a/Sources/arm/render/RenderPathPaint.hx +++ b/Sources/arm/render/RenderPathPaint.hx @@ -624,7 +624,6 @@ class RenderPathPaint { if (Context.brushBlendDirty) { Context.brushBlendDirty = false; #if kha_metal - path.clearShader = "clear_color_depth_pass/clear_color_depth_pass/clear_color_depth8_pass"; path.setTarget("texpaint_blend0"); path.clearTarget(0x00000000); path.setTarget("texpaint_blend1"); diff --git a/Sources/arm/render/RenderPathPreview.hx b/Sources/arm/render/RenderPathPreview.hx index d1addad2..48906eb6 100644 --- a/Sources/arm/render/RenderPathPreview.hx +++ b/Sources/arm/render/RenderPathPreview.hx @@ -83,9 +83,6 @@ class RenderPathPreview { } public static function commandsPreview() { - #if kha_metal - path.clearShader = "clear_color_depth_pass/clear_color_depth_pass/clear_color_depth64_pass"; - #end path.setTarget("mgbuffer2"); path.clearTarget(0xff000000); diff --git a/Sources/arm/ui/UISidebar.hx b/Sources/arm/ui/UISidebar.hx index ed95336a..1f20be38 100644 --- a/Sources/arm/ui/UISidebar.hx +++ b/Sources/arm/ui/UISidebar.hx @@ -793,7 +793,7 @@ class UISidebar { g.color = kha.Color.fromFloats(1, 1, 1, Context.brushOpacity); var angle = (Context.brushAngle + Context.brushNodesAngle) * (Math.PI / 180); g.pushRotation(-angle, mx, my); - #if (kha_direct3d11 || kha_direct3d12) + #if (kha_direct3d11 || kha_direct3d12 || kha_metal) g.drawScaledImage(Context.decalImage, mx - psizex / 2, my - psizey / 2, psizex, psizey); #else g.drawScaledImage(Context.decalImage, mx - psizex / 2, my - psizey / 2 + psizey, psizex, -psizey); diff --git a/Sources/arm/ui/UIView2D.hx b/Sources/arm/ui/UIView2D.hx index cde60446..877e3c90 100644 --- a/Sources/arm/ui/UIView2D.hx +++ b/Sources/arm/ui/UIView2D.hx @@ -56,12 +56,9 @@ class UIView2D { var scale = Config.raw.window_scale; ui = new Zui({font: App.font, theme: App.theme, color_wheel: App.colorWheel, scaleFactor: scale}); ui.scrollEnabled = false; - - iron.App.notifyOnRender2D(render); - iron.App.notifyOnUpdate(update); } - function render(g: kha.graphics2.Graphics) { + public function render(g: kha.graphics2.Graphics) { if (UINodes.inst.defaultWindowW == 0) UINodes.inst.defaultWindowW = Std.int(iron.App.w() / 2); if (UINodes.inst.defaultWindowH == 0) UINodes.inst.defaultWindowH = Std.int(iron.App.h() / 2); ww = UINodes.inst.defaultWindowW; @@ -254,7 +251,7 @@ class UIView2D { g.begin(false); } - function update() { + public function update() { var mouse = Input.getMouse(); var kb = Input.getKeyboard(); diff --git a/Sources/arm/util/ParticleUtil.hx b/Sources/arm/util/ParticleUtil.hx index e89350ff..348859e9 100644 --- a/Sources/arm/util/ParticleUtil.hx +++ b/Sources/arm/util/ParticleUtil.hx @@ -25,7 +25,6 @@ class ParticleUtil { name: "Particles", type: 0, loop: false, - render_emitter: false, count: 1000, frame_start: 0, frame_end: 1000,