Clipping not working if making Mask smaller (DEF-2225) (SOLVED)

Hi,
I have a circular Sprite, that I want only to be partly visible. (Segment of 30 Degrees for example).
I got it working like this http://www.defold.com/manuals/clipping/

  1. Add a pie node. It will act as a “keyhole” for the map.
  2. Add a box node and apply the map texture to it.
  3. Child the box node to the pie node.
  4. Set the Clipping property of the pie node to “Stencil”.

(+ set ‘Pie Fill Angle’ to 0)

Now, when I add:

gui.animate(node, "fill_angle", 30, gui.EASING_LINEAR, 1)

30 degrees of the Sprite get visible, as intended. I can make 30 further degrees visible with

gui.animate(node, "fill_angle", 60, gui.EASING_LINEAR, 1)

But if I want to go back to make only the first 30 degrees visible with

gui.animate(node, "fill_angle", 30, gui.EASING_LINEAR, 1)

It doesn’t work properly and as the Sprite is not perfectly circular, I can see the actual Pie getting smaller but the Texture of the associated Box-Node doesn’t change.

Does anybody have an idea why this is the case?

Thanks, Peter

Hi @peterH!

So, it works at 30 and 60 degrees, but not when you go back to 30 degrees?

Could it be that you start a new animation before the previous one has finished? You can call gui.cancel_animation() to do that, just before you start another animation.

I can see the actual Pie getting smaller but the Texture of the associated Box-Node doesn’t change

Not sure what you mean here. Perhaps if you post a screenshot, it may help to understand the issue?

Thanks for the reply @Mathias_Westerdahl

No, there is no animation to be finished before I start the fill_angle. I first tested it in my game, where this error couldve happened, but broke it down afterwards so nothing else was left. (set the start-angle to something, increased it [worked], restarted with the same start-angle, decreased it [didnt work])

I reproduced it with the defold logo

You can see 7 stages: 90° > 180° > 270° > 360° > 270° > 180° > 90°

The white circular background is the Pie-Node (Didn’t figure out what the blend mode does exactly, but when its set to Alpha you can see the white Pie-Node, set on Multiply you can’t, so for this example it’s set to Alpha)

The Defold Logo is a textured Box-Node and Child of the Pie and the Pies Clipping is set to Stencil (just as described in http://www.defold.com/manuals/clipping/)

The Pie is doing exactly what it’s supposed to do but the Child isnt when decreasing :confused:

Hmm, strange. I cannot reproduce this behavior.

I have a very simple setup, to try to mimick yours:

“pie” node, with rotation (0, 0, 90) (to get the angle 0 directed upwards, as seen in your gif)
The pie node has the options:

  • Clipping = stencil
  • Visible clipper = false
  • Inverted clipper = false

“box” node, with rotation (0, 0, -90) (to get the logo rotated correctly)
The “box” node is a child to the “pie” node

Here is my gui script:

local done = true

local function anim_done()
    done = true
end

local function anim_angle(angle)
    local node = gui.get_node("pie")
    done = false
    gui.animate(node, "fill_angle", angle, gui.EASING_LINEAR, 2, 0, anim_done, gui.PLAYBACK_ONCE_FORWARD)
end

function update(dt)
    if done then
        local angle = gui.get_fill_angle(gui.get_node("pie"))
        if angle == 0 then
            anim_angle(-360) -- since we rotate clockwise
        else
            anim_angle(0)
        end
    end
end

And here is the result: (sry for the compression artifacts):

2 Likes

Thanks for the Reply again @Mathias_Westerdahl
Ok, to eliminate all problems that could occur from my existing project, I also did your simple setup:

Creating a blank new gui-file, adding a Pie-Node, adding a Box-Node, applying Texture to Box-Node, positioning/resizing both, adjust settings to the ones You wrote, creating new gui_script-file, copy-pasting your Code from above.

When I build&launch I get a black screen with the Defold-Logo on it, doing nothing. When I set

  • Visible clipper = true

I get this:

When I additionally set

  • Pie Fill Angle = 0

I get this:

So it’s definately animating the Pie correclty both times, but got problems using it as a Mask for the Box-Texture. To whatever Fill Angle the Texture was shown once, it cant decrease from there.

As I copy-pasted your Code and used new Files for it (It’s still in an existing Project, but I directly start the new Files) I don’t know what could lead to this behaviour. I’ll be able to try out more stuff later today, post updates then, and probably feel ashamed, when I got the solution :stuck_out_tongue_winking_eye:

Regards, Peter

P.S.
Defold Version 1.2.91
Java 1.8.0_05

1 Like

Do you perhaps have a custom .render_script?
I can get reproduce your issue if I remove the stencil clear from my render script:


-- no issue
render.clear({[render.BUFFER_COLOR_BIT] = self.clear_color, [render.BUFFER_DEPTH_BIT] = 1, [render.BUFFER_STENCIL_BIT] = 0})

-- issue
render.clear({[render.BUFFER_COLOR_BIT] = self.clear_color, [render.BUFFER_DEPTH_BIT] = 1})

If you don’t clear it, you just fill it, and it will be the total of all your stencil masks over time.

2 Likes

EDIT:
GOT IT! At least kind of … When I bundle it as an Android-Applictaion its working perfectly, but as HTML5 and Windows Application it isn’t. Just ran it with CTRL+B the last times without testing it on a mobile device. Still don’t know where the problem is, but this is progress :stuck_out_tongue_winking_eye:



No, unfortunately I use the default render_script with the same Arguments as in your no issue line. Never edited or created a new one, as I still only do basic stuff.

I just created a new blank Project in the Dashboard and get the same error there. (didn’t touch anything except calling the gui-file in the main-collection).

The read-only render_script-file that is selected:

function init(self)
    self.tile_pred = render.predicate({"tile"})
    self.gui_pred = render.predicate({"gui"})
    self.text_pred = render.predicate({"text"})
    self.particle_pred = render.predicate({"particle"})

    self.clear_color = vmath.vector4(0, 0, 0, 0)
    self.clear_color.x = sys.get_config("render.clear_color_red", 0)
    self.clear_color.y = sys.get_config("render.clear_color_green", 0)
    self.clear_color.z = sys.get_config("render.clear_color_blue", 0)
    self.clear_color.w = sys.get_config("render.clear_color_alpha", 0)

    self.view = vmath.matrix4()
end

function update(self)
    render.set_depth_mask(true)
    render.clear({[render.BUFFER_COLOR_BIT] = self.clear_color, [render.BUFFER_DEPTH_BIT] = 1, [render.BUFFER_STENCIL_BIT] = 0})

    render.set_viewport(0, 0, render.get_window_width(), render.get_window_height())
    render.set_view(self.view)

    render.set_depth_mask(false)
    render.disable_state(render.STATE_DEPTH_TEST)
    render.disable_state(render.STATE_STENCIL_TEST)
    render.enable_state(render.STATE_BLEND)
    render.set_blend_func(render.BLEND_SRC_ALPHA, render.BLEND_ONE_MINUS_SRC_ALPHA)
    render.disable_state(render.STATE_CULL_FACE)

    render.set_projection(vmath.matrix4_orthographic(0, render.get_width(), 0, render.get_height(), -1, 1))

    render.draw(self.tile_pred)
    render.draw(self.particle_pred)
    render.draw_debug3d()

    render.set_view(vmath.matrix4())
    render.set_projection(vmath.matrix4_orthographic(0, render.get_window_width(), 0, render.get_window_height(), -1, 1))

    render.enable_state(render.STATE_STENCIL_TEST)
    render.draw(self.gui_pred)
    render.draw(self.text_pred)
    render.disable_state(render.STATE_STENCIL_TEST)

    render.set_depth_mask(false)
    render.draw_debug2d()
end

function on_message(self, message_id, message)
    if message_id == hash("clear_color") then
        self.clear_color = message.color
    elseif message_id == hash("set_view_projection") then
        self.view = message.view
    end
end

Interesting. I guess @Mathias_Westerdahl tested on OSX. Mathias, is there any reason to believe that your example would fail on Windows?

@britzl I just tried it on Win 7 and HTML5, and it works for me there too :confused:

I was finally able to reproduce this issue after creating an entirely new, empty project, with just the gui (pie + box node). However, if I add another node to the gui scene (as a sibling to the pie node), it starts working again!

1 Like

SOLVED, THANKS @Mathias_Westerdahl

I also tested an additional Box-Node in my new empty project and it works on all platforms indeed.
In the project, where I first ran into this problem are plenty of Box-Nodes and a few of the Pie-Nodes for which I want the Animation though.

So I played around a bit and noticed it depends on the order the Nodes are arranged in the Outline.
If there is a Box-Node or any other Element (tested with Pie and Text also) lower in the Outline (=more in front/above) available, the problem doesn’t occur. If I put the additional Node in between my Pie-Nodes that I want to have animated, the ones ‘behind’ don’t work, the ones in front however do.

It was a kind of unfortunate coincidence that I (initially, before I posted here) added the Pie-Nodes last and they therefore had no additional Node in front of them, but now its finally fixed … Thanks again @Mathias_Westerdahl :smiley: :grin:

Note: They don’t need to overlap or something like that, so I still think it’s a bug. For now I just edit an existing Box to be the lowest one in the Outline.

1 Like

Yes, it sounds like a bug. @Mathias_Westerdahl, we need a ticket for this one right?

2 Likes

Added as issue DEF-2225.

Thanks for the help @peterH!

2 Likes

Solved in Defold 1.2.99

1 Like