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. Voting for the Unity Awards are OPEN! We’re looking to celebrate creators across games, industry, film, and many more categories. Cast your vote now for all categories
    Dismiss Notice
  3. Dismiss Notice

Help needed on Shader for 2D

Discussion in 'Shaders' started by jg_edag, Jun 8, 2018.

  1. jg_edag

    jg_edag

    Joined:
    Nov 28, 2016
    Posts:
    2
    Hi there, anybody have a clue on how I can do a shader that does some effect like this? This shoudl be also blended off in terms of alpha value as close as the squares are painted top the middle of the manin square.




    I'm fairly new to shader creation and tried to find appropriate start points. As I expect this to be a very easy one I tried to experiement with if else loops in shaders which generally seems to be a bad idea as I read somewhere. So I tried to find a way when using a surface shader. Is this the right approach?

    I stumble at the logic on what to use to find out which pixel withon the proper mesh is curretnly rendered by the shader. I experimented with this:


    Code (CSharp):
    1.  
    2. Shader "Custom/SQUARES" {
    3.     Properties{
    4.         _TintColor("Tint Color", Color) = (1,1,1,1)
    5.         _Threashhold("Threashhold", Range(0.0,20.0)) = 1
    6.     }
    7.         SubShader{
    8.         Tags{ "RenderType" = "Opaque" }
    9.         CGPROGRAM
    10.         #pragma surface surf Lambert
    11.         struct Input {
    12.             float2 uv_MainTex;
    13.             float4 screenPos;
    14.         };
    15.  
    16.         float4 _TintColor;
    17.         float _Threashhold;
    18.  
    19.     void surf(Input IN, inout SurfaceOutput o) {
    20.         float4 objectPos = mul(UNITY_MATRIX_MVP, IN.screenPos);
    21.         o.Albedo = step(objectPos.x, _Speed) * _TintColor;
    22.     }
    23.     ENDCG
    24.     }
    25.  
    26.     Fallback "Diffuse"
    27. }

    But this seems to be wrong and I can't find a proper Threashhold to color up a square for example in half and half. The preview in the Inspector shows a filling ball but the proper object doesn't.

    Anybody ave a start for me?
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,230
    I discuss this a bit on this thread, which is for a shader with a similar goal.
    https://forum.unity.com/threads/rad...-improve-gpu-performance.530152/#post-3488747

    Short version is loops and if statements aren't as scary as people think they are, but you are correct that you shouldn't use them most of the time.

    Does this effect need to be lit? If not, don't use a surface shader.

    I have no idea what that line of code would do. The IN.screenPos value is one that comes from applying that matrix to the model's vertex position. Applying the same matrix to the screen position might by chance produce something useful from certain contrived situations (objects centered in the world with no rotation with a camera with no rotation), but most of the time it'll produce junk.

    For what you're trying to do, this may be more what you're looking for?
    https://realtimevfx.com/t/camera-facing-uvs/384/36

    However with out more information on what exactly your end goal and use case is there may be easier ways to go about this.
     
  3. jg_edag

    jg_edag

    Joined:
    Nov 28, 2016
    Posts:
    2
    Hi there,

    thank you very much for the quick help. I managed it to get the circles be drawn and also managed it to implement two properties for the number of circles; this was not a big deal. Just a short question: In which line of code is the definition of that circles should be drawn? I do not see any sine or cosine functions or something of that type.

    No I don't need it to be lit.

    Actually I can't 100% for sure explain that as well but you are right this produces junk due to your explanation



    Of course, this is the effect I'm looking for. A square that is having subsquares inside it and gets more alpha faded as close as the sub squares are surrounding the center. Thsi should be cusotmizable (via Properties for example) in terms of count of squares or padding of squares or where the alpha should start to fade. Actually also it would be nice if this could be rotatet to have the square being rotatable.

    upload_2018-6-11_11-57-3.png
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,230
    By far the easiest solution for this would be to just have the shader on a mesh quad and use the mesh's UVs. That way you can trivially rotate it and move it around the screen.

    As for the stepped alpha, that's also pretty simple. If you have a value from 0.0 to 1.0 (like from a mesh UV) you can do something like this:

    float steppedX = floor(x * _NumSteps) / _NumSteps;

    For the square shape, the UVs on a quad go from 0.0, 0.0 in the bottom left to 1.0, 1.0 in the top right. You can remap that to -1 to 1 with uv * 2.0 + 1.0, then take the absolute max component, and that should get you a square shaped gradient. That'll get you most of the way there, but doing just this will never reach a value of 1.0. For that you'll want to tweak the UV slightly to allow it to go beyond the -1.0 to 1.0 range the vertex shader outputs. You can get that to be 1 step worth with:

    // vertex shader
    o.uv = (i.texcoord * 2.0 - 1.0) * (_NumSteps + 1.0 / _NumSteps);

    // fragment shader
    float2 squareGradient = max(abs(i.uv.x), abs(i.uv.y)):
    float steppedGradient = saturate(floor(squareGradient * _NumSteps) / _NumSteps);