Quick Links: Gideros Home | Download Gideros | Developer Guide
Masking images?
  • Hi guys

    I've searched the forums in and out, but can't seem to find any way of masking images in gideros.

    The answers I've found seem to be workarounds, but I'm not sure whether that info is still relevant, or whether masks are now possible.

    Thank you heaps for your help!
  • hgy29hgy29 +1 -1
    Maintainer
    Yes, this topic sometimes pop up again :)

    There is a few ways to achieve masking in OpenGL:
    - Using stencil buffer to impress a mask picture and then render others shapes only in places where stencil was marked. This is the technique used by Path2D. It allows precise masking at the expense of a double rendering pass. This is not (yet) exposed to lua by Gideros
    - Using alpha blending composition: you can multiply a mask bitmap with a regular Sprite. This is already available in Gideros and is most of the time faster than the first technique.
    - Using shader (like in the vignette exemple I sent you): probably the fastest way.
  • Hi @hgy29

    Thank you for the answers, I will have a look at the vignette example as soon as I can get the sharers working :)
  • Hi @hgy29

    I've had a look at your example, but to be honest I have no idea what any of the values mean, lol. I think I would need to go through some sort of manual, in order to understand how to make shaders.

    If anyone would be able to show me a small example how to do this using blending modes, I would be eternally grateful :)

    Thanks you very much for all your help - you guys rock!
  • Hi @hgy29
    Sorry for pop up again,
    I have an image png and I want to make 6 part (2*3) from this image by using mask images (They are not square nor rectangle but like the jigsaw puzzle). How can I do this in Gideros, at this time (I see many new apis added so I hope it will be easy now)

    (Example mask shape and game that I want to make: https://play.google.com/store/apps/details?id=com.kristanix.android.jigsawpuzzleepic)

    Thank so much!
  • Try path2D to create a vector shape. Apply a bitmp to a render target and set the texture of the path 2D to the render target.

    A recent feature is that you can now select a region of the bitmap using render target.

    I did a similar thing in Grammar Smash English for the smashing effect.
  • @NatWobble Thanks! I will try to implement your comment.
    In my game, the mask is defined and are fixed images (As I attach bellow). So basically, I think it can not create by vector shape using path2D?
    16_9.png
    448 x 336 - 6K
  • hgy29hgy29 +1 -1 (+1 / -0 )
    Maintainer
    @vitalitymobile, I can think of two ways to achieve that:

    The first way is using rendertargets and alpha blending: create a render target, draw your image on it, then draw the mask right above using multiply blending mode, so that white pixels in the mask will leave underlying color untouched and black pixels will turn them to black. Better: if the mask 'black' color could be actually transparent, then your rendertarget cutted part shall become transparent too.

    The second way would be to use a shader with double texture input (image and mask): the shader would then automatically eliminate masked pixels, but shaders are still not completely portable, meaning that you need to write a GLSL one (for open gl based platforms) and an HLSL one (for windows RT/UWP).
  • vitalitymobilevitalitymobile +1 -1 (+1 / -0 )
    Member
    Hi @hgy29
    Yes, thank so much I follow the first way and have resulted as expected.
    The remain jobs are change black to transparent and check for touch area of pieces (Do not allow user to hold transparent area to move the piece )

    In theory, the second method would be great if we can write both GLSL and HLSL and put it into Gideros API as simple setMask Method

    (From Mask Requirement session here https://docs.coronalabs.com/guide/media/imageMask/index.html
    I guess they use your the second way in above comment
    )

    Thank so much!
    Screen Shot 2016-12-23 at 11.35.52 AM.png
    2860 x 1466 - 611K

    Likes: antix

  • john26john26 +1 -1 (+2 / -0 )
    Maintainer
    @Ninjadoodle, thanks for reminding me, the shader stuff in Gideros desperately needs documentation and tutorials. I will try to get some stuff on the website in the near future (new year resolution!)
  • hgy29hgy29 +1 -1 (+4 / -0 )
    Maintainer
    Quick and dirty:
    local JigsawVShader=
    [[
    attribute vec4 POSITION0;
    attribute vec2 TEXCOORD0;
     
    uniform mat4 g_MVPMatrix;
     
    varying mediump vec2 texCoord;
     
    void main()
    {
    gl_Position = g_MVPMatrix * POSITION0;
    texCoord = TEXCOORD0;
    }
    ]]
     
    local JigsawFShader=[[
    uniform lowp sampler2D gMask;
    uniform lowp sampler2D gJig;
    uniform mediump vec4 jigRect;
    uniform mediump vec4 maskInfo;
     
    varying mediump vec2 texCoord;
     
    #ifdef GLES2
    precision mediump float;
    #endif
     
    void main()
    {
    vec4 mask= texture2D(gMask, texCoord);
    if (mask.r<0.5)
    discard;
    vec4 jig=texture2D(gJig, texCoord*jigRect.zw+jigRect.xy);
     
    gl_FragColor = jig;
    }
    ]]
     
    local JigsawShaderAttrs=
    {
    {name="POSITION0",type=Shader.DFLOAT,mult=3,slot=0,offset=0},
    {name="vColor",type=Shader.DUBYTE,mult=0,slot=1,offset=0},
    {name="TEXCOORD0",type=Shader.DFLOAT,mult=2,slot=2,offset=0}
    }
     
    local JigsawShaderConstants={
    {name="g_MVPMatrix",type=Shader.CMATRIX,sys=Shader.SYS_WVP, vertex=true},
    {name="gMask",type=Shader.CTEXTURE,mult=1,vertex=false},
    {name="gJig",type=Shader.CTEXTURE,mult=1,vertex=false},
    {name="jigRect",type=Shader.CFLOAT4,mult=1,vertex=false},
    }
     
     
    local JigsawShader= Shader.new(
    JigsawVShader,JigsawFShader,
    Shader.FLAG_FROM_CODE,JigsawShaderConstants,JigsawShaderAttrs)
     
    local jigsaw=Texture.new("DSC_1529.JPG",true)
    local piece=Pixel.new(Texture.new("PuzzleMask.png",true),50,50)
    piece:setTexture(jigsaw,1)
    piece:setShader(JigsawShader)
    piece:setShaderConstant("jigRect",Shader.CFLOAT4,1,0.1,0.1,0.3,0.3)
     
    application:setBackgroundColor(0xFF00FF)
     
    stage:addChild(piece)
    piece:setPosition(50,50)
  • keszegh +1 -1 (+4 / -0 )
    Member
    i think a mask function should be provided in gideros automatically, it's quite useful stuff.
  • @hgy29 Thanks, It works!
    How can I modify relate x,y position of the mask in the image (I mean reposition mask in the image so that we have difference parts)?
  • hgy29hgy29 +1 -1 (+1 / -0 )
    Maintainer
    You can do that using:
    piece:setShaderConstant("jigRect",Shader.CFLOAT4,1,x,y,w,h)

    where x and y are the starting point in your image divided by the size of your image rounded up to the next power of 2, and w and h are similarily the width and height of the area of your image you want to map to your mask, mask size being itself rounded up to the next power of 2.

    So assuming you want to map ix,iy,iw,ih source rect of your image to your jigsaw piece, x,y,w,h could be computed like this:
    local imageExtW,imageExtH=math.pow(2,1+math.floor(math.log(image:getWidth())/math.log(2))),math.pow(2,1+math.floor(math.log(image:getHeight())/math.log(2)))
    local maskVisW,maskVisH=mask:getWidth()/math.pow(2,1+math.floor(math.log(mask:getWidth())/math.log(2))),mask:getHeight()/math.pow(2,1+math.floor(math.log(mask:getHeight())/math.log(2)))
     
    local x,y,w,h=ix/imageExtW,iy/imageExtH,iw/(imageExtW*maskVisW),ih/(imageExtH*maskVisH)

    NB: Not tested, but I hope you'll get the idea

    Likes: SinisterSoft

  • vitalitymobilevitalitymobile +1 -1 (+2 / -0 )
    Member
    Thank @hgy29
    It works! You are the Master of math and the King of shader. Two achievements!
    Screen Shot 2017-01-12 at 11.30.14 PM.png
    952 x 680 - 64K

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Login with Facebook Sign In with Google Sign In with OpenID

In this Discussion

Top Posters