Zoom transparency?

What’s the easiest & most accurate way of when my camera zooming close to my target that it fades out based on the distance & how would I do it?

Any help is absolutely appreciated!

Thank you & have a GREAT evening!

Do you mean camera proximity? If so, just find the distance each frame and set a transparency level in your target object (it needs the right shader for transparency to be enabled). If you mean actual camera “zoom”, like FOV, that would be trickier.

1 Like

I do not understand… T_T

can someone help?

You need to be more specific. Do you want to fade the target based on camera distance? If so,

  1. figure out the distance (Vector3.Distance)
  2. use a material on your target that supports transparency, that can be set with an alpha value of 0-1
  3. scale the distance to the 0-1 alpha range as visually appropriate.
1 Like

@seejayjames yes, i want to fade the target based on camera distance.

so i tried this :

if ( distance <= distanceFromObj ) {
    transparencyPercentage = ( 1.0f - ( distance / distanceFromObj ) );
    Debug.Log ( "transparencyPercentage : " + transparencyPercentage );
    objectRenderer.material.color.a = transparencyPercentage;
}

__*distance*__ is the current zoom distance between the camera & the object
& it didn’t work.

What am I doing wrong here?

You need to be more precise than “it didn’t work”. We can’t help you with things that “don’t work”.

What is the issue? Are you getting compile errors? Does it appear to have no effect at all? Does the Debug.Log appear to be printing the correct value? etc

Something like this?

j1gvt1

@alexeu : when the camera gets zoomed in either by the mouse wheel or by the camera collision, if the camera gets close enough, then the player fades out based on the distance between the camera & the player until it reaches full transparency.

EDIT : If you can use Fade mode as default mode for your shader go to
the link above and further for a simple and efficient solution with full
transparency!
https://forum.unity.com/threads/zoom-transparency.1078997/#post-6967496

yes i understood that.
I used transparency to make objects that hide the player from camera, transparent, and it works good. BUT i did not use a smooth transition for that. THIS is the main problem. Some tips to know about Transparency:

1: I know nothing about shaders, i don’t know what _DstBlend or _ZWrite mean. For my needs i saw some documentations, some peaces of codes… hummmm Alien language for me Ha Ha Ha. Respect for people who
manipulate shaders sooo easily. But i can say that : without theses things, IT DOES NOT WORK…
2 : depending on your shader, it will be very difficult to reach the level of transparency you can reach by setting directly the transparency in the inspector (why that ? i don’t know…) see the vid below

4rzp5l

3: More important:
Since the Opaque mode has been selected, smooth fade from transparent to opaque seems not possible…Wathever the current value of Transparency. (same vid above) but you maybe don’t need it…

4: the more currentDistanceToPlaer / maxDistanceToPlaer has a value near from 1(0.9 for ex) the best the fading works (From opaque to transparent)

5: necessery ! You can’t use transparency if you dont set the shader’s Rendering mode to Transparent.
Same for the other Rendering modes

So it wasn’t that hard to adapte my code to this in a basic scene with a basic shader. vid below
voy5t9
Take a look to the transparency bar behaviours, depending on the Threshold’s value

the code is ofcourse perfectible… im not a coder hahaha!!!

using UnityEngine;

public class Transparency : MonoBehaviour
{
    public GameObject player;
 
    [Range(0.5f, 1.0f)]
    public float transparencyThreshold;//UNDER this value, transparency begins.
 
    private float currentDistanceToPlayer;
    private float maxDistanceToPlayer;
    private float distancePercentage;

    private Material[] materials;
    private Renderer rend;

    void Start()
    {
        maxDistanceToPlayer = Vector3.Distance(transform.position, player.transform.position);
    }

    // Update is called once per frame
    void Update()
    {
        currentDistanceToPlayer = Vector3.Distance(transform.position, player.transform.position);
        distancePercentage = currentDistanceToPlayer / maxDistanceToPlayer;

        if (distancePercentage <= transparencyThreshold)// try 0.9f value then 0.5 value and see the behaviour of the transparency Bar.
        {
            PlayerTransparency();
        }
        else
        {
            PlayerOpacity();
        }
    }
    private void PlayerTransparency()
    {
        rend = player.GetComponent<Renderer>();
        if (rend != null)
        {
            materials = rend.materials;
            foreach (Material mat in materials)
            {
                mat.SetFloat("_Mode", 3); // 3 = transparent
                mat.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
                mat.SetInt("_ZWrite", 0);
           
                if (mat.HasProperty("_Color"))//Color transparency
                {
                    Color col = mat.GetColor("_Color");
                    col.a = distancePercentage;//Works good Depending on [transparencyThreshold]... BUT never reach the
                    //level of transparency you can set directly in the inspector ( WHYYY ?? )... and the shader become more shiny!!!
                    //col.a *=  (1f - distancePercentage) ; // Ugly transparency transition.
                    //col.a =  1f - distancePercentage; // Nice transparency transition but col.a oscilate only between 0.5f and 1
                    //SO How to have a smooth transition ?
                    mat.SetColor("_Color", col);//Applaying transparency.
                }
                mat.EnableKeyword("_ALPHABLEND_ON");
                mat.renderQueue = 3000;
            }
        }
    }
    private void PlayerOpacity()
    {
        if (materials != null && materials.Length > 0)
        {
            foreach (Material mat in materials)
            {
                mat.SetFloat("_Mode", 0); // 0 = Opaque
                mat.SetInt("_ZWrite", 1);
           
                if (mat.HasProperty("_Color"))
                {
                    Color col = mat.GetColor("_Color");
                    //Since the Opaque mode has been selected, smooth transition is not possible this way...
                    //Wathever the value of [transparencyThreshold].
                    col.a = 1; // Just to be sure the transparency is sat to its default value.
                    mat.SetColor("_Color", col);//Applaying opacity.
                }
                mat.DisableKeyword("_ALPHABLEND_ON");
                mat.renderQueue = 2000;
            }
        }
    }
}

Here’s a simple version:

Create a Material using the Standard Shader
Set Rendering Mode to Fade
Set the alpha of the Albedo from 1 (opaque) to 0 (transparent), this is what the distance will control
(Optional) Choose a texture for the Albedo
(Optional) Set the RGB of the Albedo to a tint color

using UnityEngine;

public class testTranspMat : MonoBehaviour
{
    // Put script on a GameObject with a renderer
    // The renderer needs a Material on it which uses the Standard Shader, Rendering Mode "Fade"
    Material myMat;

    [Range(0.1f, 10)]
    public float fadeRate = 0.5f;

    void Start()
    {
        myMat = GetComponent<Renderer>().material;
    }

    void Update()
    {
        // This is where you'd scale your distance value to (0, 1) to set the alpha level

        // For this example, instead of distance, we'll fade the material in and out using fadeRate
        // The +1 and *0.5f is just to scale the sin output from (-1, 1) to (0, 1)
        myMat.color = new Color(1, 1, 1, ((Mathf.Sin(Time.time * fadeRate) + 1) * 0.5f));
    }

}
1 Like

Awsome! works prety good.

 myMat.color = new Color(1, 1, 1, ((Mathf.Sin(Time.time * fadeRate) + 1) * distancePercentage));
1 Like

I maybe don’t make the test properly but there is a little issue. if you stop moving while you’re applying transparency, the color keep oscilating between opaque and transparent. How to fix this?
But the transparency is full and realistic !!!
i dont need this in my pseudoprojects, but its sooo interesting :slight_smile:

1 Like

So i made a test with my code using Fade mode as default mode (this depend on the shader and the result expected…) and it works as never… With a full transparency.

g2fdoa

using UnityEngine;

public class Transparency : MonoBehaviour
{
    public GameObject player;
 
    [Range(0.5f, 1.0f)]
    public float transparencyThreshold;//UNDER this value, transparency begins.
 
    private float currentDistanceToPlayer;
    private float maxDistanceToPlayer;
    private float distancePercentage;

    private Material[] materials;
    private Renderer rend;

    void Start()
    {
        maxDistanceToPlayer = Vector3.Distance(transform.position, player.transform.position);
    }

    // Update is called once per frame
    void Update()
    {
        currentDistanceToPlayer = Vector3.Distance(transform.position, player.transform.position);
        distancePercentage = currentDistanceToPlayer / maxDistanceToPlayer;

        if (distancePercentage <= transparencyThreshold)// try 0.9f value then 0.5 value and see the behaviour of the transparency Bar.
        {
            PlayerTransparency();
        }
        else
        {
            PlayerOpacity();
        }
    }
    private void PlayerTransparency()
    {
        rend = player.GetComponent<Renderer>();
        if (rend != null)
        {
            materials = rend.materials;
            foreach (Material mat in materials)
            {
                //mat.SetFloat("_Mode", 3); // 3 = transparent
                mat.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
                mat.SetInt("_ZWrite", 0);
          
                if (mat.HasProperty("_Color"))//Color transparency
                {
                    Color col = mat.GetColor("_Color");
                    col.a = distancePercentage;
                    mat.SetColor("_Color", col);
                }
                mat.EnableKeyword("_ALPHABLEND_ON");
                mat.renderQueue = 3000;
            }
        }
    }
    private void PlayerOpacity()
    {
        if (materials != null && materials.Length > 0)
        {
            foreach (Material mat in materials)
            {
                //mat.SetFloat("_Mode", 2); // 2 = Fade
                mat.SetInt("_ZWrite", 1);
          
                if (mat.HasProperty("_Color"))
                {
                    Color col = mat.GetColor("_Color");
                    col.a = distancePercentage;
                    mat.SetColor("_Color", col);//Applaying opacity.
                }
                mat.DisableKeyword("_ALPHABLEND_ON");
                mat.renderQueue = 2000;
            }
        }
    }
}

EDIT: it seems that, since Fade mode is selected by default, it’s not needful to set the mode.
I disabled the lines 45 & 66

1 Like

Cool, glad you like it! Video looks good.
I just made it oscillate to demonstrate the transparency, it will go forever. Just use the distance value, don’t multiply it by the Mathf.Sin, because that will continue to oscillate.

1 Like

Finaly and thank you seejayjames :), the code could be more simple than above…
if using Fade mode by default for your shader is conceivable. In effect Some shaders or
some materials turn immediately into transparent when Fade mode is selected.

using UnityEngine;

public class Transparency : MonoBehaviour
{
    ////USED WITH SHADER ON FADE MODE BY DEFAULT. Depending on the shader & the behaviour expected. ////
// Thank you seejayjames :)

    public GameObject player;
 
    [Range(0.5f, 1.0f)]
    public float transparencyThreshold;//UNDER this value, transparency begins.
 
    private float currentDistanceToPlayer;
    private float maxDistanceToPlayer;
    private float distancePercentage;

    private Material[] materials;
    private Renderer rend;

    void Start()
    {
        maxDistanceToPlayer = Vector3.Distance(transform.position, player.transform.position);
    }

    // Update is called once per frame
    void Update()
    {
        currentDistanceToPlayer = Vector3.Distance(transform.position, player.transform.position);
        distancePercentage = currentDistanceToPlayer / maxDistanceToPlayer;

        if (distancePercentage <= transparencyThreshold)
        {
            PlayerTransparency();
        }
    }
    private void PlayerTransparency()
    {
        rend = player.GetComponent<Renderer>();
        if (rend != null)
        {
            materials = rend.materials;
            foreach (Material mat in materials)
            {
                if (mat.HasProperty("_Color"))
                {
                    mat.color = new Color(mat.color.r, mat.color.g, mat.color.b, distancePercentage);
                }
            }
        }
    }
}

Just when I thought this code worked, for some reason when I got my new laptop, I switched from 1366x768 to 1920x1080 & when I go to zoom, it works but the camera has to be way up close to the object before it starts to fade. It worked fine on the 1366x768 laptop. How to fix this code to work with any resolution & / or device?

That’s bizarre, I wonder if something else is interfering with it. Screen resolution shouldn’t matter (should it??), the camera distance is completely within the Unity world…

1 Like

No idea if Unity Units are resolution-depending… resolution is for screen normaly…
Try to log the distance in the 2 computers (At start for ex) and see if there is a difference.

lol Hey Jay:)

1 Like