Как мне обновить сгенерировать карту нормалей, чтобы она соответствовала карте проекции равностороннего проецирования

Я рендерил геодезическую сферу радиуса 1 в OpenGL и в моем шейдерном тесселяции glsl, умножая вершину на значение из карты высоты / смещения, которая создает несколько больших лучей, выходящих из сферы. Я ищу способ, чтобы иметь возможность ясно видеть геометрию, которую это создает. Некоторое рассеянное освещение или контур или что-то вроде фильтра sobel было бы идеальным, но у меня возникают проблемы с вычислением нормалей, необходимых для применения освещения или контуров.

Мне удалось вычислить нормали поверхности в геометрическом шейдере, но это создало неприемлемое узкое место, поскольку даже при том, что в основном это просто шейдерный шейдер, большое количество полигонов увязало в гс. Я застрял с OpenGL 4.2, поэтому расширение nVidias для меня недоступно.

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

1 ответ

Я смог найти это Sobel Filter для создания карты нормалей из карты смещения. Это не идеально, так как мне все еще приходится крутить нормали по сфере, но это довольно хорошо.

vec4 GenerateNormal(int imgWid, int imgHei, GLuint *displacementMap, int texX, int texY)
{
    float normalStrength = 8;
    int xCoord = texX;// (int)(texX*(float)imgWid);
    int yCoord = texY;// (int)(texY*(float)imgHei);
    float tl = abs(GetDisplacement(displacementMap, texX, texY, imgWid, imgHei, -1, -1));   // top left
    float  l = abs(GetDisplacement(displacementMap, texX, texY, imgWid, imgHei, -1, 0));   // left
    float bl = abs(GetDisplacement(displacementMap, texX, texY, imgWid, imgHei, -1, 1));   // bottom left
    float  t = abs(GetDisplacement(displacementMap, texX, texY, imgWid, imgHei, 0, -1));   // top
    float  b = abs(GetDisplacement(displacementMap, texX, texY, imgWid, imgHei, 0, 1));   // bottom
    float tr = abs(GetDisplacement(displacementMap, texX, texY, imgWid, imgHei, 1, -1));   // top right
    float  r = abs(GetDisplacement(displacementMap, texX, texY, imgWid, imgHei, 1, 0));   // right
    float br = abs(GetDisplacement(displacementMap, texX, texY, imgWid, imgHei, 1, 1));   // bottom right
    // Compute dx using Sobel:
    //           -1 0 1 
    //           -2 0 2
    //           -1 0 1
    float dX = tr + 2 * r + br - tl - 2 * l - bl;
    // Compute dy using Sobel:
    //           -1 -2 -1 
    //            0  0  0
    //            1  2  1
    float dY = bl + 2 * b + br - tl - 2 * t - tr;
    // Build the normalized normal
    vec4 N = vec4(normalize(vec3(dX, 1.0f / normalStrength, dY)), 1.0f);
    //convert (-1.0 , 1.0) to (0.0 , 1.0), if needed
    return normalize(N * 0.5f + 0.5f);
}
Другие вопросы по тегам