Place decal layer to picked location

This commit is contained in:
luboslenco
2020-12-15 13:56:38 +01:00
parent d884048f76
commit da99070786
9 changed files with 161 additions and 58 deletions
@@ -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
View File
@@ -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;
+7
View File
@@ -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;
+3 -1
View File
@@ -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();
+21 -9
View File
@@ -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;');
}
}
}
}
+2 -1
View File
@@ -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');
+1 -1
View File
@@ -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;
+80 -45
View File
@@ -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;
}
}
}
}
+24
View File
@@ -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;
}
}