Drawing on multiple layers

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);
};
1 Like