изменить float в вершинном шейдере (GLSL) - PullRequest
1 голос
/ 28 января 2012

Я думал, что у меня это работает, но я все еще не могу понять, как изменить значение в моем вершинном шейдере. В OpenGL я делаю следующее для каждого рендера:

//i bind my shader
shader.bind();

// Then trying to set the value in my vertex shader like so:
GLuint test = glGetUniformLocation(shader.id(), "Test");
glUniform1f(test, 6.0f);

// Do some other stuff like rendering an object
// ...

// then unbind shader
shader.unbind();

Это значение, которое я хочу изменить в моем вершинном шейдере:

uniform float Test = 0.66; // Doesn't work
//const float Test = 0.66; // Works

Но мой шейдер не работает, когда я пытаюсь это сделать, он делает мой объект черным.

Если я прокомментирую glGetUniform (Location) часть и если использовать float как const вместо равномерный тогда мой шейдер работает нормально. Но я хочу иметь возможность изменять значение в моем шейдере при каждом рендере. Хотя я должен был использовать униформу для этого ...?

Есть что-то, чего мне не хватает .. ??


EDIT:

По-видимому, я получаю следующую ошибку GLSL:

непостоянное выражение при инициализации

Таким образом, чтобы он работал, он должен быть постоянным ... Значит ли это, что нельзя иметь это динамическое значение? ..

Это мой вершинный шейдер:

const float FresnelPower = 1.0;
uniform float Eta;         // <---- MUST BE CONSTANT...

const float F  = ((1.0-Eta) * (1.0-Eta)) / ((1.0+Eta) * (1.0+Eta));

varying vec3  Reflect;
varying vec3  Refract;
varying float Ratio;

void main()
{
    vec4 ecPosition  = gl_ModelViewMatrix * gl_Vertex;
    vec3 ecPosition3 = ecPosition.xyz / ecPosition.w;

    vec3 i = normalize(ecPosition3);
    vec3 n = normalize(gl_NormalMatrix * gl_Normal);

    Ratio   = F + (1.0 - F) * pow((1.0 - dot(-i, n)), FresnelPower);

    Refract = refract(i, n, Eta);
    Refract = vec3(gl_TextureMatrix[0] * vec4(Refract, 1.0));

    Reflect = reflect(i, n);
    Reflect = vec3(gl_TextureMatrix[0] * vec4(Reflect, 1.0));

    gl_Position = ftransform();
}

Ответы [ 2 ]

1 голос
/ 28 января 2012
uniform float Eta;         // <---- MUST BE CONSTANT...

Когда GLSL говорит "константа", это означает константа времени компиляции .Значение Eta, безусловно, является одинаковым в конкретном вызове отрисовки.Но оно не является постоянным, потому что оно может изменять между вызовами отрисовки.Компилятор не знает, каким будет это значение во время компиляции.

Переменная const является константой времени компиляции .Поэтому его необходимо инициализировать выражением, состоящим только из констант времени компиляции.uniform s не являются константами времени компиляции, поэтому вы не можете инициализировать переменную const с ними.

1 голос
/ 28 января 2012

Вы должны объявить свою униформу в вершинном шейдере следующим образом:

uniform float Test;

Кроме того, перед вызовом glUniform1f() вы должны вызвать glUseProgram() с указателем вашего программного объекта, поэтому убедитесь, чтоshader.bind() делает.Достаточно один раз позвонить glGetUniformLocation() и кешировать результат.Также проверьте ошибки ваших вызовов OpenGL с помощью glGetError(), чтобы убедиться, что все остальное работает правильно.

Отвечая на ваши изменения, я думаю, что эта строка - ваша проблема:

const float F  = ((1.0-Eta) * (1.0-Eta)) / ((1.0+Eta) * (1.0+Eta));

const означает постоянную времени компиляции, так как значение не может быть изменено униформой.F не может быть константой, потому что универсальная переменная не является константой (времени компиляции).Переместите строку, которая объявляет F, в тело main и удалите квалификатор const.Тогда ваш шейдер должен работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...