Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question How to get a "shimmer" shader to work?

Discussion in 'Shader Graph' started by devtanc, Jul 22, 2023.

  1. devtanc

    devtanc

    Joined:
    Jul 15, 2022
    Posts:
    1
    Hello all!

    I have worked for hours on this, and have been able to get a preview that shows what I'd like to have happen. As I adjust the "position" variable, the white gleam passes across the sprite image. That's all I'm trying to accomplish, but this is my first foray into shaders in general, and I've run into an issue. While the preview looks great, when I try to apply this to a piece of UI in my world, it doesn't show there when I move the slider. This is the shader graph for the 2d unlit sprite:

    upload_2023-7-22_0-17-6.png

    This is where it's being used on an image component in my UI:
    upload_2023-7-22_0-19-46.png

    And this is what it looks like in the scene view (the block bar):
    upload_2023-7-22_0-20-14.png

    I would hope that with the current slider value in the scene, I would see a white bar about 1/3 of the way from the left side, but no matter the adjustment in the slider, nothing changes on the texture. This is the sprite that is my image:

    upload_2023-7-22_0-21-20.png

    I've been trying various things for hours, but nothing seems to accomplish the desired effect.
    This is a choppy version of what I want:
    shimmer.gif

    Ideally, that white line would wipe smoothly across the sprite to give a shimmer effect.
     
    Last edited: Jul 23, 2023
  2. FredMoreau

    FredMoreau

    Unity Technologies

    Joined:
    May 27, 2019
    Posts:
    108
    Hi @devtanc,

    I'm happy to see some question regarding a use case that UI Integration enables in 2023.2.

    Let me try to address your question.
    First, make sure you set your Shader Graph to use the Canvas Target (Built-in, URP or HDRP) as described in this how-to tutorial.

    Now, making the "shimmer" effect is pretty trivial. Here's a break down of a texture-less possible implementation.
    Screenshot 2023-07-24 at 1.10.42 PM.png

    The above recipe takes a normalized coord. space to make the shimmer effect.

    What's a bit less trivial, is that since you are using 9-sliced images, the UVs of the meshes generated by the Canvas will stretch as to making the borders of the UI elements stay the same will the middle stretches.
    The generated mesh and its UVs will be based on the Canvas Scale Factor and Reference Pixels Per Unit, as well as the Image PPU settings and UI Image size.

    In other words, the result will probably look like this:
    Screenshot 2023-07-24 at 1.19.26 PM.png

    So, to make fit nicely and not distort, you may either use a C# script to put normalized position in UV.zw, using the BaseMeshEffect API, or use Position and Object nodes to build a Canvas relative normalized position.

    Here's how you may create it in Shader Graph with some branching using a Dropdown property in a Sub Graph.
    Screenshot 2023-07-24 at 1.11.00 PM.png

    And here's a code example of how you can put Normalized vertex positions in UV.zw channels with BaseMeshEffect.

    Code (CSharp):
    1. [AddComponentMenu("UI/Effects/Normalized Position As UV0.ZW", 82)]
    2. public class NormalizedPositionAsUV0ZW : BaseMeshEffect
    3. {
    4.     protected NormalizedPositionAsUV0ZW()
    5.     { }
    6.  
    7.     public override void ModifyMesh(VertexHelper vh)
    8.     {
    9.         Bounds bounds = new Bounds();
    10.  
    11.         UIVertex vert = new UIVertex();
    12.         for (int i = 0; i < vh.currentVertCount; i++)
    13.         {
    14.             vh.PopulateUIVertex(ref vert, i);
    15.             bounds.Encapsulate(vert.position);
    16.         }
    17.  
    18.         for (int i = 0; i < vh.currentVertCount; i++)
    19.         {
    20.             vh.PopulateUIVertex(ref vert, i);
    21.  
    22.             var normalizedPosition = new Vector2(
    23.                 Mathf.InverseLerp(bounds.min.x, bounds.max.x, vert.position.x),
    24.                 Mathf.InverseLerp(bounds.min.y, bounds.max.y, vert.position.y));
    25.  
    26.             vert.uv0 = new Vector4(vert.uv0.x, vert.uv0.y, normalizedPosition.x, normalizedPosition.y);
    27.  
    28.             vh.SetUIVertex(vert, i);
    29.         }
    30.     }
    31. }
    What it'll look like in Canvas space:
    Screenshot 2023-07-24 at 1.18.54 PM.png

    And what it'll look like in element's space, using normalized positions from UV.zw:
    Screenshot 2023-07-24 at 1.19.50 PM.png

    I hope this helps. I'm considering putting some Samples for UI effects. Please let me know if you have any more questions or suggestions.
     
    Qriva likes this.
  3. Finijumper

    Finijumper

    Joined:
    Jul 12, 2016
    Posts:
    75
    I would love to see some samples.