我目前正在编写一个使用 LWJGL 生成低多边形场景的小程序。我首先渲染了一座房子。然后我渲染了地形。最后,我渲染了水。水原本是一个平面的顶点。我使用 Perlin 噪声算法在顶点着色器中做了一些位移以生成一些波(即我无法获得特定点的实际水位)。当我渲染场景时,我观察到一些锯齿状的边缘。
它们是什么?我怎样才能删除它们?对不起,我无法上传代码。因为行数太多了。
编辑 1:
private float FOV = 70;
private float NEAR_PLANE = .1f;
private float FAR_PLANE = 1000f;
private void createProjectionMatrix() {
float aspectRatio = (float) Display.getWidth() / (float) Display.getHeight();
float y_scale = (float) ( (1f/ Math.tan(FOV/2f))*aspectRatio );
float x_scale = y_scale / aspectRatio;
float frustum_length = FAR_PLANE - NEAR_PLANE;
projectionMatrix = new Matrix4f();
projectionMatrix.m00 = x_scale;
projectionMatrix.m11 = y_scale;
projectionMatrix.m22 = -((FAR_PLANE + NEAR_PLANE) / frustum_length);
projectionMatrix.m23 = -1;
projectionMatrix.m32 = -((2*NEAR_PLANE * FAR_PLANE) / frustum_length);
projectionMatrix.m33 = 0;
}
最佳答案
问题是由于 Z-buffer 存储的片段的 Z 值精度低。看看你的值(value)观:
private float NEAR_PLANE = .1f;
private float FAR_PLANE = 1000f;
所以可见深度范围是z = < 0.1 , 1000.0 >
这被标准化为 < 0.0 , 1.0>
范围。现在,如果您的 pixelformat 仅使用 16 位 Z 缓冲区,那么(假设不是这种情况的线性 Z 缓冲区)您得到了精度 ~(1000.0/0.1)/2^16 = 0.6
这是最小可能的 Z 步。现在,如果您考虑到 Z 缓冲区值是非线性映射的,那么离您的 Z_Near
越远。精度会更低。
要改进这一点,您可以:
- 将像素格式更改为
32bits
如果 gfx 支持,用于深度缓冲区 下
Zfar/Znear
比率Znear
更显着(由于非线性 Z 值)。越接近零,事情就越糟糕。如果您正在渲染分辨率为米的对象,那么z_near < 1.0
就没有意义了。堆积更多的截头体
如果您需要覆盖非常高的动态范围,您可以在多于一次的渲染过程中渲染场景。有关详细信息,请参阅
尤其是子弹#1
使用线性 Z 缓冲区
这可以通过着色器消除非线性来完成。
关于java - OpenGL 中不需要的三角形 --- Z 冲突?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42175078/