【问题标题】:What is wrong with my normal calculations?我的正常计算有什么问题?
【发布时间】:2014-06-24 19:59:30
【问题描述】:

我尝试使用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;

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

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

(抱歉,模糊,我在拍摄这些时正在测试一些景深。)

【问题讨论】:

  • 您不会在 P.xy 而是 P.xz 的小位移处进行评估,因此您不沿着切平面构建评估补丁,因此其法线不是搜索的表面法线。

标签: java opengl opengl-es lighting terrain


【解决方案1】:

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

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

v = v.nor();

nor 函数并不像您认为的那样。它将向量归一化为单位长度。 (向量归一化 =/= 表面法线计算)。要计算法线,您必须计算局部斜率向量的叉积

【讨论】:

  • 我同意你关于顶点着色器的评论。您是否有任何我可以参考的资源,您认为可以帮助进一步解释正常计算?
  • @seesharper:这应该是一本很好的入门书:stackoverflow.com/a/6661242/524368——然后我建议你买一本关于线性代数的本科教科书。您必须熟悉使用向量空间及其上的操作。说到计算机图形学的数学,上面有很多书,我完全不知道哪些是好的,哪些是坏的。作为图形编码器的权威文本是 Foley 等人的“计算机图形 - 原理与实践”。它在 2009 年发布了一个新版本(我还得买)。
  • 引用的 glsl 方法不需要相邻顶点。您在 P 的一个小型计算拓扑邻域中评估高度图。就效率而言,建议将结果烘焙一次到法线贴图中并重复使用该贴图。
  • 我不认为这是着色器代码——这是客户端代码(见我的回答)。
  • @wcochran:OP 明确提到了在顶点着色器中进行的计算。我在一开始就在我的答案中对这部分进行了 QFT。
【解决方案2】:

你在正确的轨道上。您尝试计算的叉积是

   (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)

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-18
    • 2014-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-04
    • 2022-09-29
    相关资源
    最近更新 更多