0

我正在浏览http://arcsynthesis.org/gltut/Positioning/Tut03%20More%20Power%20To%20The%20Shaders.html上的教程

我目前正在学习创建一个三角形,将其沿圆形方向移动并逐渐将颜色从白色变为绿色。一个完整的循环后颜色会跳回白色。我试图使颜色逐渐从白色变为绿色并返回。我设置颜色更改方向的条件语句似乎永远不会评估为真,因此我的更改永远不会生效。

这是我的片段着色器。

#version 330

out vec4 outputColor;

uniform float fragLoopDuration; //5.0f
uniform float time;


const vec4 firstColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);
const vec4 secondColor = vec4(0.0f, 1.0f, 0.0f, 1.0f);

void main()
{
    bool myFlag = false; //flag will indicate which direction color change will take.
    float currTime = mod(time, fragLoopDuration);
    float currLerp = currTime / fragLoopDuration; //currLerp range = (0.0f-1.0f)
    if (currLerp == 0.9f) myFlag = !myFlag; //this flag is not geting triggered.
    if (myFlag) outputColor = mix(secondColor, firstColor, currLerp * -1.0f + 1.0f); //green to white
    if (!myFlag) outputColor = mix(firstColor, secondColor, currLerp); //white to green
}
4

1 回答 1

2

抱歉,问题是我设置标志的条件语句似乎永远不会评估为真。

你能指望什么?为了currLerp完全等于 0.9f,并且currTime必须fragLoopDuration是非常具体和非常精确的值。如果currTime稍微偏离 0.000001,则currLerp不会完全等于 0.9f,因此您的条件永远不会成立。

通常,您永远不应该测试 float 的相等性。也就是说,等于另一个值。

即使它完全相等,它也只会发生一次。所以它只在一帧上是正确的;下一帧,什么时候currLerp是0.95f什么的,又会是假的。

我猜你的意思是>=而不是==


顺便说一句,您的代码的结构不像大多数程序员那样。

你有你设置的这个标志。然后你有两条if语句,一条在标志为真时执行,一条在标志为假时执行。这是一种浪费和糟糕的编码风格。几乎每一种语言if都会有某种形式的else: 如果条件不成立就会发生的事情。

执行此操作的标准方法在这里:

if (myFlag)
  outputColor = mix(secondColor, firstColor, currLerp * -1.0f + 1.0f);
else
  outputColor = mix(firstColor, secondColor, currLerp);

而且由于您只使用myFlag一次,因此即使有一个变量也没有意义:

if (currLerp == 0.9f) //Fix this, of course
  outputColor = mix(secondColor, firstColor, currLerp * -1.0f + 1.0f);
else
  outputColor = mix(firstColor, secondColor, currLerp);
于 2012-03-27T23:20:09.090 回答