OpenGL фрагмент шейдера условного оператора не срабатывает - PullRequest
0 голосов
/ 28 марта 2012

Я прохожу учебник на 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
}

1 Ответ

2 голосов
/ 28 марта 2012

Извините, проблема в том, что мое условное заявление об установке моего флага, похоже, никогда не оценивается как true.

Чего вы ожидаете?Чтобы currLerp было точно равным 0,9f, currTime и fragLoopDuration должны быть очень конкретными и очень точными значениями.Если currTime даже слегка отклонен, даже на 0,000001, то currLerp не будет точно равен 0,9f, и, следовательно, ваше условие никогда не будет истинным.

В общем, вы никогда не должны проверятьfloat для равенство .То есть равно другому значению.

И даже если оно точно равно, оно когда-либо произойдет только один раз .Так что это будет верно только на одном кадре;следующий кадр, когда currLerp равен 0,95f или около того, он снова будет ложным.

Я предполагаю, что вы имеете в виду >= вместо ==.


Кроме того, ваш код не структурирован так, как это делает большинство программистов.

У вас есть этот флаг, который вы установили.Затем у вас есть два оператора if, один из которых будет выполнен, если флаг имеет значение true, и один, который будет выполнен, если флаг равен false.Это пустой и плохой стиль кодирования.Почти каждый язык с 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);
...