Painting stencil on a surface.

Hi, I've been trying and experimenting on GetPixel/SetPixels to read color data of a 64 x 64 pixels psd file and paste the retrieved data into a Texture2D. The stencil (PSD file) comes with a single layer without background. The Texture2d that is created inside the code is formatted as ARGB32 and the PSD is also imported as ARGB32. In the test link you can see that each star overlaps and removes the previously painted one.

How is it possible to solve this problem so that stars overlap but don't remove eachother?

WebPlayer test: http://jovialart.com/WebPlayer/WebPlayer.html

Thoughts appreciated.

here is script:

var stencil:Texture2D;
var tagFilter:String;
var paintMaterial:Material;

private var tex : Texture2D;
private var stencilUV:Color[];
private var i:int;
private var pixelUV;

function Start(){
    stencilUV = new Color[stencil.width * stencil.height];
    tex = new Texture2D (1024,1024, TextureFormat.ARGB32, false);
    //ReadStencilTexture();
}

function Update () {
    if(DetectPaintable(tagFilter)){
        CreateStencil(pixelUV.x,pixelUV.y,stencil);
    }
}

function DetectPaintable(tagFilter:String):boolean{
    // Only if we hit something, do we continue
    var hit : RaycastHit;
    if(Physics.Raycast (camera.ScreenPointToRay(Input.mousePosition), hit)){
    if (hit.transform.gameObject.tag == tagFilter){
    // Only when we press the mouse
    if (!Input.GetMouseButton (0))
        return;
    // Just in case, also make sure the collider also has a renderer
    // material and texture. Also we should ignore primitive colliders.
    var renderer : Renderer = hit.collider.renderer;
    var meshCollider = hit.collider as MeshCollider;
    if (renderer == null || renderer.sharedMaterial == null ||
        renderer.sharedMaterial.mainTexture == null || meshCollider == null)
        return;

    pixelUV= hit.textureCoord;
    pixelUV.x *= tex.width;
    pixelUV.y *= tex.height;
    return true;
    }
    }
}

function CreateStencil(x:int,y:int, texture:Texture2D){
    paintMaterial.mainTexture = tex;
    for (var xPix =0; xPix<texture.width; xPix++){
        for (var yPix=0;yPix<texture.height; yPix++){
                stencilUV _= texture.GetPixel (xPix,yPix) * texture.GetPixel (xPix,yPix).a + tex.GetPixel((x -texture.width/2) +xPix, (y -texture.height/2)+yPix) * (1-texture.GetPixel(xPix,yPix).a); // <-----_
 *i++;*
 *}*
 *}*
 *i=0;*
 *tex.SetPixels(x -texture.width/2, y-texture.height/2,texture.width,texture.height,stencilUV);*
 *tex.Apply();*
*}*
*```*

You should do what a graphics card does when you ask it to perform alpha blending (alpha blending is what you're trying to do here):

final rgb colour = sourceColour*sourceAlpha + destinationColour*oneMinusSourceAlpha

or in your case:

final rgb colour = (rgb colour of the texture you're applying * alpha colour of the texture you're applying) + (rgb colour of the texture into which you are rendering * (1 - alpha colour of the texture you're applying))

That way you won't just overwrite the alpha values of your 64x64, you'll blend them properly :)

Hi Kourosh, would you be so kind to share your corrected script, i’m having a hard time multiplying my rgb components with the alpha channels…
Thx!

I’m trying to implement this scrip, but with no luck so far…
Could you post the correct script? It would be an awesome help.

Thanks in advance

Hi, did anyone manage to run this code on iPhone? I need exactly this but it is running too slow… is there another workaround?

Hi, did anyone manage to run this code on iPhone? I need exactly this but it is running too slow… is there another workaround?

There is logic mistake in the script. I spend much time before I realize that I need to swap this couple of lines in CreateStencil function:

        for (var xPix =0; xPix<texture.width; xPix++){
                    for (var yPix=0;yPix<texture.height; yPix++){
                    ...
                    }

This two lines need to swap, to get script working correct. Oterwise iterator writes into array Y-row at first. Than changes X. And again writes Y-row. This is the reason why I was getting wrong drawing result.