2015-04-21 5 views
0

Я начинаю с нормальной сферы, которую мне нужно деформировать в овальную форму. Я делаю это, растягивая одну ось, которая в моем коде будет ось y.Пересчет нормалей и ShadowCoords после деформации сферы в овал

mat4 ToOvalMat = mat4(vec4(1., 0., 0., 0.), 
         vec4(0., 1.5, 0., 0.), 
         vec4(0., 0., 1., 0.), 
         vec4(0., 0., 0., 1.)); 

Я растягиваю его на 1,5, умножая на вход, называемый a. Это хорошо работает для моих намерений, но мне все же нужно найти хороший способ исправить нормали и получить правильные тени, поскольку они все еще привязаны к исходной сфере.

После охоты за ответом на Google я напал на GPU Gems - Deformers, что связано с нормалями, но я не совсем понимаю объясняемые концепции. Якобианская матрица кажется, что она сможет решить мою нормальную проблему, но я не уверен и хотел бы получить какую-то помощь или отзывы относительно моих вычислений, так как это трудно понять из рендеринга в моей тестовой программе.

Поскольку я растяжение в г измерении У меня есть нормальная единичная матрица размера 4, где я просто заменить Y 1 с 1.5a. Это была бы моя якобианская матрица, если бы я правильно понял текст. Инверсия, а затем транспонирование эта матрица была бы тем, с чем я буду умножать свои нормали. Могу ли я также использовать это на моем ShadowMatrix?

Normal = (transpose(inverse(ToOvalMat)) * vec4(VertexNormal, 0.)).xyz; 
Normal = normalize((ViewMatrix * WorldMatrix * vec4(Normal, 0.)).xyz); 

Я получаю некоторые артефакты с этими расчетами, и они полностью не продавать его для меня относительно правдоподобности, что заставляет меня чувствовать себя как-то от моих матриц или что-то. И я полностью догадался с ShadowMatrix, поскольку я еще не изучил его достаточно, так как до сих пор я придерживался нормалей.

ответ

0

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

Более чистый подход ИМХО состоит в том, чтобы передать отдельную матрицу нормального преобразования в шейдер и использовать ее для преобразования нормалей. Это может быть матрица 3x3 (см. Мой ответ здесь для получения дополнительной информации: OpenGL ES 2.0 an Android: What dimensions should the normalMatrix have?).

Затем вы вычисляете инверсию/транспонирование в своем собственном коде на CPU. Для неравномерного масштабирования обратная является матрицей масштабирования, которая содержит инверсию масштабных коэффициентов, а перенос ее ничего не делает. Для примера:

mat3 ToOvalNormalMat = mat3(vec3(1.0f, 0.0f, 0.0f), 
          vec3(0.0f, 1.0f/1.5f, 0.0f), 
          vec3(0.0f, 0.0f, 1.0f)); 

См normal matrix for non uniform scaling более подробно о том, как рассчитывается нормальная матрица для неравномерного масштабирования.

+0

Я знаю, что для этого примера транспозиция ничего не делает, и поэтому инвертирование y-координаты может быть сделано просто, делая то, что вы показываете, да. Но я хотел бы узнать более общий ответ, и я пытаюсь изучить его процесс, когда могут возникнуть другие деформации :) – Simon

+0

Этот процесс несколько объясняется в ответе, связанном в последнем абзаце. Вы должны вычислить обратную матрицу, а затем перенести ее. Ну, на самом деле есть более простой способ. Может быть, я должен посмотреть, смогу ли я поместить это в один из ответов. –