Почему порядок, по-видимому, несвязанных входных данных и униформ GLSL-программ влияет на компиляцию шейдеров в MacOS? - PullRequest
1 голос
/ 25 апреля 2020

Я включаю все содержимое каждого шейдера для полноты. Как указано в комментариях к коду, размещение матрицы uniform после in s заставляет in s поменяться местами в MacOS Chrome (in s правильно работает на Linux и Windows, независимо от положения uniform). Под «переключением мест» я подразумеваю, что данные в атрибуте 0 считываются в instancePosition, а данные в атрибуте 1 считываются в position.

Мои вопросы:

  1. Почему это происходит? (Это определенно ошибка, о которой я должен сообщить? Я что-то не так делаю?)
  2. Каковы некоторые рекомендации, позволяющие избежать подобных проблем совместимости с ошибками? В прошлом я использовал три. js фреймворк, и он кажется невосприимчивым к таким проблемам, но я не вижу большой разницы между кодом фреймворка и моим.
  3. Если это ошибка, вероятно, это связано с выравниванием памяти 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 с».

...