OpenGL - Как вычислить нормали в сетке высоты местности?

18

Мой подход заключается в вычислении двух касательных векторов, параллельных оси X и Y соответственно. Затем вычислите поперечное произведение, чтобы найти нормальный вектор.

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

Мне было интересно, есть ли более прямой расчет или менее дорогостоящий с точки зрения циклов процессора.

    
задан rraallvv 21.12.2012 в 02:44
источник
  • Могу ли я спросить, что вы использовали для рисования этого изображения? Это действительно приятно. –  Aesthete 21.12.2012 в 02:46
  • Adobe Illustrator –  rraallvv 21.12.2012 в 02:47

1 ответ

43

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

На самом деле это достаточно быстро, что я использую его для вычисления нормалей «на лету» в вершинном шейдере.

  // # P.xy store the position for which we want to calculate the normals
  // # height() here is a function that return the height at a point in the terrain

  // read neightbor heights using an arbitrary small offset
  vec3 off = vec3(1.0, 1.0, 0.0);
  float hL = height(P.xy - off.xz);
  float hR = height(P.xy + off.xz);
  float hD = height(P.xy - off.zy);
  float hU = height(P.xy + off.zy);

  // deduce terrain normal
  N.x = hL - hR;
  N.y = hD - hU;
  N.z = 2.0;
  N = normalize(N);
    
ответ дан Gigi 21.12.2012 в 03:18
источник
  • Слишком плохо, я не могу дать вам больше, чем +1: я удвоил свой FPS, используя ваш простой алгоритм! –  Zac 05.07.2013 в 15:56
  • Очень приятно, отлично работает для моих предварительных вычислений на процессоре –  Paul Spain 08.12.2016 в 01:20
  • Очень приятно! Можете ли вы расширить свое решение для 3D-текстур? –  qantik 11.04.2017 в 22:56
  • Есть ли там математическое объяснение? –  j00hi 02.02.2018 в 19:53
  • Это работает безупречно! Просто примечание: цифры в «выключенном» векторе должны быть изменены для вашего конкретного случая (мне пришлось использовать немного большее смещение, чтобы заставить его работать в моем случае) –  Michele 16.05.2018 в 16:06