В GLSL (330 или иначе) что может привести к тому, что единообразная структура будет вести себя иначе, чем переменная структура? - PullRequest
0 голосов
/ 30 августа 2018

У меня странная проблема в OpenGL 3.3. Я определил структуру с именем Dual с vec4 членами "u" и "v" и начал писать и тестировать функции, такие как "сэндвич-продукт", который вы увидите позже в моем фрагменте (я включил реализацию, но это должно быть неактуально.) Во время этого тестирования я использовал две отдельные формы vec4, называя их «u» и «v», чтобы прояснить их будущую цель, и просто сделал Duals на лету из них. Когда я был удовлетворен поведением, я сделал единый Dual, называемый «модель» (как в модели-проекции), и начал обмениваться ссылками на автономные векторы для ссылок на члены модели. У меня черный экран, но ошибок нет.

Я переделывал свой вершинный шейдер, пока проблема не может быть включена / отключена, просто переключая комментарии в две строки:

#version 330

struct Dual { vec4 u, v; };

// (...)

// This should be agnostic to where the args come from
// It was and is correct given local variables/values
Dual sandwich(Dual u, Dual v) { return mul(mul(u, v), conj(u)); }

uniform mat4 projection;

const vec4 u0 = vec4(1,0,0,0), v0 = vec4(0,0,0,0);
uniform vec4 u = u0, v = v0;
uniform Dual model = Dual(u0, v0);

in vec4 pos_in;
out vec4 pos_out;

void main(){
        // Swizzling 'xyz' and then 'yzw' adapts GLSL 'xyzw' to/from 'wxyz'
        // It may look strange, but again, it works for local values
        Dual x = Dual(u0, vec4(0, pos_in.xyz)),
                // mxm = sandwich(model, x); // -> big black canvas
                mxm = sandwich(Dual(u, v), x); // -> big rainbow square
        gl_Position = projection * vec4(mxm.v.yzw, 1);
        pos_out = gl_Position;
}

В моем коде C ++ я пытался установить значения один раз после инициализации, один раз для нажатия клавиши для разных пресетов, даже один раз для кадра, но сейчас я полагаюсь на инициализацию по умолчанию в шейдере, пока я не нажму ключ - вот как это выглядит:

auto mu = program.locate("model.u"), mv = program.locate("model.v"),
        u = program.locate("u"), v = program.locate("v");
// ...key 1 is pressed, so set both pairs to the Dual identity...
glUniform4f(mu, 1, 0, 0, 0); glUniform4f(mv, 0, 0, 0, 0);
glUniform4f(u, 1, 0, 0, 0);  glUniform4f(v, 0, 0, 0, 0);
// ...key 2 is pressed, set both to something else, and so on

Конечно, мое первое предположение состояло в том, что я неправильно определил местонахождение участников, но это синтаксис, который я видел в другом месте, и я тоже не вижу опечатку. Поскольку с неизвестным именем нет связанной ошибки, я проверил расположение контрольной цифры -1, но model.u и model.v сообщают 0 и 1 соответственно.

Используя константы "u0" и "v0" для инициализации элементов vec4 и модели, но в качестве проверки работоспособности я попытался инициализировать их по значению. Поведение было точно таким же, как и должно быть - почему будет использовать значение, чтобы получить результат, отличный от переменной, инициализированной для этого значения? Даже если я сыграю адвоката дьявола и предположу, что есть какая-то разница, почему эта же проблема не повлияет на отдельные "u" и "v", когда они инициализируются в именованные переменные "u0" и "v0" в отличие от значения им дали?

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

1 Ответ

0 голосов
/ 30 августа 2018
const vec4 u0 = vec4(1,0,0,0), v0 = vec4(0,0,0,0);
uniform vec4 u = u0, v = v0;
uniform Dual model = Dual(u0, v0);

Эти три строки инициализируют u0, v0, u, v, model. Эти инициализации с предоставленными значениями выполняются во время соединения .

Я не могу найти в спецификации GLSL ни слова о порядке глобальных переменных. Ближайшее, что я нашел, это 4.2 Scoping :

Внутри объявления область имени начинается сразу после инициализатор, если он присутствует, или сразу после объявления имени, если нет.

Но «объем» - это не то же самое, что «порядок или инициализация».

Таким образом, возможно, что model инициализируется до u0, v0, и поэтому эти значения не определены.

Безопасный способ (который не зависит от реализации разных поставщиков) не полагается на другие глобальные переменные, а вместо этого использует:

uniform Dual model = Dual(vec4(1,0,0,0), vec4(0,0,0,0));
...