我正在通过 lwjgl 使用 opengl 渲染一个大场景。当我将投影矩阵的 zFar 设置为 100 之类的小数字时,它会在该距离处截断我的视锥。但是如果我将它设置为 1000 或更大,这个设置将被忽略,OpenGL 只会在大约 500 个单位的距离处进行剪辑。这发生在我所有的着色器中,最有趣的事实是这种裁剪发生在轴对齐的情况下,所以它只取决于相机沿轴的距离,而不是对角线距离。
我究竟做错了什么?OpenGL中是否有一个设置来限制某个点的视图?这发生在我的英特尔和英伟达卡上。我正在使用“现代 OpenGL”并自己管理矩阵。
private void createProjectionMatrix()
{
float aspectRatio = (float) Display.getWidth() / (float) Display.getHeight();
float y_scale = (float) ((1f / Math.tan(Math.toRadians(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;
}
视图矩阵有什么办法可以限制视锥体?
编辑: 顶点着色器:
#version 400 core
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 transformationMatrix;
uniform vec3 lightPosition[4];
uniform float fogDensity;
uniform float fogGradient;
uniform vec4 plane;
uniform mat4 lightSpaceMatrix;
in vec3 position;
in vec2 textureCoords;
in vec3 normal;
out vec2 pass_textureCoords;
out vec3 surfaceNormal;
out vec3 toLightVector[4];
out vec3 toCameraVector;
out float visibility;
out vec4 FragPosLightSpace;
void main(void)
{
vec4 worldPosition = transformationMatrix * vec4(position, 1.0);
gl_ClipDistance[0] = dot(worldPosition, plane);
vec4 positionRelativeToCam = viewMatrix * worldPosition;
gl_Position = projectionMatrix * viewMatrix * worldPosition;
pass_textureCoords = textureCoords;
surfaceNormal = (transformationMatrix * vec4(normal, 0.0)).xyz;
for(int i = 0;i < 4;i++)
{
toLightVector[i] = lightPosition[i] - worldPosition.xyz;
}
toCameraVector = (inverse(viewMatrix) * vec4(0.0, 0.0, 0.0, 1.0)).xyz - worldPosition.xyz;
float distanceToCam = length(positionRelativeToCam.xyz);
visibility = exp(-pow((distanceToCam * fogDensity), fogGradient));
visibility = clamp(visibility, 0.0, 1.0);
FragPosLightSpace = lightSpaceMatrix * worldPosition;
}
注释掉 gl_ClipDistance[0] 不会改变任何东西。
这是一张图片,这不是世界末日,这是沿轴裁剪的地形,如果你移动你会看到更多。您还可以看到水下地形是如何被剪裁的。使用不同着色器的模型、水或粒子也会被剪裁。