diff --git a/Shaders/painter/glsl/layer_merge.frag.glsl b/Shaders/painter/glsl/layer_merge.frag.glsl index ba7d9b05..531f60b1 100644 --- a/Shaders/painter/glsl/layer_merge.frag.glsl +++ b/Shaders/painter/glsl/layer_merge.frag.glsl @@ -1,14 +1,12 @@ #version 330 uniform sampler2D tex0; uniform sampler2D tex1; -uniform sampler2D tex2; +uniform sampler2D texmask; uniform sampler2D texa; -uniform sampler2D texb; -uniform sampler2D texc; uniform float opac; uniform int blending; in vec2 texCoord; -out vec4 FragColor[3]; +out vec4 FragColor; vec3 hsv_to_rgb(const vec3 c) { const vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); @@ -24,67 +22,66 @@ vec3 rgb_to_hsv(const vec3 c) { } void main() { vec4 col0 = textureLod(tex0, texCoord, 0); - vec4 col1 = textureLod(tex1, texCoord, 0); - vec4 col2 = textureLod(tex2, texCoord, 0); vec4 cola = textureLod(texa, texCoord, 0); - vec4 colb = textureLod(texb, texCoord, 0); - vec4 colc = textureLod(texc, texCoord, 0); float str = col0.a * opac; - if (blending == 0) { // Mix - FragColor[0] = vec4(mix(cola.rgb, col0.rgb, str), max(col0.a, cola.a)); + str *= textureLod(texmask, texCoord, 0).r; + if (blending == -1) { // Merging _nor and _pack + vec4 col1 = textureLod(tex1, texCoord, 0); + FragColor = vec4(mix(cola, col1, str)); + } + else if (blending == 0) { // Mix + FragColor = vec4(mix(cola.rgb, col0.rgb, str), max(col0.a, cola.a)); } else if (blending == 1) { // Darken - FragColor[0] = vec4(mix(cola.rgb, min(cola.rgb, col0.rgb), str), max(col0.a, cola.a)); + FragColor = vec4(mix(cola.rgb, min(cola.rgb, col0.rgb), str), max(col0.a, cola.a)); } else if (blending == 2) { // Multiply - FragColor[0] = vec4(mix(cola.rgb, cola.rgb * col0.rgb, str), max(col0.a, cola.a)); + FragColor = vec4(mix(cola.rgb, cola.rgb * col0.rgb, str), max(col0.a, cola.a)); } else if (blending == 3) { // Burn - FragColor[0] = vec4(mix(cola.rgb, vec3(1.0, 1.0, 1.0) - (vec3(1.0, 1.0, 1.0) - cola.rgb) / col0.rgb, str), max(col0.a, cola.a)); + FragColor = vec4(mix(cola.rgb, vec3(1.0, 1.0, 1.0) - (vec3(1.0, 1.0, 1.0) - cola.rgb) / col0.rgb, str), max(col0.a, cola.a)); } else if (blending == 4) { // Lighten - FragColor[0] = vec4(max(cola.rgb, col0.rgb * str), max(col0.a, cola.a)); + FragColor = vec4(max(cola.rgb, col0.rgb * str), max(col0.a, cola.a)); } else if (blending == 5) { // Screen - FragColor[0] = vec4((vec3(1.0, 1.0, 1.0) - (vec3(1.0 - str, 1.0 - str, 1.0 - str) + str * (vec3(1.0, 1.0, 1.0) - col0.rgb)) * (vec3(1.0, 1.0, 1.0) - cola.rgb)), max(col0.a, cola.a)); + FragColor = vec4((vec3(1.0, 1.0, 1.0) - (vec3(1.0 - str, 1.0 - str, 1.0 - str) + str * (vec3(1.0, 1.0, 1.0) - col0.rgb)) * (vec3(1.0, 1.0, 1.0) - cola.rgb)), max(col0.a, cola.a)); } else if (blending == 6) { // Dodge - FragColor[0] = vec4(mix(cola.rgb, cola.rgb / (vec3(1.0, 1.0, 1.0) - col0.rgb), str), max(col0.a, cola.a)); + FragColor = vec4(mix(cola.rgb, cola.rgb / (vec3(1.0, 1.0, 1.0) - col0.rgb), str), max(col0.a, cola.a)); } else if (blending == 7) { // Add - FragColor[0] = vec4(mix(cola.rgb, cola.rgb + col0.rgb, str), max(col0.a, cola.a)); + FragColor = vec4(mix(cola.rgb, cola.rgb + col0.rgb, str), max(col0.a, cola.a)); } else if (blending == 8) { // Overlay - //FragColor[0] = vec4(mix(cola.rgb, (cola.rgb < vec3(0.5, 0.5, 0.5) ? vec3(2.0, 2.0, 2.0) * cola.rgb * col0.rgb : vec3(1.0, 1.0, 1.0) - vec3(2.0, 2.0, 2.0) * (vec3(1.0, 1.0, 1.0) - col0.rgb) * (vec3(1.0, 1.0, 1.0) - cola.rgb)), str), max(col0.a, cola.a)); // TODO - FragColor[0] = vec4(mix(cola.rgb, col0.rgb, str), max(col0.a, cola.a)); + //FragColor = vec4(mix(cola.rgb, (cola.rgb < vec3(0.5, 0.5, 0.5) ? vec3(2.0, 2.0, 2.0) * cola.rgb * col0.rgb : vec3(1.0, 1.0, 1.0) - vec3(2.0, 2.0, 2.0) * (vec3(1.0, 1.0, 1.0) - col0.rgb) * (vec3(1.0, 1.0, 1.0) - cola.rgb)), str), max(col0.a, cola.a)); // TODO + FragColor = vec4(mix(cola.rgb, col0.rgb, str), max(col0.a, cola.a)); } else if (blending == 9) { // Soft Light - FragColor[0] = vec4(((1.0 - str) * cola.rgb + str * ((vec3(1.0, 1.0, 1.0) - cola.rgb) * col0.rgb * cola.rgb + cola.rgb * (vec3(1.0, 1.0, 1.0) - (vec3(1.0, 1.0, 1.0) - col0.rgb) * (vec3(1.0, 1.0, 1.0) - cola.rgb)))), max(col0.a, cola.a)); + FragColor = vec4(((1.0 - str) * cola.rgb + str * ((vec3(1.0, 1.0, 1.0) - cola.rgb) * col0.rgb * cola.rgb + cola.rgb * (vec3(1.0, 1.0, 1.0) - (vec3(1.0, 1.0, 1.0) - col0.rgb) * (vec3(1.0, 1.0, 1.0) - cola.rgb)))), max(col0.a, cola.a)); } else if (blending == 10) { // Linear Light - FragColor[0] = vec4((cola.rgb + str * (vec3(2.0, 2.0, 2.0) * (col0.rgb - vec3(0.5, 0.5, 0.5)))), max(col0.a, cola.a)); + FragColor = vec4((cola.rgb + str * (vec3(2.0, 2.0, 2.0) * (col0.rgb - vec3(0.5, 0.5, 0.5)))), max(col0.a, cola.a)); } else if (blending == 11) { // Difference - FragColor[0] = vec4(mix(cola.rgb, abs(cola.rgb - col0.rgb), str), max(col0.a, cola.a)); + FragColor = vec4(mix(cola.rgb, abs(cola.rgb - col0.rgb), str), max(col0.a, cola.a)); } else if (blending == 12) { // Subtract - FragColor[0] = vec4(mix(cola.rgb, cola.rgb - col0.rgb, str), max(col0.a, cola.a)); + FragColor = vec4(mix(cola.rgb, cola.rgb - col0.rgb, str), max(col0.a, cola.a)); } else if (blending == 13) { // Divide - FragColor[0] = vec4(vec3(1.0 - str, 1.0 - str, 1.0 - str) * cola.rgb + vec3(str, str, str) * cola.rgb / col0.rgb, max(col0.a, cola.a)); + FragColor = vec4(vec3(1.0 - str, 1.0 - str, 1.0 - str) * cola.rgb + vec3(str, str, str) * cola.rgb / col0.rgb, max(col0.a, cola.a)); } else if (blending == 14) { // Hue - FragColor[0] = vec4(mix(cola.rgb, hsv_to_rgb(vec3(rgb_to_hsv(col0.rgb).r, rgb_to_hsv(cola.rgb).g, rgb_to_hsv(cola.rgb).b)), str), max(col0.a, cola.a)); + FragColor = vec4(mix(cola.rgb, hsv_to_rgb(vec3(rgb_to_hsv(col0.rgb).r, rgb_to_hsv(cola.rgb).g, rgb_to_hsv(cola.rgb).b)), str), max(col0.a, cola.a)); } else if (blending == 15) { // Saturation - FragColor[0] = vec4(mix(cola.rgb, hsv_to_rgb(vec3(rgb_to_hsv(cola.rgb).r, rgb_to_hsv(col0.rgb).g, rgb_to_hsv(cola.rgb).b)), str), max(col0.a, cola.a)); + FragColor = vec4(mix(cola.rgb, hsv_to_rgb(vec3(rgb_to_hsv(cola.rgb).r, rgb_to_hsv(col0.rgb).g, rgb_to_hsv(cola.rgb).b)), str), max(col0.a, cola.a)); } else if (blending == 16) { // Color - FragColor[0] = vec4(mix(cola.rgb, hsv_to_rgb(vec3(rgb_to_hsv(col0.rgb).r, rgb_to_hsv(col0.rgb).g, rgb_to_hsv(cola.rgb).b)), str), max(col0.a, cola.a)); + FragColor = vec4(mix(cola.rgb, hsv_to_rgb(vec3(rgb_to_hsv(col0.rgb).r, rgb_to_hsv(col0.rgb).g, rgb_to_hsv(cola.rgb).b)), str), max(col0.a, cola.a)); } else { // Value - FragColor[0] = vec4(mix(cola.rgb, hsv_to_rgb(vec3(rgb_to_hsv(cola.rgb).r, rgb_to_hsv(cola.rgb).g, rgb_to_hsv(col0.rgb).b)), str), max(col0.a, cola.a)); + FragColor = vec4(mix(cola.rgb, hsv_to_rgb(vec3(rgb_to_hsv(cola.rgb).r, rgb_to_hsv(cola.rgb).g, rgb_to_hsv(col0.rgb).b)), str), max(col0.a, cola.a)); } - FragColor[1] = vec4(mix(colb, col1, str)); - FragColor[2] = vec4(mix(colc, col2, str)); } diff --git a/Shaders/painter/hlsl/layer_merge.frag.glsl b/Shaders/painter/hlsl/layer_merge.frag.glsl index a04948c6..e0389d52 100644 Binary files a/Shaders/painter/hlsl/layer_merge.frag.glsl and b/Shaders/painter/hlsl/layer_merge.frag.glsl differ diff --git a/Shaders/painter/hlsl/src/layer_merge.frag.hlsl b/Shaders/painter/hlsl/src/layer_merge.frag.hlsl index 5fa50bd5..a422f0a7 100644 --- a/Shaders/painter/hlsl/src/layer_merge.frag.hlsl +++ b/Shaders/painter/hlsl/src/layer_merge.frag.hlsl @@ -2,14 +2,10 @@ Texture2D tex0; SamplerState _tex0_sampler; Texture2D tex1; SamplerState _tex1_sampler; -Texture2D tex2; -SamplerState _tex2_sampler; +Texture2D texmask; +SamplerState _texmask_sampler; Texture2D texa; SamplerState _texa_sampler; -Texture2D texb; -SamplerState _texb_sampler; -Texture2D texc; -SamplerState _texc_sampler; uniform float opac; uniform int blending; float3 hsv_to_rgb(const float3 c) { @@ -25,17 +21,18 @@ float3 rgb_to_hsv(const float3 c) { float e = 1.0e-10; return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); } -struct SPIRV_Cross_Output { float4 color0 : SV_Target0; float4 color1 : SV_Target1; float4 color2 : SV_Target2; }; +struct SPIRV_Cross_Output { float4 color0 : SV_Target0; }; SPIRV_Cross_Output main(float2 texCoord : TEXCOORD0) { float4 col0 = tex0.SampleLevel(_tex0_sampler, texCoord, 0); - float4 col1 = tex1.SampleLevel(_tex1_sampler, texCoord, 0); - float4 col2 = tex2.SampleLevel(_tex2_sampler, texCoord, 0); float4 cola = texa.SampleLevel(_texa_sampler, texCoord, 0); - float4 colb = texb.SampleLevel(_texb_sampler, texCoord, 0); - float4 colc = texc.SampleLevel(_texc_sampler, texCoord, 0); float str = col0.a * opac; + str *= texmask.SampleLevel(_texmask_sampler, texCoord, 0).r; SPIRV_Cross_Output stage_output; - if (blending == 0) { // Mix + if (blending == -1) { // Merging _nor and _pack + float4 col1 = tex1.SampleLevel(_tex1_sampler, texCoord, 0); + stage_output.color0 = float4(lerp(cola, col1, str)); + } + else if (blending == 0) { // Mix stage_output.color0 = float4(lerp(cola.rgb, col0.rgb, str), max(col0.a, cola.a)); } else if (blending == 1) { // Darken @@ -89,7 +86,5 @@ SPIRV_Cross_Output main(float2 texCoord : TEXCOORD0) { else { // Value stage_output.color0 = float4(lerp(cola.rgb, hsv_to_rgb(float3(rgb_to_hsv(cola.rgb).r, rgb_to_hsv(cola.rgb).g, rgb_to_hsv(col0.rgb).b)), str), max(col0.a, cola.a)); } - stage_output.color1 = float4(lerp(colb, col1, str)); - stage_output.color2 = float4(lerp(colc, col2, str)); return stage_output; } diff --git a/Sources/arm/Layers.hx b/Sources/arm/Layers.hx index a9dd1a71..b1a8db41 100644 --- a/Sources/arm/Layers.hx +++ b/Sources/arm/Layers.hx @@ -20,26 +20,21 @@ import arm.Project; class Layers { - public static var pipe: PipelineState = null; + public static var pipeMerge: PipelineState = null; public static var pipeCopy: PipelineState; public static var pipeMask: PipelineState; public static var tex0: TextureUnit; public static var tex1: TextureUnit; - public static var tex2: TextureUnit; + public static var texmask: TextureUnit; public static var texa: TextureUnit; - public static var texb: TextureUnit; - public static var texc: TextureUnit; public static var opac: ConstantLocation; public static var blending: ConstantLocation; public static var tex0Mask: TextureUnit; public static var texaMask: TextureUnit; public static var imga: Image = null; - public static var imgb: Image = null; - public static var imgc: Image = null; public static var expa: Image = null; public static var expb: Image = null; public static var expc: Image = null; - public static var expd: Image = null; public static var pipeCursor: PipelineState; public static var cursorVP: ConstantLocation; public static var cursorInvVP: ConstantLocation; @@ -79,7 +74,7 @@ class Layers { public static function resizeLayers(g: kha.graphics4.Graphics) { var C = Config.raw; if (App.resHandle.position >= 4) { // Save memory for >=16k - C.undo_steps = 2; + C.undo_steps = 1; if (UITrait.inst.undoHandle != null) UITrait.inst.undoHandle.value = C.undo_steps; while (History.undoLayers.length > C.undo_steps) { var l = History.undoLayers.pop(); l.unload(); } } @@ -120,21 +115,19 @@ class Layers { } public static function makePipe() { - pipe = new PipelineState(); - pipe.vertexShader = Reflect.field(kha.Shaders, "layer_merge_vert"); - pipe.fragmentShader = Reflect.field(kha.Shaders, "layer_merge_frag"); + pipeMerge = new PipelineState(); + pipeMerge.vertexShader = Reflect.field(kha.Shaders, "layer_merge_vert"); + pipeMerge.fragmentShader = Reflect.field(kha.Shaders, "layer_merge_frag"); var vs = new VertexStructure(); vs.add("pos", VertexData.Float2); - pipe.inputLayout = [vs]; - pipe.compile(); - tex0 = pipe.getTextureUnit("tex0"); - tex1 = pipe.getTextureUnit("tex1"); - tex2 = pipe.getTextureUnit("tex2"); - texa = pipe.getTextureUnit("texa"); - texb = pipe.getTextureUnit("texb"); - texc = pipe.getTextureUnit("texc"); - opac = pipe.getConstantLocation("opac"); - blending = pipe.getConstantLocation("blending"); + pipeMerge.inputLayout = [vs]; + pipeMerge.compile(); + tex0 = pipeMerge.getTextureUnit("tex0"); // Always binding texpaint.a for blending + tex1 = pipeMerge.getTextureUnit("tex1"); + texmask = pipeMerge.getTextureUnit("texmask"); + texa = pipeMerge.getTextureUnit("texa"); + opac = pipeMerge.getConstantLocation("opac"); + blending = pipeMerge.getConstantLocation("blending"); pipeCopy = new PipelineState(); pipeCopy.vertexShader = Reflect.field(kha.Shaders, "layer_view_vert"); @@ -185,14 +178,8 @@ class Layers { var l = Project.layers[0]; if (imga != null && imga.width != l.texpaint.width) { RenderPath.active.renderTargets.get("temptex0").unload(); - RenderPath.active.renderTargets.get("temptex1").unload(); - RenderPath.active.renderTargets.get("temptex2").unload(); RenderPath.active.renderTargets.remove("temptex0"); - RenderPath.active.renderTargets.remove("temptex1"); - RenderPath.active.renderTargets.remove("temptex2"); imga = null; - imgb = null; - imgc = null; } if (imga == null) { { @@ -204,24 +191,6 @@ class Layers { var rt = RenderPath.active.createRenderTarget(t); imga = rt.image; } - { - var t = new RenderTargetRaw(); - t.name = "temptex1"; - t.width = l.texpaint.width; - t.height = l.texpaint.height; - t.format = "RGBA32"; - var rt = RenderPath.active.createRenderTarget(t); - imgb = rt.image; - } - { - var t = new RenderTargetRaw(); - t.name = "temptex2"; - t.width = l.texpaint.width; - t.height = l.texpaint.height; - t.format = "RGBA32"; - var rt = RenderPath.active.createRenderTarget(t); - imgc = rt.image; - } } } @@ -231,22 +200,19 @@ class Layers { expa.unload(); expb.unload(); expc.unload(); - expd.unload(); expa = null; expb = null; expc = null; - expd = null; } if (expa == null) { expa = Image.createRenderTarget(l.texpaint.width, l.texpaint.height); expb = Image.createRenderTarget(l.texpaint.width, l.texpaint.height); expc = Image.createRenderTarget(l.texpaint.width, l.texpaint.height); - expd = Image.createRenderTarget(l.texpaint.width, l.texpaint.height); } } public static function mergeSelectedLayer(g: kha.graphics4.Graphics) { - if (pipe == null) makePipe(); + if (pipeMerge == null) makePipe(); var l0 = Project.layers[0]; var l1 = Context.layer; @@ -266,30 +232,21 @@ class Layers { l1.applyMask(); } - // Copy layer0 to temp - imga.g2.begin(false); + // Merge into layer below + if (iron.data.ConstData.screenAlignedVB == null) iron.data.ConstData.createScreenAlignedData(); + + imga.g2.begin(false); // Copy to temp imga.g2.pipeline = pipeCopy; imga.g2.drawImage(l0.texpaint, 0, 0); imga.g2.end(); - imgb.g2.begin(false); - imgb.g2.pipeline = pipeCopy; - imgb.g2.drawImage(l0.texpaint_nor, 0, 0); - imgb.g2.end(); - imgc.g2.begin(false); - imgc.g2.pipeline = pipeCopy; - imgc.g2.drawImage(l0.texpaint_pack, 0, 0); - imgc.g2.end(); - // Merge into layer0 - if (iron.data.ConstData.screenAlignedVB == null) iron.data.ConstData.createScreenAlignedData(); - l0.texpaint.g4.begin([l0.texpaint_nor, l0.texpaint_pack]); - l0.texpaint.g4.setPipeline(pipe); + l0.texpaint.g4.begin(); + l0.texpaint.g4.setPipeline(pipeMerge); l0.texpaint.g4.setTexture(tex0, l1.texpaint); - l0.texpaint.g4.setTexture(tex1, l1.texpaint_nor); - l0.texpaint.g4.setTexture(tex2, l1.texpaint_pack); + var empty = RenderPath.active.renderTargets.get("empty_white").image; + l0.texpaint.g4.setTexture(tex1, empty); + l0.texpaint.g4.setTexture(texmask, empty); l0.texpaint.g4.setTexture(texa, imga); - l0.texpaint.g4.setTexture(texb, imgb); - l0.texpaint.g4.setTexture(texc, imgc); l0.texpaint.g4.setFloat(opac, l1.maskOpacity); l0.texpaint.g4.setInt(blending, l1.blending); l0.texpaint.g4.setVertexBuffer(iron.data.ConstData.screenAlignedVB); @@ -297,6 +254,42 @@ class Layers { l0.texpaint.g4.drawIndexedVertices(); l0.texpaint.g4.end(); + imga.g2.begin(false); + imga.g2.pipeline = pipeCopy; + imga.g2.drawImage(l0.texpaint_nor, 0, 0); + imga.g2.end(); + + l0.texpaint_nor.g4.begin(); + l0.texpaint_nor.g4.setPipeline(pipeMerge); + l0.texpaint_nor.g4.setTexture(tex0, l1.texpaint); + l0.texpaint_nor.g4.setTexture(tex1, l1.texpaint_nor); + l0.texpaint_nor.g4.setTexture(texmask, empty); + l0.texpaint_nor.g4.setTexture(texa, imga); + l0.texpaint_nor.g4.setFloat(opac, l1.maskOpacity); + l0.texpaint.g4.setInt(blending, -1); + l0.texpaint_nor.g4.setVertexBuffer(iron.data.ConstData.screenAlignedVB); + l0.texpaint_nor.g4.setIndexBuffer(iron.data.ConstData.screenAlignedIB); + l0.texpaint_nor.g4.drawIndexedVertices(); + l0.texpaint_nor.g4.end(); + + imga.g2.begin(false); + imga.g2.pipeline = pipeCopy; + imga.g2.drawImage(l0.texpaint_pack, 0, 0); + imga.g2.end(); + + l0.texpaint_pack.g4.begin(); + l0.texpaint_pack.g4.setPipeline(pipeMerge); + l0.texpaint_pack.g4.setTexture(tex0, l1.texpaint); + l0.texpaint_pack.g4.setTexture(tex1, l1.texpaint_pack); + l0.texpaint_pack.g4.setTexture(texmask, empty); + l0.texpaint_pack.g4.setTexture(texa, imga); + l0.texpaint_pack.g4.setFloat(opac, l1.maskOpacity); + l0.texpaint.g4.setInt(blending, -1); + l0.texpaint_pack.g4.setVertexBuffer(iron.data.ConstData.screenAlignedVB); + l0.texpaint_pack.g4.setIndexBuffer(iron.data.ConstData.screenAlignedIB); + l0.texpaint_pack.g4.drawIndexedVertices(); + l0.texpaint_pack.g4.end(); + g.begin(); Context.layer.delete(); diff --git a/Sources/arm/data/LayerSlot.hx b/Sources/arm/data/LayerSlot.hx index 8470c2f1..d1515208 100644 --- a/Sources/arm/data/LayerSlot.hx +++ b/Sources/arm/data/LayerSlot.hx @@ -185,7 +185,7 @@ class LayerSlot { public function applyMask() { if (texpaint_mask == null) return; - if (Layers.pipe == null) Layers.makePipe(); + if (Layers.pipeMerge == null) Layers.makePipe(); Layers.makeTempImg(); // Copy layer to temp @@ -217,7 +217,7 @@ class LayerSlot { var l = new LayerSlot(); layers.insert(i, l); - if (Layers.pipe == null) Layers.makePipe(); + if (Layers.pipeMerge == null) Layers.makePipe(); l.texpaint.g2.begin(false); l.texpaint.g2.pipeline = Layers.pipeCopy; l.texpaint.g2.drawImage(texpaint, 0, 0); diff --git a/Sources/arm/io/ExportTexture.hx b/Sources/arm/io/ExportTexture.hx index 0dd24e3d..c05776fb 100644 --- a/Sources/arm/io/ExportTexture.hx +++ b/Sources/arm/io/ExportTexture.hx @@ -63,7 +63,7 @@ class ExportTexture { if (UITrait.inst.layersExport == 0 && layers.length > 1) { Layers.makeTempImg(); Layers.makeExportImg(); - if (Layers.pipe == null) Layers.makePipe(); + if (Layers.pipeMerge == null) Layers.makePipe(); if (iron.data.ConstData.screenAlignedVB == null) iron.data.ConstData.createScreenAlignedData(); // Duplicate base layer @@ -101,48 +101,59 @@ class ExportTexture { if (!Project.paintObjects[l1.objectMask - 1].name.endsWith(udimTile)) continue; } - // Apply mask - var hasMask = l1.texpaint_mask != null; - if (hasMask) { - Layers.expd.g4.begin(); - Layers.expd.g4.setPipeline(Layers.pipeMask); - Layers.expd.g4.setTexture(Layers.tex0Mask, l1.texpaint); - Layers.expd.g4.setTexture(Layers.texaMask, l1.texpaint_mask); - Layers.expd.g4.setVertexBuffer(iron.data.ConstData.screenAlignedVB); - Layers.expd.g4.setIndexBuffer(iron.data.ConstData.screenAlignedIB); - Layers.expd.g4.drawIndexedVertices(); - Layers.expd.g4.end(); - } - - // Copy layer0 to temp - Layers.imga.g2.begin(false); + // Merge into layer0 + Layers.imga.g2.begin(false); // Copy to temp Layers.imga.g2.pipeline = Layers.pipeCopy; Layers.imga.g2.drawImage(Layers.expa, 0, 0); Layers.imga.g2.end(); - Layers.imgb.g2.begin(false); - Layers.imgb.g2.pipeline = Layers.pipeCopy; - Layers.imgb.g2.drawImage(Layers.expb, 0, 0); - Layers.imgb.g2.end(); - Layers.imgc.g2.begin(false); - Layers.imgc.g2.pipeline = Layers.pipeCopy; - Layers.imgc.g2.drawImage(Layers.expc, 0, 0); - Layers.imgc.g2.end(); - - // Merge into layer0 - Layers.expa.g4.begin([Layers.expb, Layers.expc]); - Layers.expa.g4.setPipeline(Layers.pipe); - Layers.expa.g4.setTexture(Layers.tex0, hasMask ? Layers.expd : l1.texpaint); - Layers.expa.g4.setTexture(Layers.tex1, l1.texpaint_nor); - Layers.expa.g4.setTexture(Layers.tex2, l1.texpaint_pack); + Layers.expa.g4.begin(); + Layers.expa.g4.setPipeline(Layers.pipeMerge); + Layers.expa.g4.setTexture(Layers.tex0, l1.texpaint); + var empty = iron.RenderPath.active.renderTargets.get("empty_white").image; + Layers.expa.g4.setTexture(Layers.tex1, empty); + var hasMask = l1.texpaint_mask != null; + Layers.expa.g4.setTexture(Layers.texmask, hasMask ? l1.texpaint_mask : empty); Layers.expa.g4.setTexture(Layers.texa, Layers.imga); - Layers.expa.g4.setTexture(Layers.texb, Layers.imgb); - Layers.expa.g4.setTexture(Layers.texc, Layers.imgc); Layers.expa.g4.setFloat(Layers.opac, l1.maskOpacity); Layers.expa.g4.setInt(Layers.blending, l1.blending); Layers.expa.g4.setVertexBuffer(iron.data.ConstData.screenAlignedVB); Layers.expa.g4.setIndexBuffer(iron.data.ConstData.screenAlignedIB); Layers.expa.g4.drawIndexedVertices(); Layers.expa.g4.end(); + + Layers.imga.g2.begin(false); + Layers.imga.g2.pipeline = Layers.pipeCopy; + Layers.imga.g2.drawImage(Layers.expb, 0, 0); + Layers.imga.g2.end(); + Layers.expb.g4.begin(); + Layers.expb.g4.setPipeline(Layers.pipeMerge); + Layers.expb.g4.setTexture(Layers.tex0, l1.texpaint); + Layers.expb.g4.setTexture(Layers.tex1, l1.texpaint_nor); + Layers.expb.g4.setTexture(Layers.texmask, empty); + Layers.expb.g4.setTexture(Layers.texa, Layers.imga); + Layers.expb.g4.setFloat(Layers.opac, l1.maskOpacity); + Layers.expa.g4.setInt(Layers.blending, -1); + Layers.expb.g4.setVertexBuffer(iron.data.ConstData.screenAlignedVB); + Layers.expb.g4.setIndexBuffer(iron.data.ConstData.screenAlignedIB); + Layers.expb.g4.drawIndexedVertices(); + Layers.expb.g4.end(); + + Layers.imga.g2.begin(false); + Layers.imga.g2.pipeline = Layers.pipeCopy; + Layers.imga.g2.drawImage(Layers.expc, 0, 0); + Layers.imga.g2.end(); + Layers.expc.g4.begin(); + Layers.expc.g4.setPipeline(Layers.pipeMerge); + Layers.expc.g4.setTexture(Layers.tex0, l1.texpaint); + Layers.expc.g4.setTexture(Layers.tex1, l1.texpaint_pack); + Layers.expc.g4.setTexture(Layers.texmask, empty); + Layers.expc.g4.setTexture(Layers.texa, Layers.imga); + Layers.expc.g4.setFloat(Layers.opac, l1.maskOpacity); + Layers.expa.g4.setInt(Layers.blending, -1); + Layers.expc.g4.setVertexBuffer(iron.data.ConstData.screenAlignedVB); + Layers.expc.g4.setIndexBuffer(iron.data.ConstData.screenAlignedIB); + Layers.expc.g4.drawIndexedVertices(); + Layers.expc.g4.end(); } texpaint = Layers.expa; diff --git a/Sources/arm/render/RenderPathPaint.hx b/Sources/arm/render/RenderPathPaint.hx index 5e83b872..642512bb 100644 --- a/Sources/arm/render/RenderPathPaint.hx +++ b/Sources/arm/render/RenderPathPaint.hx @@ -525,7 +525,7 @@ class RenderPathPaint { public static function finishPaint() { if (Context.tool == ToolBake && !dilated && UITrait.inst.dilateRadius > 0) { - if (Layers.imga == null) Layers.makeTempImg(); + Layers.makeTempImg(); dilated = true; path.setTarget("temptex0"); path.bindTarget("texpaint0", "tex"); diff --git a/Sources/arm/ui/BoxPreferences.hx b/Sources/arm/ui/BoxPreferences.hx index db538145..bd8890b9 100644 --- a/Sources/arm/ui/BoxPreferences.hx +++ b/Sources/arm/ui/BoxPreferences.hx @@ -87,7 +87,7 @@ class BoxPreferences { } if (ui.tab(htab, "Usage")) { UITrait.inst.undoHandle = Id.handle({value: Config.raw.undo_steps}); - Config.raw.undo_steps = Std.int(ui.slider(UITrait.inst.undoHandle, "Undo Steps", 2, 64, false, 1)); + Config.raw.undo_steps = Std.int(ui.slider(UITrait.inst.undoHandle, "Undo Steps", 1, 64, false, 1)); if (UITrait.inst.undoHandle.changed) { ui.g.end(); while (History.undoLayers.length < Config.raw.undo_steps) {