1

我正在通过 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] 不会改变任何东西。

这是一张图片,这不是世界末日,这是沿轴裁剪的地形,如果你移动你会看到更多。您还可以看到水下地形是如何被剪裁的。使用不同着色器的模型、水或粒子也会被剪裁。

图片在这里

4

1 回答 1

1

感谢所有试图提供帮助的人,我意识到我的错。世界没有被剪裁,天空盒太小了,所以它渲染了整个世界。

于 2016-01-05T20:15:51.563 回答