Brush mask

This commit is contained in:
luboslenco
2019-08-06 14:40:29 +02:00
parent e16f8b7964
commit a16722cd72
8 changed files with 113 additions and 67 deletions
+3 -1
View File
@@ -98,7 +98,9 @@ class Logic {
for (i in 0...5) {
for (b in node.buttons) {
if (b.name == 'property' + i) {
Reflect.setProperty(v, b.name, b.data[b.default_value]);
var arrayData = Std.is(b.data, Array);
var texts = arrayData ? b.data : Nodes.getEnumTexts();
Reflect.setProperty(v, b.name, texts[b.default_value]);
}
}
}
+16 -1
View File
@@ -208,7 +208,7 @@ class MaterialBuilder {
// Non-continuous
// frag.write('float dist = distance(wposition, winp.xyz);');
}
else { // !paint3d
else { // !brush3d
frag.write('vec2 binp = inp.xy * 2.0 - 1.0;');
frag.write('binp.x *= aspectRatio;');
frag.write('binp = binp * 0.5 + 0.5;');
@@ -468,6 +468,21 @@ class MaterialBuilder {
frag.write('opacity *= textureLod(textexttool, texCoord, 0.0).r;');
}
if (UITrait.inst.brushMaskImage != null && Context.tool == ToolBrush) {
frag.add_uniform('sampler2D texbrushmask', '_texbrushmask');
frag.write('vec2 binp_mask = inp.xy * 2.0 - 1.0;');
frag.write('binp_mask.x *= aspectRatio;');
frag.write('binp_mask = binp_mask * 0.5 + 0.5;');
frag.write('vec2 pa_mask = bsp.xy - binp_mask.xy;');
frag.write('pa_mask /= brushRadius;');
if (UITrait.inst.brush3d) {
frag.add_uniform('vec3 eye', '_cameraPosition');
frag.write('pa_mask *= distance(eye, winp) / 1.5;');
}
frag.write('pa_mask = pa_mask.xy * 0.5 + 0.5;');
frag.write('opacity *= textureLod(texbrushmask, pa_mask, 0).r;');
}
if (Context.tool == ToolParticle) { // particle mask
frag.add_uniform('sampler2D texparticle', '_texparticle');
#if (kha_opengl || kha_webgl)
+54 -53
View File
@@ -28,58 +28,58 @@ class NodesBrush {
],
buttons: []
},
{
id: 0,
name: "Brush Output",
type: "BrushOutputNode",
x: 0,
y: 0,
color: 0xff4982a0,
inputs: [
{
id: 0,
node_id: 0,
name: "Position",
type: "VECTOR",
color: 0xff63c763,
default_value: [0.0, 0.0, 0.0]
},
{
id: 0,
node_id: 0,
name: "Radius",
type: "VALUE",
color: 0xffa1a1a1,
default_value: 1.0
},
{
id: 0,
node_id: 0,
name: "Opacity",
type: "VALUE",
color: 0xffa1a1a1,
default_value: 1.0
},
{
id: 0,
node_id: 0,
name: "Hardness",
type: "VALUE",
color: 0xffa1a1a1,
default_value: 1.0
},
{
id: 0,
node_id: 0,
name: "UV Scale",
type: "VALUE",
color: 0xffa1a1a1,
default_value: 1.0
}
],
outputs: [],
buttons: []
},
// {
// id: 0,
// name: "Brush Output",
// type: "BrushOutputNode",
// x: 0,
// y: 0,
// color: 0xff4982a0,
// inputs: [
// {
// id: 0,
// node_id: 0,
// name: "Position",
// type: "VECTOR",
// color: 0xff63c763,
// default_value: [0.0, 0.0, 0.0]
// },
// {
// id: 0,
// node_id: 0,
// name: "Radius",
// type: "VALUE",
// color: 0xffa1a1a1,
// default_value: 1.0
// },
// {
// id: 0,
// node_id: 0,
// name: "Opacity",
// type: "VALUE",
// color: 0xffa1a1a1,
// default_value: 1.0
// },
// {
// id: 0,
// node_id: 0,
// name: "Hardness",
// type: "VALUE",
// color: 0xffa1a1a1,
// default_value: 1.0
// },
// {
// id: 0,
// node_id: 0,
// name: "UV Scale",
// type: "VALUE",
// color: 0xffa1a1a1,
// default_value: 1.0
// }
// ],
// outputs: [],
// buttons: []
// },
{
id: 0,
name: "Value",
@@ -378,7 +378,8 @@ class NodesBrush {
],
buttons: [
{
name: "File",
// name: "File",
name: "property0",
type: "ENUM",
default_value: 0,
data: ""
+17 -4
View File
@@ -9,13 +9,28 @@ class BrushOutputNode extends LogicNode {
public function new(tree:LogicTree) {
super(tree);
UITrait.inst.notifyOnBrush(run);
UITrait.inst.onBrush = run;
}
override function run(from:Int) {
UITrait.inst.paintVec = inputs[0].get();
UITrait.inst.brushNodesRadius = inputs[1].get();
UITrait.inst.brushNodesOpacity = inputs[2].get();
var opac:Dynamic = inputs[2].get(); // Float or texture name
if (opac == null) opac = 1.0;
var lastMask = UITrait.inst.brushMaskImage;
if (Std.is(opac, String)) {
UITrait.inst.brushNodesOpacity = 1.0;
var index = Project.assetNames.indexOf(opac);
var asset = Project.assets[index];
UITrait.inst.brushMaskImage = UITrait.inst.getImage(asset);
}
else {
UITrait.inst.brushNodesOpacity = opac;
UITrait.inst.brushMaskImage = null;
}
if (lastMask != UITrait.inst.brushMaskImage) {
MaterialParser.parsePaintMaterial();
}
UITrait.inst.brushNodesHardness = inputs[3].get();
UITrait.inst.brushNodesScale = inputs[4].get();
@@ -67,7 +82,5 @@ class BrushOutputNode extends LogicNode {
Context.rdirty = 2;
}
}
runOutput(0);
}
}
+15
View File
@@ -0,0 +1,15 @@
package arm.nodes.brush;
@:keep
class TEX_IMAGE extends LogicNode {
public var property0:String; // file
public function new(tree:LogicTree) {
super(tree);
}
override function get(from:Int):Dynamic {
return property0;
}
}
+3
View File
@@ -121,6 +121,9 @@ class Uniforms {
else if (link == "_texdecalmask") { // Opacity map for decal
return UITrait.inst.decalMaskImage;
}
else if (link == "_texbrushmask") {
return UITrait.inst.brushMaskImage;
}
else if (link == "_texpaint_undo") {
var i = History.undoI - 1 < 0 ? Config.raw.undo_steps - 1 : History.undoI - 1;
return RenderPath.active.renderTargets.get("texpaint_undo" + i).image;
+2 -1
View File
@@ -68,6 +68,7 @@ class UINodes {
inst = this;
Nodes.excludeRemove.push("OUTPUT_MATERIAL_PBR");
Nodes.excludeRemove.push("BrushOutputNode");
// Cycles.arm_export_tangents = false;
Data.getBlob('defaults/default_material.json', function(b1:Blob) {
@@ -418,7 +419,7 @@ class UINodes {
var canvas = canvasType == 0 ? canvas : canvasBrush;
var numNodes = list[menuCategory].length;
var ph = numNodes * 20 * ui.SCALE;
var ph = numNodes * 22 * ui.SCALE;
var py = popupY;
g.color = ui.t.WINDOW_BG_COL;
var menuw = Std.int(ew * 1.6);
+3 -7
View File
@@ -124,8 +124,7 @@ class UITrait {
public var layerFilter = 0;
var onBrush:Array<Int->Void> = [];
public var onBrush:Int->Void = null;
public var paintVec = new Vec4();
public var lastPaintX = -1.0;
public var lastPaintY = -1.0;
@@ -148,6 +147,7 @@ class UITrait {
public var brushNodesRadius = 1.0;
public var brushNodesOpacity = 1.0;
public var brushMaskImage:Image = null;
public var brushNodesScale = 1.0;
public var brushNodesHardness = 1.0;
@@ -229,10 +229,6 @@ class UITrait {
public var worktab = Id.handle({position: 0});
public var toolNames = ["Brush", "Eraser", "Fill", "Decal", "Text", "Clone", "Blur", "Particle", "Bake", "ColorID", "Picker"];
public function notifyOnBrush(f:Int->Void) {
onBrush.push(f);
}
public function new() {
inst = this;
@@ -621,7 +617,7 @@ class UITrait {
}
}
brushTime += Time.delta;
for (f in onBrush) f(0);
if (onBrush != null) onBrush(0);
}
}