В GLSL (330 или иначе) что может привести к тому, что единообразная структура будет вести себя иначе, чем переменная структура?

Я испытываю странную проблему в 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

Решение

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 Обзор:

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

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

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

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

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

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]