Yes, I will be glad to (btw: there might be some ‘chicken-and-egg’ effect within this post … we touched upon the same ‘general issue’ of mine at the ‘playcanvas engine’ github issues some days ago https://github.com/playcanvas/engine/issues/2556)
But yes I am still trying to make drawing effects upon; models (quite more complex than simple primitives).
In a sub-project, to a much larger one, I am trying to enable the user to draw on gaming-quality characters (for tattoo artists) as well as high-end modellings of real cars (comercial car stickers).
For now I am focusing on the ‘tattoo part’. In order to work with multiple layers and maybe an alpha (within my first approach), I am expanding one of the scripts (from How to get the uv coordinate of a mesh) like this:
var RenderLayerTotexturePnt = pc.createScript('renderLayerTotexturePnt');
RenderLayerTotexturePnt.attributes.add("layerName", {type: "string"});
// initialize code called once per entity
RenderLayerTotexturePnt.prototype.initialize = function() {
// Create a 512x512x24-bit render target with a depth buffer
var colorBuffer = new pc.Texture(this.app.graphicsDevice, {
width: 512,
height: 512,
format: pc.PIXELFORMAT_R8_G8_B8_A8,
autoMipmap: true
});
colorBuffer.minFilter = pc.FILTER_LINEAR;
colorBuffer.magFilter = pc.FILTER_LINEAR;
var renderTarget = new pc.RenderTarget(this.app.graphicsDevice, colorBuffer, {
depth: true
});
// New part that I maybe will elaborate upon with clearStencilBuffer and/or cullingMask (but dont know how?)
this.app.root.findByName("RenderCamera").camera.clearColorBuffer =true; // or 'false'?
var color = this.app.root.findByName("RenderCamera").camera.clearColor;
color.r = 0.59;
this.app.root.findByName("RenderCamera").camera.clearColor = color;
// --- end of new part
var layer = this.app.scene.layers.getLayerByName(this.layerName);
layer.renderTarget = renderTarget;
};
It lets me go a bit of the way (colorBuffer-wise), but only gets me from
- to
Likewise with black color-brush (layer):
- to
PS: yes @Leonidas showed me the cube-with-lines example as well.
I need a tool-in-my-mindbox to use it though - the HTML inline format puzzles me?
How to, for instance, ‘convert’:
app.on(“update”, function (dt) {
to
jsScript.prototype.update = function() {
and so on? (don’t get me wrong, I do know how to convert some of it … but far from all)
{
// disable brushes from the previous frame and return them to the free pool
while (usedBrushes.length > 0) {
var brush = usedBrushes.pop();
brush.enabled = false;
brushes.push(brush);
}
seems quite far from examples like:
for (var i=0;i<this.entity.model.model.meshInstances.length;i++)
{
var material = this.entity.model.model.meshInstances[i].material;
console.log(layer.renderTarget.colorBuffer);
material.emissiveMap = layer.renderTarget.colorBuffer;
material.update();
}
and
var layer = this.app.scene.layers.getLayerByName(this.layerName);
this.material.setParameter("texture_mask",layer.renderTarget.colorBuffer);
this.app.root.findByName("UVImage").element.texture = layer.renderTarget.colorBuffer;
}
Bottom-bottom line; I can tell that this chunk below (from https://github.com/playcanvas/playcanvas.github.io/blob/master/graphics/painter.html) and paintLayer.id are vital to solving my problem:
var paintCamera = new pc.Entity();
paintCamera.addComponent("camera", {
clearColorBuffer: false,
projection: pc.PROJECTION_ORTHOGRAPHIC,
layers: [paintLayer.id]
});
->> so something like:
var paintLayer = new pc.Layer({ name: "paintLayer" });
app.scene.layers.insert(paintLayer, 0);
// set up layer to render to the render targer
paintLayer.renderTarget = renderTarget;
// we render multiple brush imprints each frame to make smooth lines, and set up pool to reuse them each frame
var brushes = [];
function getBrush() {
brush = createPrimitive("sphere", new pc.Vec3(2, 1, 0), new pc.Vec3(1, 1, 1), [paintLayer.id], brushMaterial);
- mixed with the Brush.js script?:
var Brush = pc.createScript('brush');
Brush.attributes.add('cameraEntity', {type: 'entity'});
Brush.attributes.add('brushSize', {type: 'number',min: 1, max: 50});
// initialize code called once per entity
Brush.prototype.initialize = function() {
var self = this;
var height = this.cameraEntity.camera.orthoHeight;
var math = pc.math;
var size = this.brushSize / 100;
this.entity.setLocalScale(size,size,size);
this.chosenColor = 0; /*0: RED; 1: GREEN; 2: BLACK*/
this.on("attr:brushSize",function() {
var size = this.brushSize / 100;
this.entity.setLocalScale(size,size,size);
});
this.app.on("hitUV",function(hitPos) {
if(!this.entity.model.enabled) this.entity.model.enabled = true;
this.entity.setLocalPosition(math.lerp(-height, height, hitPos.x), math.lerp(-height, height, hitPos.y), -3);
},this);
this.app.root.findByName("Reset").element.on("click",function() {
this.cameraEntity.camera.clearColorBuffer = true;
setTimeout(function() {
self.cameraEntity.camera.clearColorBuffer = false;
},50);
},this);
var brushs = this.app.root.findByName("Brush Group").children;
brushs[0].element.on("click",function() {
this.canvas1Layer = document.createElement("canvas"); this.canvas1Layer = self.cameraEntity.camera.colorBuffer;
this.brushSize = 3;
for(var i = 0;i < brushs.length;brushs[i++].element.color = pc.Color.WHITE);
brushs[0].element.color = pc.Color.RED;
this.chosenColor =0;
},this);
brushs[1].element.on("click",function() {
this.brushSize = 7;
for(var i = 0;i < brushs.length;brushs[i++].element.color = pc.Color.WHITE);
brushs[1].element.color = pc.Color.GREEN;
this.chosenColor =1;
},this);
brushs[2].element.on("click",function() {
this.brushSize = 16;
for(var i = 0;i < brushs.length;brushs[i++].element.color = pc.Color.WHITE);
brushs[2].element.color = pc.Color.BLACK ;this.chosenColor =2;
},this);
if(this.chosenColor===0){brushs[0].element.color = pc.Color.RED;}
if(this.chosenColor===1){brushs[1].element.color = pc.Color.GREEN;}
if(this.chosenColor===2){brushs[2].element.color = pc.Color.BLACK;}
//brushs[0].element.color = pc.Color.BLUE;
this.app.on("brushUp",function() {
this.entity.model.enabled = false;
},this);
};