Height paint

This commit is contained in:
luboslenco
2018-05-09 22:10:57 +02:00
parent 68b996f16b
commit bf513f4e68
5 changed files with 185 additions and 38 deletions
+1 -1
View File
@@ -1 +1 @@
{"nodes":[{"id":0,"name":"Material Output","type":"OUTPUT_MATERIAL_PBR","x":307,"y":192,"color":-5025958,"inputs":[{"id":0,"node_id":0,"name":"Base Color","type":"RGBA","color":-3684567,"default_value":[0.8,0.8,0.8,1]},{"id":0,"node_id":0,"name":"Opacity","type":"VALUE","color":-6184543,"default_value":1},{"id":0,"node_id":0,"name":"Occlusion","type":"VALUE","color":-6184543,"default_value":1},{"id":0,"node_id":0,"name":"Roughness","type":"VALUE","color":-6184543,"default_value":0.1},{"id":0,"node_id":0,"name":"Metallic","type":"VALUE","color":-6184543,"default_value":0},{"id":0,"node_id":0,"name":"Normal Map","type":"VECTOR","color":-10238109,"default_value":[0.5,0.5,1]}],"outputs":[],"buttons":[]},{"id":1,"name":"RGB","type":"RGB","x":72,"y":192,"color":-5025958,"inputs":[],"outputs":[{"id":1,"node_id":1,"name":"Color","type":"RGBA","color":-3684567,"default_value":[1,1,1,1]}],"buttons":[{"name":"default_value","type":"RGBA","output":0}]}],"links":[{"id":0,"from_id":1,"from_socket":0,"to_id":0,"to_socket":0}]}
{"nodes":[{"id":1,"name":"RGB","type":"RGB","x":72,"y":192,"color":-5025958,"inputs":[],"outputs":[{"id":1,"node_id":1,"name":"Color","type":"RGBA","color":-3684567,"default_value":[1,1,1,1]}],"buttons":[{"name":"default_value","type":"RGBA","output":0}]},{"id":2,"name":"Material Output","type":"OUTPUT_MATERIAL_PBR","x":316,"y":192,"color":-5025958,"inputs":[{"id":2,"node_id":2,"name":"Base Color","type":"RGBA","color":-3684567,"default_value":[0.8,0.8,0.8,1]},{"id":2,"node_id":2,"name":"Opacity","type":"VALUE","color":-6184543,"default_value":1},{"id":2,"node_id":2,"name":"Occlusion","type":"VALUE","color":-6184543,"default_value":1},{"id":2,"node_id":2,"name":"Roughness","type":"VALUE","color":-6184543,"default_value":0.1},{"id":2,"node_id":2,"name":"Metallic","type":"VALUE","color":-6184543,"default_value":0},{"id":2,"node_id":2,"name":"Normal Map","type":"VECTOR","color":-10238109,"default_value":[0.5,0.5,1]},{"id":2,"node_id":2,"name":"Emission","type":"VALUE","color":-6184543,"default_value":0},{"id":2,"node_id":2,"name":"Height","type":"VALUE","color":-6184543,"default_value":0},{"id":2,"node_id":2,"name":"Subsurface","type":"VALUE","color":-6184543,"default_value":0}],"outputs":[],"buttons":[]}],"links":[{"id":0,"from_id":1,"from_socket":0,"to_id":2,"to_socket":0}]}
+77 -10
View File
@@ -383,7 +383,7 @@ class UINodes extends iron.Trait {
return con_paint;
}
frag.add_out('vec4 fragColor[3]');
frag.add_out('vec4 fragColor[4]');
frag.add_uniform('float brushRadius', '_brushRadius');
frag.add_uniform('float brushOpacity', '_brushOpacity');
@@ -446,11 +446,13 @@ class UINodes extends iron.Trait {
var met = sout.out_metallic;
var occ = sout.out_occlusion;
var nortan = Cycles.out_normaltan;
var height = sout.out_height;
frag.write('vec3 basecol = $base;');
frag.write('float roughness = $rough;');
frag.write('float metallic = $met;');
frag.write('float occlusion = $occ;');
frag.write('vec3 nortan = $nortan;');
frag.write('float height = $height;');
if (eraser) frag.write(' float str = 1.0 - brushOpacity;');
else frag.write(' float str = clamp(brushOpacity * (brushRadius - dist) * brushStrength, 0.0, 1.0);');
@@ -459,6 +461,7 @@ class UINodes extends iron.Trait {
frag.write(' fragColor[1] = vec4(nortan, 1.0);');
// frag.write(' fragColor[1] = vec4(nortan, str);');
frag.write(' fragColor[2] = vec4(occlusion, roughness, metallic, str);');
frag.write(' fragColor[3] = vec4(1.0, 0.0, height, str);');
if (!UITrait.inst.paintBase) frag.write('fragColor[0].a = 0.0;');
if (!UITrait.inst.paintNor) frag.write('fragColor[1].a = 0.0;');
@@ -524,8 +527,8 @@ class UINodes extends iron.Trait {
return con_mesh;
}
function make_depth(data:ShaderData):armory.system.ShaderContext {
var context_id = 'depth';
function make_depth(data:ShaderData, shadowmap = false):armory.system.ShaderContext {
var context_id = shadowmap ? 'shadowmap' : 'depth';
var con_depth:armory.system.ShaderContext = data.add_context({
name: context_id,
depth_write: true,
@@ -534,15 +537,33 @@ class UINodes extends iron.Trait {
color_write_red: false,
color_write_green: false,
color_write_blue: false,
color_write_alpha: false });
color_write_alpha: false,
vertex_structure: shadowmap ? [{"name": "pos", "size": 3},{"name": "nor", "size": 3},{"name": "tex", "size": 2}] : [{"name": "pos", "size": 3}]
});
var vert = con_depth.make_vert();
var frag = con_depth.make_frag();
frag.ins = vert.outs;
vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrix');
vert.write('gl_Position = WVP * vec4(pos, 1.0);');
if (shadowmap) {
vert.add_uniform('mat4 W', '_worldMatrix');
vert.add_uniform('mat3 N', '_normalMatrix');
vert.add_uniform('mat4 LVP', '_lampViewProjectionMatrix');
vert.add_uniform('sampler2D texpaint_opt');
vert.write('vec4 opt = texture(texpaint_opt, tex);');
vert.write('float height = opt.b;');
vert.write('vec3 wnormal = normalize(N * nor);');
vert.write('vec4 wposition = W * vec4(pos, 1.0);');
var displaceStrength = UITrait.inst.displaceStrength;
vert.write('wposition.xyz += wnormal * height * $displaceStrength;');
vert.write('gl_Position = LVP * vec4(wposition.xyz, 1.0);');
}
else {
vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrix');
vert.write('gl_Position = WVP * vec4(pos, 1.0);');
}
con_depth.data.shader_from_source = true;
con_depth.data.vertex_shader = vert.get();
@@ -569,18 +590,28 @@ class UINodes extends iron.Trait {
vert.add_out('vec4 prevwvpposition');
vert.add_out('vec3 eyeDir');
vert.add_uniform('mat3 N', '_normalMatrix');
vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrix');
vert.add_uniform('mat4 VP', '_viewProjectionMatrix');
vert.add_uniform('mat4 prevWVP', '_prevWorldViewProjectionMatrix');
vert.add_uniform('vec3 eye', '_cameraPosition');
vert.add_uniform('mat4 W', '_worldMatrix');
vert.write('vec4 spos = vec4(pos, 1.0);');
vert.write('wnormal = normalize(N * nor);');
vert.write('vec3 wposition = vec4(W * spos).xyz;');
vert.write('gl_Position = WVP * spos;');
vert.write('vec4 wposition = W * spos;');
// Height
// TODO: can cause TAA issues
vert.add_uniform('sampler2D texpaint_opt');
vert.write('vec4 opt = texture(texpaint_opt, tex);');
vert.write('float height = opt.b;');
var displaceStrength = UITrait.inst.displaceStrength;
vert.write('wposition.xyz += wnormal * height * $displaceStrength;');
//
vert.write('gl_Position = VP * wposition;');
vert.write('texCoord = tex;');
vert.write('wvpposition = gl_Position;');
vert.write('prevwvpposition = prevWVP * spos;');
vert.write('eyeDir = eye - wposition;');
vert.write('eyeDir = eye - wposition.xyz;');
frag.ins = vert.outs;
@@ -617,6 +648,21 @@ class UINodes extends iron.Trait {
frag.write('n = texture(texpaint_nor, texCoord).rgb * 2.0 - 1.0;');
frag.write('n = normalize(TBN * normalize(n));');
// Height
frag.add_uniform('sampler2D texpaint_opt');
frag.write('vec4 vech;');
frag.write('vech.x = textureOffset(texpaint_opt, texCoord, ivec2(-1, 0)).b;');
frag.write('vech.y = textureOffset(texpaint_opt, texCoord, ivec2(1, 0)).b;');
frag.write('vech.z = textureOffset(texpaint_opt, texCoord, ivec2(0, -1)).b;');
frag.write('vech.w = textureOffset(texpaint_opt, texCoord, ivec2(0, 1)).b;');
// Displace normal strength
frag.write('vech *= 15 * 7; float h1 = vech.x - vech.y; float h2 = vech.z - vech.w;');
frag.write('vec3 va = normalize(vec3(2.0, 0.0, h1));');
frag.write('vec3 vb = normalize(vec3(0.0, 2.0, h2));');
frag.write('vec3 vc = normalize(vec3(h1, h2, 2.0));');
frag.write('n = normalize(mat3(va, vb, vc) * n);');
//
frag.write('vec4 pack = texture(texpaint_pack, texCoord);');
frag.write('occlusion = pack.r;');
frag.write('roughness = pack.g;');
@@ -633,6 +679,7 @@ class UINodes extends iron.Trait {
frag.add_uniform('sampler2D texpaint1');
frag.add_uniform('sampler2D texpaint_nor1');
frag.add_uniform('sampler2D texpaint_pack1');
// frag.add_uniform('sampler2D texpaint_opt1');
frag.write('vec4 col_tex1 = texture(texpaint1, texCoord);');
// frag.write('vec4 col_nor1 = texture(texpaint_nor1, texCoord);');
@@ -686,6 +733,7 @@ class UINodes extends iron.Trait {
});
}
public var materialParsed = false;
public function parsePaintMaterial() {
UITrait.inst.dirty = true;
@@ -758,6 +806,25 @@ class UINodes extends iron.Trait {
new MaterialContext(dmatcon, function(self:MaterialContext) {
m.contexts.push(self);
});
var smcon = make_depth(_sd, true);
var smcdata = smcon.data;
// from_source is synchronous..
var smsc = new iron.data.ShaderData.ShaderContext(smcdata, null, function(sc:iron.data.ShaderData.ShaderContext){});
for (c in m.shader.contexts) if (c.raw.name == 'shadowmap') { m.shader.contexts.remove(c); break; }
m.shader.contexts.push(smsc);
// var smmatcon:TMaterialContext = {
// name: "shadowmap"
// }
// m.raw.contexts.push(smmatcon);
// for (c in m.contexts) if (c.raw.name == 'shadowmap') { m.contexts.remove(c); break; }
// new MaterialContext(smmatcon, function(self:MaterialContext) {
// m.contexts.push(self);
// });
materialParsed = true;
// }
// else {
// sc.raw.vertex_shader = cdata.vertex_shader;
+44 -25
View File
@@ -39,7 +39,7 @@ class LayerSlot {
public var texpaint_nor:kha.Image;
public var texpaint_pack:kha.Image;
// public var texpaint_opt:kha.Image;
public var texpaint_opt:kha.Image;
public function new() {
id = counter++;
@@ -70,14 +70,14 @@ class LayerSlot {
texpaint_pack = RenderPath.active.createRenderTarget(t).image;
}
// {
// var t = new RenderTargetRaw();
// t.name = "texpaint_opt" + id;
// t.width = 4096;
// t.height = 4096;
// t.format = 'RGBA32';
// texpaint_opt = RenderPath.active.createRenderTarget(t).image;
// }
{
var t = new RenderTargetRaw();
t.name = "texpaint_opt" + id;
t.width = 4096;
t.height = 4096;
t.format = 'RGBA32';
texpaint_opt = RenderPath.active.createRenderTarget(t).image;
}
}
public function unload() {
@@ -85,7 +85,7 @@ class LayerSlot {
texpaint_nor.unload();
texpaint_pack.unload();
// texpaint_opt.unload();
texpaint_opt.unload();
}
}
@@ -481,9 +481,9 @@ class UITrait extends iron.Trait {
layers[0].texpaint_pack.g4.clear(kha.Color.fromFloats(1.0, 0.4, 0.0, 1.0)); // Occ, rough, met
layers[0].texpaint_pack.g4.end();
// layers[0].texpaint_opt.g4.begin();
// layers[0].texpaint_opt.g4.clear(kha.Color.fromFloats(1.0, 0.0, 0.0, 0.0)); // Opac, emis, height
// layers[0].texpaint_opt.g4.end();
layers[0].texpaint_opt.g4.begin();
layers[0].texpaint_opt.g4.clear(kha.Color.fromFloats(1.0, 0.0, 0.0, 0.0)); // Opac, emis, height
layers[0].texpaint_opt.g4.end();
g.begin();
iron.App.removeRender(initLayers);
@@ -505,9 +505,9 @@ class UITrait extends iron.Trait {
layers[i].texpaint_pack.g4.clear(kha.Color.fromFloats(1.0, 0.0, 0.0, 0.0)); // Occ, rough, met
layers[i].texpaint_pack.g4.end();
// layers[i].texpaint_opt.g4.begin();
// layers[i].texpaint_opt.g4.clear(kha.Color.fromFloats(0.0, 0.0, 0.0, 0.0)); // Opac, emis, height
// layers[i].texpaint_opt.g4.end();
layers[i].texpaint_opt.g4.begin();
layers[i].texpaint_opt.g4.clear(kha.Color.fromFloats(0.0, 0.0, 0.0, 0.0)); // Opac, emis, height
layers[i].texpaint_opt.g4.end();
g.begin();
iron.App.removeRender(clearLastLayer);
@@ -522,12 +522,12 @@ class UITrait extends iron.Trait {
var rttexpaint = rts.get("texpaint" + l.id);
var rttexpaint_nor = rts.get("texpaint_nor" + l.id);
var rttexpaint_pack = rts.get("texpaint_pack" + l.id);
// var rttexpaint_opt = rts.get("texpaint_opt" + l.id);
var rttexpaint_opt = rts.get("texpaint_opt" + l.id);
rttexpaint.image = kha.Image.createRenderTarget(res, res, kha.graphics4.TextureFormat.RGBA32, kha.graphics4.DepthStencilFormat.Depth16);
rttexpaint_nor.image = kha.Image.createRenderTarget(res, res, kha.graphics4.TextureFormat.RGBA32, kha.graphics4.DepthStencilFormat.NoDepthAndStencil);
rttexpaint_pack.image = kha.Image.createRenderTarget(res, res, kha.graphics4.TextureFormat.RGBA32, kha.graphics4.DepthStencilFormat.NoDepthAndStencil);
// rttexpaint_opt.image = kha.Image.createRenderTarget(res, res, kha.graphics4.TextureFormat.RGBA32, kha.graphics4.DepthStencilFormat.NoDepthAndStencil);
rttexpaint_opt.image = kha.Image.createRenderTarget(res, res, kha.graphics4.TextureFormat.RGBA32, kha.graphics4.DepthStencilFormat.NoDepthAndStencil);
g.end();
rttexpaint.image.g2.begin();
@@ -542,9 +542,9 @@ class UITrait extends iron.Trait {
rttexpaint_pack.image.g2.drawScaledImage(l.texpaint_pack, 0, 0, res, res);
rttexpaint_pack.image.g2.end();
// rttexpaint_opt.image.g2.begin();
// rttexpaint_opt.image.g2.drawScaledImage(l.texpaint_opt, 0, 0, res, res);
// rttexpaint_opt.image.g2.end();
rttexpaint_opt.image.g2.begin();
rttexpaint_opt.image.g2.drawScaledImage(l.texpaint_opt, 0, 0, res, res);
rttexpaint_opt.image.g2.end();
g.begin();
l.unload();
@@ -552,7 +552,7 @@ class UITrait extends iron.Trait {
l.texpaint = rts.get("texpaint" + l.id).image;
l.texpaint_nor = rts.get("texpaint_nor" + l.id).image;
l.texpaint_pack = rts.get("texpaint_pack" + l.id).image;
// l.texpaint_opt = rts.get("texpaint_opt" + l.id).image;
l.texpaint_opt = rts.get("texpaint_opt" + l.id).image;
}
dirty = true;
@@ -611,9 +611,9 @@ class UITrait extends iron.Trait {
l0.texpaint_pack.g2.drawImage(l1.texpaint_pack, 0, 0);
l0.texpaint_pack.g2.end();
// l0.texpaint_opt.g2.begin(false);
// l0.texpaint_opt.g2.drawImage(l1.texpaint_opt, 0, 0);
// l0.texpaint_opt.g2.end();
l0.texpaint_opt.g2.begin(false);
l0.texpaint_opt.g2.drawImage(l1.texpaint_opt, 0, 0);
l0.texpaint_opt.g2.end();
g.begin();
@@ -689,6 +689,7 @@ class UITrait extends iron.Trait {
public var layers:Array<LayerSlot> = null;
public var selectedLayer:LayerSlot;
var selectTime = 0.0;
public var displaceStrength = 1.0;
function renderUI(g:kha.graphics2.Graphics) {
if (!show) return;
@@ -947,6 +948,11 @@ class UITrait extends iron.Trait {
var lamp = iron.Scene.active.lamps[0];
lamp.data.raw.strength = ui.slider(Id.handle({value: lamp.data.raw.strength / 10}), "Light", 0.0, 5.0, true) * 10;
}
displaceStrength = ui.slider(Id.handle({value: displaceStrength}), "Displace", 0.0, 2.0, true);
if (ui.changed) {
UINodes.inst.parseMeshMaterial();
}
}
// Draw plugins
@@ -1102,6 +1108,19 @@ class UITrait extends iron.Trait {
if (isOcc) Krom.fileSaveBytes(path + "/tex_orm.png", bo.getBytes().getData());
#end
}
pixels = selectedLayer.texpaint_opt.getPixels();
for (i in 0...textureSize * textureSize) {
rgb.set(i * 3 + 0, pixels.get(i * 4 + 2));
rgb.set(i * 3 + 1, pixels.get(i * 4 + 2));
rgb.set(i * 3 + 2, pixels.get(i * 4 + 2));
}
bo = new haxe.io.BytesOutput();
var pngwriter = new iron.format.png.Writer(bo);
pngwriter.write(iron.format.png.Tools.buildRGB(textureSize, textureSize, rgb));
#if kha_krom
if (isMet) Krom.fileSaveBytes(path + "/tex_oeh.png", bo.getBytes().getData());
#end
}
}
+63 -2
View File
@@ -401,6 +401,62 @@ class RenderPathDeferred {
// Paint
static var initVoxels = true;
public static function drawShadowMapPaint(l:iron.object.LampObject) {
#if (rp_shadowmap)
var faces = l.data.raw.shadowmap_cube ? 6 : 1;
for (j in 0...faces) {
if (faces > 1) path.currentFace = j;
path.setTarget(Inc.getShadowMap());
// Paint
if (arm.UINodes.inst.materialParsed) {
var tid = arm.UITrait.inst.layers[0].id;
path.bindTarget("texpaint_opt" + tid, "texpaint_opt");
}
//
path.clearTarget(null, 1.0);
path.drawMeshes("shadowmap");
}
path.currentFace = -1;
// One lamp at a time for now, precompute all lamps for tiled
#if rp_soft_shadows
if (l.raw.type != "point") {
path.setTarget("visa"); // Merge using min blend
Inc.bindShadowMap();
path.drawShader("shader_datas/dilate_pass/dilate_pass_x");
path.setTarget("visb");
path.bindTarget("visa", "shadowMap");
path.drawShader("shader_datas/dilate_pass/dilate_pass_y");
}
path.setTarget("visa", ["dist"]);
//if (i == 0) path.clearTarget(0x00000000);
if (l.raw.type != "point") path.bindTarget("visb", "dilate");
Inc.bindShadowMap();
//path.bindTarget("_main", "gbufferD");
path.bindTarget("gbuffer0", "gbuffer0");
path.drawShader("shader_datas/visibility_pass/visibility_pass");
path.setTarget("visb");
path.bindTarget("visa", "tex");
path.bindTarget("gbuffer0", "gbuffer0");
path.bindTarget("dist", "dist");
path.drawShader("shader_datas/blur_shadow_pass/blur_shadow_pass_x");
path.setTarget("visa");
path.bindTarget("visb", "tex");
path.bindTarget("gbuffer0", "gbuffer0");
path.bindTarget("dist", "dist");
path.drawShader("shader_datas/blur_shadow_pass/blur_shadow_pass_y");
#end
#end
}
//
@:access(iron.RenderPath)
@@ -451,7 +507,7 @@ class RenderPathDeferred {
path.drawMeshes("voxel");
path.generateMipmaps("voxels");
}
path.setTarget("texpaint" + tid, ["texpaint_nor" + tid, "texpaint_pack" + tid]);
path.setTarget("texpaint" + tid, ["texpaint_nor" + tid, "texpaint_pack" + tid, "texpaint_opt" + tid]);
path.bindTarget("_paintdb", "paintdb");
if (arm.UITrait.inst.brushType == 3) { // Bake AO
path.bindTarget("voxels", "voxels");
@@ -502,11 +558,13 @@ class RenderPathDeferred {
path.bindTarget("texpaint" + tid, "texpaint");
path.bindTarget("texpaint_nor" + tid, "texpaint_nor");
path.bindTarget("texpaint_pack" + tid, "texpaint_pack");
path.bindTarget("texpaint_opt" + tid, "texpaint_opt");
if (arm.UITrait.inst.layers.length > 1) {
tid = arm.UITrait.inst.layers[1].id;
path.bindTarget("texpaint" + tid, "texpaint1");
path.bindTarget("texpaint_nor" + tid, "texpaint_nor1");
path.bindTarget("texpaint_pack" + tid, "texpaint_pack1");
path.bindTarget("texpaint_opt" + tid, "texpaint_opt1");
}
//
@@ -650,7 +708,10 @@ class RenderPathDeferred {
#if (rp_shadowmap)
{
if (path.lampCastShadow()) {
Inc.drawShadowMap(l);
// Inc.drawShadowMap(l);
// Paint
drawShadowMapPaint(l);
//
}
}
#end
BIN
View File
Binary file not shown.