我尝试使用OpenGLES 2制作应用程序。有2个设备可供测试。 不幸的是,两者之间似乎存在差异。
我有以下用于测试的“基本”着色器代码:
// vertex shader
uniform mat4 uVMatrix; // View Matrix
uniform mat4 uPMatrix; // perspective Matrix
uniform vec3 uLight1Pos; // LightPos
attribute vec4 aPosition;
attribute vec4 aColor;
varying vec4 vColor;
void main() {
vColor = aColor;
mat4 MVPMatrix = uPMatrix * uVMatrix;
gl_Position = MVPMatrix * aPosition;
}
// fragment shader
uniform mat4 uVMatrix;
uniform vec3 uLight1Pos;
varying vec4 vColor;
varying vec3 vPosition;
void main() {
vec3 light2Pos = uLight1Pos;
gl_FragColor = vColor;
}
问题是,找不到一些制服。
我像往常一样附加和链接着色器,但检查ID如下:
uVMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uVMatrix");
uPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uPMatrix");
uLight1PosHandle = GLES20.glGetUniformLocation(mProgram, "uLight1Pos");
我得到不同的价值观。 在我的Galaxy S1上,它是 2,1,3 (所以所有有效值 - 即使是奇怪的顺序)。 在我的Galaxy S3上,它是 0,1,-1 (所以无法找到最后一个)。
我做错了什么?我是否必须在S3(Mali GPU)上以不同方式声明统一? 我意识到我必须“使用”制服以获得参考。这就是我写 vec3 light2Pos = uLight1Pos; 的原因如果我不这样做,我也没有参考S1。
感谢您的帮助!
托拜厄斯
- 编辑 -
奇怪的是,我试图将顶点着色器的制服从 vec3 更改为 mat4 :
uniform mat4 uLight1Pos;
mat4 lPos = uLight1Pos;
似乎矩阵工作正常,我可以在使用矩阵时获得它的句柄。怎么来的?
答案 0 :(得分:2)
你的"使用"没有对输出fragcolor有贡献。您刚刚证明S3具有比S1更好的编译器来删除死代码。
答案 1 :(得分:1)
GLSL编制者倾向于消除对结果没有贡献的未使用的制服。此行为符合OpenGL规范。
在您的情况下,允许编译器消除死区vec3 light2Pos = uLight1Pos;
,使uLight1Pos
统一无效。