我以为我有它工作但我仍然无法弄清楚如何更改顶点着色器中的值。对于每个渲染,我在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(位置) 部分,并将float用作 const 制服 然后我的着色器工作正常。但我希望能够在每个渲染中更改着色器中的值。我虽然必须使用制服......?
有什么东西我不见了...... ??
修改
显然我收到以下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();
}
答案 0 :(得分:1)
您必须在顶点着色器中声明您的制服,如下所示:
uniform float Test;
此外,在调用glUseProgram()
之前,您必须使用程序对象句柄调用glUniform1f()
,因此请确保这是shader.bind()
所做的。如果您调用glGetUniformLocation()
一次并缓存结果就足够了。另外,使用glGetError()
检查OpenGL调用的错误,以确保其他所有内容都正常工作。
回复你的编辑,我认为这一行是你的问题:
const float F = ((1.0-Eta) * (1.0-Eta)) / ((1.0+Eta) * (1.0+Eta));
const
表示编译时间常量,因为该值不能通过统一更改。 F
不能是常量,因为统一变量不是(编译时)常量。将声明F
的行移动到main
的主体并删除const限定符。然后你的着色器应该工作。
答案 1 :(得分:1)
uniform float Eta; // <---- MUST BE CONSTANT...
当GLSL说“常量”时,它意味着编译时常量。 Eta
的值在特定绘制调用中肯定是统一的。但它不是恒定的,因为它可以在绘制调用之间改变。编译器在编译时不知道该值是什么。
const
变量是编译时常量。因此必须使用仅包含编译时常量的表达式对其进行初始化。 uniform
不是编译时常量,因此您无法使用它们初始化const
变量。