Using an alphamask without the alpha being visible

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
Onishion
Veteran
Posts: 295
Joined: Mon Apr 20, 2015 10:36 am
Contact:

Using an alphamask without the alpha being visible

#1 Post by Onishion »

Ok, I have a slightly complex issue. I have a composite where I want to display one graphic layer, that has an animated alpha mask to occlude parts of it. I've got it working to the point that the alpha layer animates properly, and properly effects the opacity of the target layer, but the problem is that the alpha layer itself is visible in frame, and I want it to be invisible because it's just a junk image used for its alphachannel. If I just set the alpha of the alpha layer to zero, then it vanishes, but so does the target layer. ;) I can fake it for part of this by hiding the alpha layer behind the middle layer, but this only works when the alpha is in a position to not peek out from behind it. Is there some better way to hide the alpha layer itself, while retaining it's ability to pass on the alphachannel from the png itself?

Code: Select all

image TestLC = LiveComposite(                                                                     
    (100, 100),      
    (0, 0), "AlphaImage",                       #putting it here can hide it when it's fully behind the base, but not when it's larger or moved wrong
    (0, 0), "BaseImage",                        
    (0, 0), AlphaMask("TargetImage", "AlphaImage"),
    )

image BaseImage: #This would be a png with its own alpha channel
    "images/Base.png" 
    
image TargetImage:
    "images/Target.png" 
    
image AlphaImage:
    "images/alphalayer.png"     #This would be a png with its own alpha channel
    #alpha 0                    #If I use this, the alpha layer hides, but so does the target layer. If I don't use this, the alpha layer is visible.
    ease 2.5 offset (25,100) 
    ease 2 offset (0,-35)
    pause .5
    repeat


User avatar
theCodeCat
Regular
Posts: 62
Joined: Sun Sep 06, 2015 8:40 pm
Projects: Lucid9, Mystic Destinies: Serendipity of Aeons
Skype: theCodeCat
Contact:

Re: Using an alphamask without the alpha being visible

#2 Post by theCodeCat »

I've got it working to the point that the alpha layer animates properly
Odd. When I tried to replicate your example I couldn't get the positional part of the animation to work at all. Which version of Renpy are you using?

In general using ATL transforms that change the position of 'TargetImage' or 'AlphaImage' had no effect.

After digging through the Renpy source code a bit, it looks like the AlphaMask class just never runs the code that positions images, so they always get placed at (0,0). I tried creating an alternate version that does position images, but that turned out to be harder than I excepted.

However instead of getting AlphaMask to position the images itself, you can bre-bake displayables that incorporates the positional changes and pass those to AlphaMask.
Sorry if I'm not really making sense here. It's difficult to explain if you aren't somewhat familiar with how Renpy renders objects.

Long story short, put your displayables inside a "Fixed" element of a fixed size before passing them on to AlphaMask.

Ex:

Code: Select all

#Add this somewhere
init python:
    def FixedWrapper(child,width,height):
        rv = renpy.display.layout.Fixed(xmaximum=width, ymaximum=height, xminimum=width, yminimum=height)
        rv.add(child)
        return rv

# Instead of
image test = AlphaMask("target","mask")
# use
image test = AlphaMask(FixedWrapper("target",800,600),FixedWrapper("mask",800,600))
# Where the width and height parameters denote the region your moving displayable is contained in
# If the displayable doesn't move at all then you don't need to add a wrapper
In your case, replace the first bit with

Code: Select all

init python:
    def FixedWrapper(child,width,height):
        rv = renpy.display.layout.Fixed(xmaximum=width, ymaximum=height, xminimum=width, yminimum=height)
        rv.add(child)
        return rv

image TestLC = LiveComposite(                                                                     
    (100, 100),
    (0, 0), "BaseImage",
    # Since this entire LiveComposite is 100x100, the AlphaImage doesn't need more space than that
    (0, 0), AlphaMask("TargetImage", FixedWrapper("AlphaImage",100,100)),
    )
and it should work.

Onishion
Veteran
Posts: 295
Joined: Mon Apr 20, 2015 10:36 am
Contact:

Re: Using an alphamask without the alpha being visible

#3 Post by Onishion »

I'm sorry if I'm a bit confused, but my issue wasn't with getting the masking image to move, I got that much, the problem is that I can't get the masking image to mask the target image properly without also being visible itself. What I would like to be able to do is have the alpha image mask the target image based on the alphachannel of it's png, without actually being a visible part of the image.

Like, basically, imagine the alpha mask image as a keyhole. The keyhole is white and the rest of the image is black, so if you display it normally it's just a white keyhole, right? This masking image needs to be a part of the live composite, because it needs to inherit the positional data of the live composite itself, so that its location is relative to the location of the live composite. Then I have the target image, and I want the result to be that you can only see the part of the target image that overlaps with that keyhole, and so far that much works on my end. The problem is, the white keyhole layer ends up being visible, and at points where it's not hidden behind the target or base layers of the composite, you can see it moving around. What I would like is for that part of be invisible to the naked eye, while its impact on the target layer is the same as if it were visible.

User avatar
theCodeCat
Regular
Posts: 62
Joined: Sun Sep 06, 2015 8:40 pm
Projects: Lucid9, Mystic Destinies: Serendipity of Aeons
Skype: theCodeCat
Contact:

Re: Using an alphamask without the alpha being visible

#4 Post by theCodeCat »

This masking image needs to be a part of the live composite, because it needs to inherit the positional data of the live composite itself
The 'AlphaMask' component is positioned relative to the LiveComposite it is in automatically.

Adding a second AlphaImage to the LiveComposite should have no effect on the AlphaMask, so you really shouldn't need the line that says:

Code: Select all

     (0, 0), "AlphaImage",
And it is this line that makes the "Alpha Layer" visible as well.

1. Does your masking code still work if you remove the ' (0, 0), "AlphaImage",' line?
2. Does the code I recommended in my first post work? And if not, how so?

Onishion
Veteran
Posts: 295
Joined: Mon Apr 20, 2015 10:36 am
Contact:

Re: Using an alphamask without the alpha being visible

#5 Post by Onishion »

The 'AlphaMask' component is positioned relative to the LiveComposite it is in automatically.
Yeah, if it's a stationary image, but if it's an animated one, then I don't think that is the case, although I will test out the theory. Let me clear something up from the example that might make a difference, in the actual code, the alpha isn't an image with a built in animation, it's an image "At("AlphaImage", AlphaAnimation())," so that animation needs to be triggered conditionally. Different alphas are used based on different variable conditions, and these need to sync up with the other animations, so descyncing can occur if I don't make them as similar as possible. I'll play around with it a bit, but I don't think that their location can just be assumed to be in the right place.

1. If I just remove the alpha layer from the LC then the result is that the target layer isn't visible at all. wherever the game thinks the alpha layer is meant to be, they clearly do not intersect, it is not at the anticipated location (and it's hard to aim because I can't see it).

2. I'm not really sure what your code is intended to do, it seems to be more about the position of the alpha layer rather than its visibility. I can try to get it in there though in the morning.

I mean, keep in mind, the example code I gave is a very simplified example to get my issue across, it's not the actual code I'm working with, which is much more complicated and involves Condition Switches and Xela's Dynamic Switchers, the point is I need to figure out how to make the Alpha layer itself invisible without that invisibility transferring over to the alphaed object. I can maybe try to put together a more complex example code.

Post Reply

Who is online

Users browsing this forum: No registered users