Search Unity

Avoiding multiple if's in vert shader

Discussion in 'Shaders' started by jister, Feb 21, 2018.

  1. jister

    jister

    Joined:
    Oct 9, 2009
    Posts:
    1,749
    hey
    2 questions:
    first: any idea how to rewrite this dropping the if?
    all i can come up with is using a max for the < 0 part.

    Code (CSharp):
    1. void vert(inout appdata_full v, out Input o)
    2. {
    3.     UNITY_INITIALIZE_OUTPUT(Input, o);
    4.     //0 <= dot(AB,AM) <= dot(AB,AB) &&
    5.     //0 <= dot(BC,BM) <= dot(BC,BC)
    6.     o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
    7.     half abam = dot(_Point1-_Point2, _Point1-o.worldPos);
    8.     half abab = dot(_Point1-_Point2,_Point1-_Point2);
    9.     half bcbm = dot(_Point2-_Point3, _Point2-o.worldPos);
    10.     half bcbc = dot(_Point2-_Point3,_Point2-_Point3);
    11.     if(0 <= abam && abam <= abab && 0 <= bcbm && bcbm <= bcbc)
    12.         //o.delta = clamp(max(0,abam),0,1)*clamp(max(0,bcbm),0,1);
    13.         v.vertex.y -= v.vertex.y;//*o.delta;
    14. }
    second: what cheapest calculating the 3 point in C# and passing them with Shader.SetGlobalVector() or passing a position and a direction with Shader.SetGlobalVector() and calculate the 3 points in the vert shader?

    Code (CSharp):
    1. Vector3 cross = Vector3.Cross (transform.forward.normalized * length, Vector3.up);
    2. Vector3 startPoint = transform.position - transform.forward.normalized*length;
    3. abcd[0].position = startPoint + cross.normalized * width/2;
    4. abcd[1].position = startPoint - cross.normalized * width/2;
    5. abcd[2].position = abcd[0].position + (transform.forward.normalized * length);
    6. abcd[3].position = abcd[1].position + (transform.forward.normalized * length);
     
    Last edited: Feb 21, 2018
  2. jister

    jister

    Joined:
    Oct 9, 2009
    Posts:
    1,749
    Auwtch!! nevermind :oops::rolleyes:

    Code (CSharp):
    1. o.delta = clamp(max(0,abam),0,1)*clamp(max(0,bcbm),0,1)*clamp(max(0,abab-abam),0,1)*clamp(max(0,bcbc-bcbm),0,1);
    2. v.vertex.y -= v.vertex.y*o.delta;
     
  3. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    You can use saturate(x) instead of clamp(x, 0, 1). A saturate on the outside is usually a free operation on desktop hardware. As in:
    a = saturate(b * c)
    And not
    a = -saturate(b) or a = saturate(b) * c

    Also, the max(0, x) is not needed inside the saturate. I'd rewrite it something like this:
    Code (csharp):
    1.  
    2. half4 temp = saturate(half4(abam, bcbm, abab, bcbc) - half4(0.0, 0.0, abam, bcbm));
    3. temp.xy *= temp.zw;
    4. o.delta = temp.x * temp.y;
    5.  
     
    jister and hippocoder like this.