Я включаю все содержимое каждого шейдера для полноты. Как указано в комментариях к коду, размещение матрицы uniform
после in
s заставляет in
s поменяться местами в MacOS Chrome (in
s правильно работает на Linux и Windows, независимо от положения uniform
). Под «переключением мест» я подразумеваю, что данные в атрибуте 0 считываются в instancePosition
, а данные в атрибуте 1 считываются в position
.
Мои вопросы:
- Почему это происходит? (Это определенно ошибка, о которой я должен сообщить? Я что-то не так делаю?)
- Каковы некоторые рекомендации, позволяющие избежать подобных проблем совместимости с ошибками? В прошлом я использовал три. js фреймворк, и он кажется невосприимчивым к таким проблемам, но я не вижу большой разницы между кодом фреймворка и моим.
- Если это ошибка, вероятно, это связано с выравниванием памяти OpenGL и GLSL для униформ и вариаций ?
вершинный шейдер
#version 300 es
uniform mat4 projectionViewMatrix; // Moving it here fixes the issue
layout (location = 0) in vec3 position; // Issue occurs with or without explicit "layout"
layout (location = 1) in vec3 instancePosition;
out vec3 vPosition;
out vec2 vUv;
uniform mat4 projectionViewMatrix; // Putting this line here causes the above position and instance position to be flipped on MacOS Chrome
void main(void) {
vec4 worldPosition = vec4(position + instancePosition, 1.0);
gl_Position = projectionViewMatrix * worldPosition;
vPosition = position;
vUv = vec2(worldPosition.x, worldPosition.z);
}
Фрагмент шейдера
#version 300 es
precision mediump float;
in vec3 vPosition;
in vec2 vUv;
out vec4 pc_fragColor;
uniform sampler2D uDiffuse;
void main(void) {
pc_fragColor = texture(uDiffuse, vUv) + vec4(0.25 - 0.1 * length(vPosition));
pc_fragColor.rgb *= vec3(smoothstep(1.0, 0.9991, gl_FragCoord.z)); // Fog
}
3 числа с плавающей точкой привязаны к атрибуту 0, а еще 3 числа с плавающей точкой связаны с атрибутом 1 с помощью
[bind first float32 buffer]
renderer.gl.EnableVertexAttribArray(0)
renderer.gl.VertexAttribPointer(0, 3, gl.FLOAT, false, 3 * 4, 0)
[bind second float32 buffer]
renderer.gl.EnableVertexAttribArray(1)
renderer.gl.VertexAttribPointer(1, 3, gl.FLOAT, false, 3 * 4, 0)
renderer.gl.VertexAttribDivisor(1, 1)
Примечание. При первом возникновении этой проблемы, в другом шейдере униформа была между in
с и out
с. Перемещение его после out
s решило проблему в то время. Это не просто проблема «всегда ставить uniform
с до in
с и out
с».