Точная передача относительного положения игрока в AGAL

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

У меня игра настроена так, что игрок всегда находится в «позиции вселенной» 0, 0, 0, и все объекты имеют свои transform.matrix3Ds, перемещаемые вокруг игрока, когда он движется.

Я должен отметить, что у меня несколько шейдеров работают нормально, некоторые из них включают смешивание текстур, интерполяцию между двумя моделями и зеркальное затенение; ЭТА проблема, однако, меня одолела.

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

Ну, видимо, нет. (Я мог бы объяснить, чем занимаюсь, но чувствую, что люди уже игнорируют этот вопрос ...). Может ли кто-нибудь сказать мне, КАК я могу правильно рассчитать направление на игрока, учитывая, что мне также нужно включить (Я ДУМАЮ) тот факт, что положения вершин модели «смещены» от центрального положения модели? Это делало мне голову!

Спасибо.

ИЗМЕНИТЬ

Вот соответствующий код AS3, за которым следует AGAL:

// invMatrix is a cloned and inverted copy of the Planet object's transform.matrix3D...
// .deltaTransformVector ONLY uses the matrix3D's rotation to rotate a vector3D...
var tempVector:Vector3D = invMatrix.deltaTransformVector(transform.matrix3D.position);
tempVector.normalize();
context3D.setProgramConstantsFromVector(Context3DProgramType.VERTEX, 5, Vector.<Number>([-tempVector.x, -tempVector.y, -tempVector.z, 0]));
context3D.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 7, rotMatrix, true);
... other constants set here ...
context3D.setVertexBufferAt(3, mesh.normalsBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);

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

"m44 v3, va3, vc7 \n" + // passed rotMatrix is used to rotate the face normals
"dp3 v4, vc5, va3 \n" + // put the dot product of the normalised, rotated camera position and the rotated normal in v4

Затем во фрагментном шейдере:

"mul ft0, ft0, v4 \n" + // multiply the sampled texture in ft0 by the passed dot product in v4

Но все это приводит к некоторому странному поведению при рендеринге, когда половина атмосферы кажется нарисованной, в зависимости от вашего положения относительно планеты. Непонятно. Любая помощь приветствуется.


person moosefetcher    schedule 25.11.2013    source источник


Ответы (2)


Вам нужно найти вектор от вершины до некоторой точки в пространстве? Если это так, вам просто нужно работать в одном кадре, скажем, в мировом кадре. Для этого вам нужно знать желаемое положение в мировом пространстве, и вам нужно преобразовать ваши вершины в мировое пространство (просто умножьте на матрицу модели).

person nikitablack    schedule 27.11.2013
comment
Спасибо за ответ. Я не вдавался в подробности выше, извините, но то, что вы описываете, - это то, что я делаю. Я передаю обратную позицию объекта во фрагментный шейдер. Я также передаю матрицу вращения объекта и с ней вращаю позиции вершин. Затем я добавляю повернутое положение вершины к положению обратного объекта. Это должно дать мне направление к камере от фрагмента, вычисляемого шейдером, но то, что я вижу, выглядит не так, как я ожидал. Похоже, что больше атмосферы «прорисовывается» вверху и внизу модели. Любые идеи? - person moosefetcher; 27.11.2013
comment
Это кажется правильным. Но позвольте мне прояснить некоторые шаги. 1. Такие вычисления нужно производить в вершинном шейдере. Почему вы передали обратное положение объектов во фрагментный шейдер? А почему обратное? 2. Вы упомянули, что передаете матрицу вращения. В фрагментном шейдере тоже? Ваш объект не переводится? - person nikitablack; 28.11.2013
comment
Я передаю матрицу вида модели (ее комбинированный перенос, масштаб и поворот) в регистр vc0. Я пробовал преобразовать буфер вершин модели с помощью этого регистра (как вы говорите, это делается в вершинном шейдере), а затем передать результат во фрагментный шейдер, но это тоже не сработало. Я попробую еще раз и посмотрю, как у меня дела. Я выполняю вычисление скалярного произведения в фрагментном шейдере, потому что я использую его, чтобы определить, насколько МНОГО из выбранной текстуры отрисовывается в этом пикселе. - person moosefetcher; 28.11.2013
comment
Итак, вы знаете направление камеры в мировом пространстве. И вам нужно взять скалярное произведение нормали с этим направлением. Вы можете сделать это в вершинном шейдере, преобразовав нормаль в мировое пространство, но это немного сложно, потому что у вас есть перевод и масштабирование. Лучшим подходом является преобразование направления камеры в пространство объекта в приложении и использование этого значения для скалярного произведения с нормальным. Результат нужно передать во фрагментный шейдер. - person nikitablack; 28.11.2013
comment
Но если я вычислю скалярный продукт в приложении, я буду использовать только один нормальный. Чтобы добиться желаемого затухания, мне, конечно же, нужно вычислить скалярное произведение в фрагментном шейдере, используя нормаль каждой грани, так что получаются разные скалярные произведения ... - person moosefetcher; 28.11.2013
comment
Извините - я думаю, что теперь понимаю, что вы имеете в виду: передайте преобразованное направление камеры в шейдер и скалярное произведение с нормалью лица в вершинном шейдере. Тогда возникает вопрос: как мне преобразовать направление камеры в пространство объекта? Это матрица обратного вращения? И мне все еще нужно добавить индивидуальное положение каждого пикселя относительно координат центра объекта? - person moosefetcher; 28.11.2013
comment
Да, я имею в виду передачу камеры шейдеру. Да, вам нужна обратная матрица. Если ваша матрица содержит вращение, масштабирование, перевод, то обратная операция немного сложна. Но в классе Matrix3D есть метод invert (). Если вы учитываете только направление камеры, вам не нужно учитывать позиции. P.S .: Если вы разместите упрощенный минималистичный код, будет намного проще все это объяснить. - person nikitablack; 29.11.2013
comment
Я добавил соответствующие части кода. Я буду продолжать пробовать варианты вышеперечисленного. Я пробовал НЕ вращать нормаль, а вращать переданное направление камеры. Я пробовал наоборот. Заканчиваются варианты ... - person moosefetcher; 29.11.2013

ОК - спасибо, Volgogradetzzz, за ответ; Вы определенно убедили меня, что я думаю в правильном «направлении». В конечном итоге это стало вопросом одновременного исправления многих вещей. Я закончил:
1) передать шейдеру относительное положение камеры без поворота.
2) повернуть буферы вершин И нормалей в вершинном шейдере с помощью матрицы вращения объекта (которая включает масштаб, но НЕ позиционный перенос)
3) наконец, ключевым моментом было ВЫЧИТАНИЕ повернутой позиции вершины из положения камеры во фрагментном шейдере.
Итак - наконец, это работает! (Ну, ЭТО была неделя моей жизни, я никогда не вернусь).

person moosefetcher    schedule 03.12.2013