Фрагмент шейдера ведет себя неожиданно (тестовая сетка) - PullRequest
2 голосов
/ 01 ноября 2019

Я пытаюсь написать простой фрагментный шейдер для отображения сетки (или, скорее, шаблона проверки) на многоугольнике. Я хочу, чтобы этот шаблон «оставался на месте», т. Е. Когда сам многоугольник перемещается, квадраты остаются на одном и том же месте, поэтому результирующий шаблон как бы скользит по поверхности шаблона.

Я разрабатываюэто в Java с использованием LWJGL для встроенной системы на основе ARM, и я могу отлаживать как на удаленном устройстве ARM, подключенном к моему ПК, так и локально на самом ПК. Для этого я использую intelliJ.

На ПК моя программа по умолчанию использует OpenGL 3.2. В ARM контекстом является OpenGL ES 3.0. Графическая карта на ARM Vivante GC 2000.

Вот проблема: локально, на моем ПК, шейдер работает безупречно, как я и хочу. Но когда я перехожу к ARM - паттерн дрожит, искажается и не синхронизируется между двумя треугольниками, составляющими мой многоугольник. Интересным фактом является то, что шаблон изменяется и перемещается в зависимости от положения камеры, даже если шейдер использует для расчетов только ModelMatrix и вершинные положения плоскости, которые между кадрами остаются одинаковыми (я проверял). И все же положение камеры как-то сильно влияет на результат, чего не должно быть.

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

#version 300 es

layout (location=0) in vec3 position;

uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;
uniform mat4 modelMatrix;

out highp vec3 vertexPosition;

void main()
{   
    // generate position data for the fragment shader
    // does not take view matrix or projection matrix into account
    vec4 vp = modelMatrix * vec4(position, 1.0);
    vertexPosition = vec3(vp.x, vp.y, vp.z);

    // position data for the OpenGL vertex drawing
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}

фрагментный шейдер:

#version 300 es

precision highp float;

in highp vec3 vertexPosition;

out mediump vec4 fragColor;

void main()
{
    highp float c = float((int(round(vertexPosition.x/5.0))+int(round(vertexPosition.z/5.0))) % 2);

    fragColor = vec4(vec3(c/2.0 + 0.3), 1);
}

Как вы можетеПонимаете, я пытался возиться с точностью операций с плавающей точкой, увы, безрезультатноВы также можете заметить, что только положение в полях многоугольников modelMatrix и Vertex влияет на fragColor, и я могу гарантировать, что я их обрезал, и они не меняются между вызовами шейдеров, но каким-то образом движение камеры влияет на результирующие цвета / узоры фрагмента.

Также стоит отметить, что никакие другие текстуры на объектах сцены, кажется, не затронуты проблемой

Вот несколько скриншотов:

Как это выглядит локально(все работает):

enter image description here

Вот как это выглядит на устройстве ARM. enter image description here

Обратите внимание на текстуры, смещенные между треугольниками, и между ними есть странная линия, которая, кажется, полностью заполнена совершенно другим набором правил. Проблема не появляется на всех углах обзора - только некоторые. Если я указываю камеру в других направлениях, иногда я могу перемещать ее довольно свободно, без видимых артефактов.

Еще одна вещь, которую я заметил, состоит в том, что чем больше мой многоугольник, тем больше возникает дрожание и артефакты, которыезаставляет меня поверить, что это связано с точностью / вычислением либо положения вершин (в вершинном шейдере), либо положения фрагмента относительно этих положений вершин в части шейдера фрагмента.

Редактировать: I 'мы проверили точность с плавающей точкой, используя glGetShaderPrecisionFormat (GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, range, precision);и то же самое на локальном ПК и MTU. Так что этого не должно быть, если только вам не нужно как-то специально включить какой-то флаг, который я пропускаю.

Редактировать: И еще одна вещь, которую я заметил, это то, что локально на ПК появляется небольшой тестовый блокцентр одной из площадей. А на ARM квадраты сдвинуты наполовину, поэтому он стоит прямо на пересечении (если я выровняю камеру, чтобы не возникало артефактов). Не могу правильно объяснить это, потому что, на мой взгляд, расчет должен дать тот же результат.

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

Ответы [ 2 ]

2 голосов
/ 01 ноября 2019

Таким образом, в конце концов это была смесь двух проблем:

1) Оператор% работает по-разному в OGL 3.2 и OGLES 3.0. В первом случае он всегда возвращает положительное целое число, даже если операнды были отрицательными. Т.е. 3% 2 = -3% 2 = 1 В OpenGL ES, однако, он фактически поддерживает знак.

2) Это была проблема точности. Я работаю в высоких положительных координатах, поэтому моя координата vertexPosition заканчивается в диапазоне 10k положительных. Когда я беру сумму, она может доходить до 20к. Похоже, даже с плавающей запятой highP недостаточно для поддержания адекватной точности при таких больших числах, поэтому он в конечном итоге ломается. Что является ODD, потому что диапазон высокой точности показывает как -2 ^ 127 ~~ 2 ^ 127, что должно быть достаточно для моих расчетов. Но это как-то не так. Мое решение состояло в том, чтобы нормализовать координаты, уменьшив значение до <10. </p>

Если кто-то может более подробно рассказать о том, что я могу сделать - дайте мне знать!

0 голосов
/ 07 ноября 2019

Проблемы с моим шейдером все еще существуют. «Текстура» многоугольника искажается при некоторых углах обзора. Я нашел здесь еще один вопрос, который в значительной степени совпадает с тем, который я испытываю, и на него есть немного обходного ответа. Я свяжу это здесь. Полигон обрезки перспективной проекции OpenGL с вершинным внешним усечением = неправильное наложение текстуры?

...