我在OpenGL中渲染半径为1的测地球,并在我的glsl tesselation着色器中将顶点乘以高度/位移贴图中的值,从而创建从球体突出的一些大光线。我正在寻找一种能够清楚地看到这种创造的几何形状的方法。一些漫射光或轮廓或类似索贝尔滤波器的东西是理想的,但我无法计算应用照明或轮廓所需的法线。
我能够计算几何着色器中的曲面法线,但这造成了一个不可接受的瓶颈,即使它只是一个直通着色器,大量的多边形使gs陷入困境。我坚持使用OpenGL 4.2,因此我无法使用nVidias passthrough扩展。
我想也许预先计算好的法线贴图可能就是这样,但我不知道如何基于我的equirectangular投影置换贴图生成它。有什么想法或有用的建议吗?
答案 0 :(得分: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);
}