0

I want to get the pixelcolor by interpolarating between 3 colors based on the models world Y position and the key height for the colors. I could use if statements, but that is a no-go on shader coding.

float _HeightMiddle = 10.0; //color = c0 at y=0 to c1 at y=10
float _HeightMax = 200.0;   //color = c1 at y=10 to c2 at y=200


fixed4 frag (v2f i) : SV_Target {  
    fixed4 c0 = fixed4(0.4, 0.4, 0.4, 1);
    fixed4 c1 = fixed4(0, 1, 1, 0.8);
    fixed4 c2 = fixed4(0, 1, 1, 0.2);

    fixed4 col = lerp(c0, lerp(c1, c2, i.worldPos.y / 200), i.worldPos.y / 10);
    return col;
}

But this gives wrong colors (using the colors above, the pixels on ground a.k.a. c0 are red instead of mig-grey).

Also somehow the shader produces different results when using variables so I hardcoded them.

Peter O.
  • 32,158
  • 14
  • 82
  • 96
Mc Midas
  • 189
  • 1
  • 5
  • 17

1 Answers1

0

My suggestion is to use a ternary operator, which honestly should compile to about the same thing as an if...else, but stylistically promotes your execution time to be the same for each run of the shader code. Another way of thinking about this, one if...else statement isn't going to mess up your shader unless you've extra execution happening in one of its branches. For more info, see the accepted answer here - Do conditional statements slow down shaders?

So you can run code something like this...

fixed4 col = (y < _HeightMiddle) ? 
   lerp(...for your first range...) : lerp(...for your second rage...)

Sorry, not going to go to the effort to write out an entire correct example. You sound like you'd pick up the concept pretty quickly without it.

Erik Hermansen
  • 2,200
  • 3
  • 21
  • 41
  • 1
    Thanks, yes youre right, one condition checking shouldnt bother. The ternary operator is nice, but normally slower than if-else statement. Anyways, regarding the 'wrong color' I noticed this is always some sort of negative color, so the t must be overshooting its ratio. I fixed the problem by clamping t: lerp(color1, color2, clamp ( i.worldPos / 200, 0, 1) ); – Mc Midas Jun 28 '20 at 00:20
  • @McMidas *"The ternary operator is nice, but normally slower than if-else statement*" According to whom? Ternaries are vector ops, they don't rely on branching (excluding GLSL) – arkon Jun 14 '22 at 18:57