mob-sakai / SoftMaskForUGUI

Enhance Unity UI (uGUI) with advanced soft-masking features to create more visually appealing effects!
https://github.com/mob-sakai/SoftMaskForUGUI
MIT License
2k stars 262 forks source link

Camera movement affects the mask rendering when on a World Space Canvas. #49

Closed DiegoGal closed 5 years ago

DiegoGal commented 5 years ago

Hi there!

I have a camera with a script that moves his transform position at update. When playing the game, the camera starts moving the SoftMask instead of letting it at his place, as I show you right here:

Orto1conv

The masked element is on a Canvas with World Space render mode. But furthermore, if I check the maskable element to use Stencil, the movement only applies to the maskable item, the mask stands where I want it.

Orto2

The camera is Orthographic and the hierarchy of the objects is as follows:

image

The behaviour I want is the mask to stay at its place on the real world and not being influenced by the camera movement.

Specs:

If you want to see some of the code of how I move the camera or some other configurations just ask for it, I will be pleased to show you :)

Despite that, I love the plug-in, great work! 💃

mob-sakai commented 5 years ago

Hi @DiegoGal Thank you for reporting. :)

I would like to know more information on this issue. Can you submit a small reproducible project for this issue?

DiegoGal commented 5 years ago

Of course!

Here you are, the camera movement is randomized each time and moves very smoothly, but you can move camera to see tha the mask goes away its original position.

KillerPunk.zip

mob-sakai commented 5 years ago

Thanks!

mob-sakai commented 5 years ago

@DiegoGal

WIP: When moving the world camera, hasChanged flag was not set to true.

Before before

After after

DiegoGal commented 5 years ago

Wow! That is just what I need, where is the best place to change that?

mob-sakai commented 5 years ago

When the camera moves (when the camera view matrix or projection matrix changes), hasChanged should be true.

SoftMask.cs

static void UpdateMaskTextures()
{
    s_nowViewProjectionMatrices.Clear ();
    foreach (var sm in s_ActiveSoftMasks)
    {
        if (!sm || sm._hasChanged)
            continue;

        // ADD FROM HERE
        var canvas = sm.graphic.canvas;
        if (canvas.renderMode == RenderMode.WorldSpace)
        {
            var cam = canvas.worldCamera;
            Matrix4x4 nowsVP = cam.projectionMatrix * cam.worldToCameraMatrix;
            Matrix4x4 previousVP = cam.reviousViewProjectionMatrix;

            if (previousVP != nowsVP)
            {
                sm.hasChanged = true;
            }
        }
        // TO HERE

        var rt = sm.rectTransform;
        if (rt.hasChanged)
        {
            rt.hasChanged = false;
            sm.hasChanged = true;
        }
...
mob-sakai commented 5 years ago

Note: Camera.reviousViewProjectionMatrix property has been added in Unity 2018.1.

mob-sakai commented 5 years ago

This will be released soon.

AndreasMLarsen commented 4 years ago

I was just doing some testing and it seems the previous projection matrix and the current projection matrix are never the same if the camera is sitting still, causing hasChanged to always be set to true

mob-sakai commented 4 years ago

@AndreasMLarsen

Wow. Please create an issue about that.