Place decal layer to picked location
This commit is contained in:
@@ -487,6 +487,27 @@ float ltcEvaluate(vec3 N, vec3 V, float dotNV, vec3 P, mat3 Minv, vec3 points0,
|
||||
if (n == 5) sum += integrateEdge(L4, L0);
|
||||
return max(0.0, -sum);
|
||||
}
|
||||
";
|
||||
|
||||
public static var str_get_pos_from_depth = "
|
||||
vec3 get_pos_from_depth(vec2 uv, mat4 invVP) {
|
||||
#if defined(HLSL) || defined(METAL) || defined(SPIRV)
|
||||
float depth = textureLod(gbufferD, vec2(uv.x, 1.0 - uv.y), 0.0).r;
|
||||
#else
|
||||
float depth = textureLod(gbufferD, uv, 0.0).r;
|
||||
#endif
|
||||
vec4 wpos = vec4(uv * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0);
|
||||
wpos = mul(wpos, invVP);
|
||||
return wpos.xyz / wpos.w;
|
||||
}
|
||||
";
|
||||
|
||||
public static var str_get_nor_from_depth = "
|
||||
vec3 get_nor_from_depth(vec3 p0, vec2 uv, mat4 invVP, vec2 texStep) {
|
||||
vec3 p1 = get_pos_from_depth(uv + vec2(texStep.x * 4.0, 0.0), invVP);
|
||||
vec3 p2 = get_pos_from_depth(uv + vec2(0.0, texStep.y * 4.0), invVP);
|
||||
return normalize(cross(p2 - p0, p1 - p0));
|
||||
}
|
||||
";
|
||||
|
||||
}
|
||||
|
||||
+2
-1
@@ -391,7 +391,8 @@ class App {
|
||||
// Material dragged onto viewport or layers tab
|
||||
if (inViewport || inLayers || in2dView) {
|
||||
var uvType = Input.getKeyboard().down("control") ? UVProject : UVMap;
|
||||
Layers.createFillLayer(uvType);
|
||||
var decalMat = uvType == UVProject ? RenderUtil.getDecalMat() : null;
|
||||
Layers.createFillLayer(uvType, decalMat);
|
||||
}
|
||||
else if (inNodes) {
|
||||
var index = 0;
|
||||
|
||||
@@ -71,6 +71,13 @@ class Context {
|
||||
public static var uvyPicked = 0.0;
|
||||
public static var pickerSelectMaterial = true;
|
||||
public static var pickerMaskHandle = new Handle();
|
||||
public static var pickPosNor = false;
|
||||
public static var posXPicked = 0.0;
|
||||
public static var posYPicked = 0.0;
|
||||
public static var posZPicked = 0.0;
|
||||
public static var norXPicked = 0.0;
|
||||
public static var norYPicked = 0.0;
|
||||
public static var norZPicked = 0.0;
|
||||
|
||||
public static var defaultEnvmap: Image = null;
|
||||
public static var defaultIrradiance: kha.arrays.Float32Array = null;
|
||||
|
||||
@@ -10,6 +10,7 @@ import kha.graphics4.VertexData;
|
||||
import kha.graphics4.BlendingFactor;
|
||||
import kha.graphics4.CompareMode;
|
||||
import iron.RenderPath;
|
||||
import iron.math.Mat4;
|
||||
import arm.ui.UISidebar;
|
||||
import arm.ui.UIHeader;
|
||||
import arm.data.LayerSlot;
|
||||
@@ -614,11 +615,12 @@ class Layers {
|
||||
return l;
|
||||
}
|
||||
|
||||
public static function createFillLayer(uvType = UVMap) {
|
||||
public static function createFillLayer(uvType = UVMap, decalMat: Mat4 = null) {
|
||||
function _init() {
|
||||
var l = newLayer(false);
|
||||
History.newLayer();
|
||||
l.uvType = uvType;
|
||||
if (decalMat != null) l.decalMat = decalMat;
|
||||
l.objectMask = Context.layerFilter;
|
||||
History.toFillLayer();
|
||||
l.toFillLayer();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package arm.node;
|
||||
|
||||
import arm.shader.ShaderFunctions;
|
||||
import arm.shader.NodeShader;
|
||||
import arm.Enums;
|
||||
|
||||
@@ -28,15 +29,26 @@ class MakeColorIdPicker {
|
||||
frag.write('fragColor = vec4(idcol, 1.0);');
|
||||
}
|
||||
else if (Context.tool == ToolPicker) {
|
||||
frag.add_out('vec4 fragColor[3]');
|
||||
frag.add_uniform('sampler2D texpaint');
|
||||
frag.add_uniform('sampler2D texpaint_nor');
|
||||
frag.add_uniform('sampler2D texpaint_pack');
|
||||
frag.write('fragColor[0] = textureLod(texpaint, texCoordInp, 0.0);');
|
||||
frag.write('fragColor[1] = textureLod(texpaint_nor, texCoordInp, 0.0);');
|
||||
frag.write('fragColor[2] = textureLod(texpaint_pack, texCoordInp, 0.0);');
|
||||
frag.write('fragColor[0].a = texCoordInp.x;');
|
||||
frag.write('fragColor[2].a = texCoordInp.y;');
|
||||
if (Context.pickPosNor) {
|
||||
frag.add_out('vec4 fragColor[2]');
|
||||
frag.add_uniform('sampler2D gbufferD');
|
||||
frag.add_uniform('mat4 invVP', '_inverseViewProjectionMatrix');
|
||||
frag.add_function(ShaderFunctions.str_get_pos_from_depth);
|
||||
frag.add_function(ShaderFunctions.str_get_nor_from_depth);
|
||||
frag.write('fragColor[0] = vec4(get_pos_from_depth(vec2(inpLocal.x, 1.0 - inpLocal.y), invVP), 0.0);');
|
||||
frag.write('fragColor[1] = vec4(get_nor_from_depth(fragColor[0].rgb, vec2(inpLocal.x, 1.0 - inpLocal.y), invVP, vec2(1.0, 1.0) / gbufferSize), 0.0);');
|
||||
}
|
||||
else {
|
||||
frag.add_out('vec4 fragColor[3]');
|
||||
frag.add_uniform('sampler2D texpaint');
|
||||
frag.add_uniform('sampler2D texpaint_nor');
|
||||
frag.add_uniform('sampler2D texpaint_pack');
|
||||
frag.write('fragColor[0] = textureLod(texpaint, texCoordInp, 0.0);');
|
||||
frag.write('fragColor[1] = textureLod(texpaint_nor, texCoordInp, 0.0);');
|
||||
frag.write('fragColor[2] = textureLod(texpaint_pack, texCoordInp, 0.0);');
|
||||
frag.write('fragColor[0].a = texCoordInp.x;');
|
||||
frag.write('fragColor[2].a = texCoordInp.y;');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,8 @@ class MakeTexcoord {
|
||||
|
||||
frag.n = true;
|
||||
frag.add_uniform('vec3 decalLayerNor', '_decalLayerNor');
|
||||
frag.write('if (abs(dot(n, decalLayerNor) - 1.0) > 0.2) discard;');
|
||||
var angle = Context.brushAngleRejectDot;
|
||||
frag.write('if (abs(dot(n, decalLayerNor) - 1.0) > $angle) discard;');
|
||||
|
||||
frag.wposition = true;
|
||||
frag.add_uniform('vec3 decalLayerLoc', '_decalLayerLoc');
|
||||
|
||||
@@ -42,7 +42,7 @@ class LineDraw {
|
||||
|
||||
public static function render(g4: kha.graphics4.Graphics) {
|
||||
|
||||
var hide = Operator.shortcut(Config.keymap.stencil_hide, ShortcutDown);
|
||||
var hide = Operator.shortcut(Config.keymap.stencil_hide, ShortcutDown) || iron.system.Input.getKeyboard().down("control");
|
||||
var isPaint = UIHeader.inst.worktab.position == SpacePaint;
|
||||
var isDecal = isPaint && Context.layer.fill_layer != null && Context.layer.uvType == UVProject;
|
||||
if (!isDecal || hide) return;
|
||||
|
||||
@@ -86,6 +86,22 @@ class RenderPathPaint {
|
||||
t.format = "RGBA32";
|
||||
path.createRenderTarget(t);
|
||||
}
|
||||
{
|
||||
var t = new RenderTargetRaw();
|
||||
t.name = "texpaint_posnor_picker0";
|
||||
t.width = 1;
|
||||
t.height = 1;
|
||||
t.format = "RGBA128";
|
||||
path.createRenderTarget(t);
|
||||
}
|
||||
{
|
||||
var t = new RenderTargetRaw();
|
||||
t.name = "texpaint_posnor_picker1";
|
||||
t.width = 1;
|
||||
t.height = 1;
|
||||
t.format = "RGBA128";
|
||||
path.createRenderTarget(t);
|
||||
}
|
||||
|
||||
path.loadShader("shader_datas/copy_mrt3_pass/copy_mrt3_pass");
|
||||
path.loadShader("shader_datas/dilate_pass/dilate_pass");
|
||||
@@ -125,52 +141,71 @@ class RenderPathPaint {
|
||||
UIHeader.inst.headerHandle.redraws = 2;
|
||||
}
|
||||
else if (Context.tool == ToolPicker) {
|
||||
#if kha_metal
|
||||
//path.setTarget("texpaint_picker");
|
||||
//path.clearTarget(0xff000000);
|
||||
//path.setTarget("texpaint_nor_picker");
|
||||
//path.clearTarget(0xff000000);
|
||||
//path.setTarget("texpaint_pack_picker");
|
||||
//path.clearTarget(0xff000000);
|
||||
path.setTarget("texpaint_picker", ["texpaint_nor_picker", "texpaint_pack_picker"]);
|
||||
#else
|
||||
path.setTarget("texpaint_picker", ["texpaint_nor_picker", "texpaint_pack_picker"]);
|
||||
//path.clearTarget(0xff000000);
|
||||
#end
|
||||
path.bindTarget("gbuffer2", "gbuffer2");
|
||||
tid = Context.layer.id;
|
||||
path.bindTarget("texpaint" + tid, "texpaint");
|
||||
path.bindTarget("texpaint_nor" + tid, "texpaint_nor");
|
||||
path.bindTarget("texpaint_pack" + tid, "texpaint_pack");
|
||||
path.drawMeshes("paint");
|
||||
UIHeader.inst.headerHandle.redraws = 2;
|
||||
if (Context.pickPosNor) {
|
||||
path.setTarget("texpaint_posnor_picker0", ["texpaint_posnor_picker1"]);
|
||||
path.bindTarget("gbuffer2", "gbuffer2");
|
||||
path.bindTarget("_main", "gbufferD");
|
||||
path.drawMeshes("paint");
|
||||
var texpaint_posnor_picker0 = path.renderTargets.get("texpaint_posnor_picker0").image;
|
||||
var texpaint_posnor_picker1 = path.renderTargets.get("texpaint_posnor_picker1").image;
|
||||
var a = texpaint_posnor_picker0.getPixels();
|
||||
var b = texpaint_posnor_picker1.getPixels();
|
||||
Context.posXPicked = a.getFloat(0);
|
||||
Context.posYPicked = a.getFloat(4);
|
||||
Context.posZPicked = a.getFloat(8);
|
||||
Context.norXPicked = b.getFloat(0);
|
||||
Context.norYPicked = b.getFloat(4);
|
||||
Context.norZPicked = b.getFloat(8);
|
||||
}
|
||||
else {
|
||||
#if kha_metal
|
||||
//path.setTarget("texpaint_picker");
|
||||
//path.clearTarget(0xff000000);
|
||||
//path.setTarget("texpaint_nor_picker");
|
||||
//path.clearTarget(0xff000000);
|
||||
//path.setTarget("texpaint_pack_picker");
|
||||
//path.clearTarget(0xff000000);
|
||||
path.setTarget("texpaint_picker", ["texpaint_nor_picker", "texpaint_pack_picker"]);
|
||||
#else
|
||||
path.setTarget("texpaint_picker", ["texpaint_nor_picker", "texpaint_pack_picker"]);
|
||||
//path.clearTarget(0xff000000);
|
||||
#end
|
||||
path.bindTarget("gbuffer2", "gbuffer2");
|
||||
tid = Context.layer.id;
|
||||
path.bindTarget("texpaint" + tid, "texpaint");
|
||||
path.bindTarget("texpaint_nor" + tid, "texpaint_nor");
|
||||
path.bindTarget("texpaint_pack" + tid, "texpaint_pack");
|
||||
path.drawMeshes("paint");
|
||||
UIHeader.inst.headerHandle.redraws = 2;
|
||||
|
||||
var texpaint_picker = path.renderTargets.get("texpaint_picker").image;
|
||||
var texpaint_nor_picker = path.renderTargets.get("texpaint_nor_picker").image;
|
||||
var texpaint_pack_picker = path.renderTargets.get("texpaint_pack_picker").image;
|
||||
var a = texpaint_picker.getPixels();
|
||||
var b = texpaint_nor_picker.getPixels();
|
||||
var c = texpaint_pack_picker.getPixels();
|
||||
// Picked surface values
|
||||
Context.baseRPicked = a.get(0) / 255;
|
||||
Context.baseGPicked = a.get(1) / 255;
|
||||
Context.baseBPicked = a.get(2) / 255;
|
||||
Context.uvxPicked = a.get(3) / 255;
|
||||
Context.normalRPicked = b.get(0) / 255;
|
||||
Context.normalGPicked = b.get(1) / 255;
|
||||
Context.normalBPicked = b.get(2) / 255;
|
||||
Context.uvyPicked = c.get(3) / 255;
|
||||
Context.occlusionPicked = c.get(0) / 255;
|
||||
Context.roughnessPicked = c.get(1) / 255;
|
||||
Context.metallicPicked = c.get(2) / 255;
|
||||
// Pick material
|
||||
if (Context.pickerSelectMaterial) {
|
||||
var matid = b.get(3);
|
||||
for (m in Project.materials) {
|
||||
if (m.id == matid) {
|
||||
Context.setMaterial(m);
|
||||
Context.materialIdPicked = matid;
|
||||
break;
|
||||
var texpaint_picker = path.renderTargets.get("texpaint_picker").image;
|
||||
var texpaint_nor_picker = path.renderTargets.get("texpaint_nor_picker").image;
|
||||
var texpaint_pack_picker = path.renderTargets.get("texpaint_pack_picker").image;
|
||||
var a = texpaint_picker.getPixels();
|
||||
var b = texpaint_nor_picker.getPixels();
|
||||
var c = texpaint_pack_picker.getPixels();
|
||||
|
||||
// Picked surface values
|
||||
Context.baseRPicked = a.get(0) / 255;
|
||||
Context.baseGPicked = a.get(1) / 255;
|
||||
Context.baseBPicked = a.get(2) / 255;
|
||||
Context.uvxPicked = a.get(3) / 255;
|
||||
Context.normalRPicked = b.get(0) / 255;
|
||||
Context.normalGPicked = b.get(1) / 255;
|
||||
Context.normalBPicked = b.get(2) / 255;
|
||||
Context.uvyPicked = c.get(3) / 255;
|
||||
Context.occlusionPicked = c.get(0) / 255;
|
||||
Context.roughnessPicked = c.get(1) / 255;
|
||||
Context.metallicPicked = c.get(2) / 255;
|
||||
// Pick material
|
||||
if (Context.pickerSelectMaterial) {
|
||||
var matid = b.get(3);
|
||||
for (m in Project.materials) {
|
||||
if (m.id == matid) {
|
||||
Context.setMaterial(m);
|
||||
Context.materialIdPicked = matid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import iron.RenderPath;
|
||||
import iron.object.MeshObject;
|
||||
import iron.math.Mat4;
|
||||
import iron.math.Vec4;
|
||||
import iron.math.Quat;
|
||||
import iron.data.MaterialData;
|
||||
import iron.data.ShaderData;
|
||||
import arm.ui.UIHeader;
|
||||
@@ -462,4 +463,27 @@ class RenderUtil {
|
||||
Context.paintObject.transform.scaleWorld = _scaleWorld;
|
||||
Context.paintObject.transform.buildMatrix();
|
||||
}
|
||||
|
||||
public static function pickPositionAndNormal() {
|
||||
Context.pickPosNor = true;
|
||||
Context.pdirty = 1;
|
||||
var _tool = Context.tool;
|
||||
Context.tool = ToolPicker;
|
||||
MakeMaterial.parsePaintMaterial();
|
||||
arm.render.RenderPathPaint.commandsPaint(false);
|
||||
Context.tool = _tool;
|
||||
Context.pickPosNor = false;
|
||||
MakeMaterial.parsePaintMaterial();
|
||||
Context.pdirty = 0;
|
||||
}
|
||||
|
||||
public static function getDecalMat(): Mat4 {
|
||||
RenderUtil.pickPositionAndNormal();
|
||||
var decalMat = Mat4.identity();
|
||||
var loc = new Vec4(Context.posXPicked, Context.posYPicked, Context.posZPicked);
|
||||
var rot = new Quat().fromTo(new Vec4(0.0, 0.0, -1.0), new Vec4(Context.norXPicked, Context.norYPicked, Context.norZPicked));
|
||||
var scale = new Vec4(0.5, 0.5, 0.5);
|
||||
decalMat.compose(loc, rot, scale);
|
||||
return decalMat;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user