Search Unity

Gradient Shader color overflow issue

Discussion in 'Shaders' started by JonPQ, Aug 8, 2017.

  1. JonPQ

    JonPQ

    Joined:
    Aug 10, 2016
    Posts:
    120
    I made a gradient shader.... it lerps from one color to another based on pow(UV.y + offset, param), and adds in some emissive color on top. NUmbers can go above 1.0 in r,g,b. then I clamp them 0-1.
    on iOS it works fine... on Android... the bottom third of the image (cyan sky at bottom, blue at top) appears dark red... like its dropping the green and blue. It looks like it is not clamping color in 0-1 range... but more like a 'floor to 0' function or something like that.
    I don't even think the color components are >1.0 at the bottom of the image .... any idea why the green and blue dissapear (on droid only ) ? or how to fix it?
    Thanks for any help in advance.
     
    Last edited: Aug 8, 2017
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,343
    Some phones are just kind of broken for certain things. There's likely not anything you're really doing wrong with your shader, but the shader compiler for that phone has a bug. The solution might be as simple as just fiddling with the shader a bit to break things apart into multiple lines, or try to do something in a slightly different way.

    For example, your code might look like this:

    float lerpValue = // some code
    fixed4 newColor = saturate(lerp(colorA, colorB, lerpValue));

    You could try doing:
    fixed lerpValue = // some code

    or
    fixed lerpValue = saturate( // some code );
    fixed4 newColor = lerp(colorA, colorB, lerpValue);

    or
    fixed lerpValue = saturate( // some code );
    fixed4 newColor = lerp(colorA, colorB, fixed4(lerpValue, lerpValue, lerpValue, lerpValue));

    etc etc.
     
  3. JonPQ

    JonPQ

    Joined:
    Aug 10, 2016
    Posts:
    120
    thanks bgolus, Good tips.
    Just solved it... I was doing a pow( UV.y+offset, powParam) to control the fade lerp value. so the offset could sometimes make the input to pow() negative.. which is invalid input to pow() (unless the powParam is a whole number (integer))
    I guess iOS just failed better than android implementation of Pow()
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,343
    Yep, that's the other thing most mobile GPUs will get you on. When they're not outright broken they'll be far more stringent on only supporting the spec's limitations. I assume you stuck a saturate() or max(0.001, value) there?
     
  5. JonPQ

    JonPQ

    Joined:
    Aug 10, 2016
    Posts:
    120
    yep indeed I did!