0

我在 OpenGL 和我的 glsl 镶嵌着色器中渲染一个半径为 1 的测地线球体,将顶点乘以高度/置换贴图中的一个值,这会产生一些从球体突出的大光线。我正在寻找一种能够清楚地看到它创建的几何图形的方法。一些漫反射照明或轮廓或类似 sobel 过滤器的东西是理想的,但我无法计算应用照明或轮廓所需的法线。

我能够在几何着色器中计算表面法线,但这造成了一个无法接受的瓶颈,因为即使它主要只是一个直通着色器,大量的多边形也会让 gs 陷入困境。我坚持使用 OpenGL 4.2,因此我无法使用 nVidias 直通扩展。

我在想也许一个预先计算的法线贴图可能是要走的路,但我不确定如何根据我的 equirectangular 投影置换贴图生成它。有什么想法或有用的建议吗?

4

1 回答 1

0

我能够找到它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);
}
于 2015-02-25T18:50:09.493 回答