我的正常计算有什么问题?

时间:2014-06-24 19:59:30

标签: java opengl opengl-es lighting terrain

我尝试使用OpenGL - How to calculate normals in a terrain height grid?中描述的算法。我在我的顶点着色器中弹出它并使用一些perlin噪声函数来测试它,它就像一个魅力,但当我将它移植到Java时,它没有那么好用。

float nx = 0;
float ny = 0;
float nz = 0;
Vector3 P = new Vector3(vpx,vpy,vpz);
Vector3 off = new Vector3(1,1,0);
float hL = tryGetHeight(_mempoints2,P.x - off.x,P.z - off.z);
float hR = tryGetHeight(_mempoints2,P.x + off.x,P.z + off.z);
float hD = tryGetHeight(_mempoints2,P.x - off.z,P.z - off.y);
float hU = tryGetHeight(_mempoints2,P.x + off.z,P.z + off.y);
nx = hL - hR;
ny = hD - hU;
nz = 2.0f;
Vector3 v = new Vector3(nx,ny,nz);
v = v.nor();
nx = v.x;
ny = v.y;
nz = v.z;

顶点着色器中算法的结果:

vertex shader

我的缓冲区设置中的算法结果:

buffer setup

(很抱歉模糊不清,当我拍摄这些东西时,我正在测试一些景深。)

2 个答案:

答案 0 :(得分:0)

  

顶点着色器中算法的结果:

不应在任何着色器阶段计算法线。顶点着色器没有关于相邻顶点的信息,几何着色器是一个性能值,tesselation着色器只能为本地tesselation提供法线。在片段着色器中进行屏幕空间正常计算是很奇怪的。预先计算CPU上的法线并将它们作为另一个顶点属性传递。

  

v = v.nor();

nor功能不符合您的想法。它将矢量标准化为单位长度。 (矢量归一化= / =表面法线计算)。要计算法线,您必须计算局部斜率向量的叉积

答案 1 :(得分:0)

你走在正确的轨道上。您尝试计算的交叉产品是

   (1, 0, (R-L)/2)
 x (0, 1, (U-D)/2)
 -----------------
(-(R-L)/2, -(U-D)/2, 1)

与向量

具有相同的方向
(L-R,D-U,2)

标准化后你有

N = norm(L-R,D-U,2)

你的左,右,上,下表面高度是

L = height(P.x - 1, P.y)
R = height(P.x + 1, P.y)
U = height(P.x, P.y + 1)
D = height(P.x, P.y - 1)

如果你看起来有一些错误的标志和不匹配的下标。