我正在尝试使用 OpenGL 3.3+ 在我的景观编辑器上实现阴影映射。使用一些教程,我设法让我的代码编译和运行,但整个景观都处于阴影中,除了我的景观网格的后排(最小的 z)。
我目前正在为我的光使用与相机相同的投影、视图和模型矩阵(负 z 离相机最远)。
我的投影、视图和模型矩阵的初始化(来自 LWJGL 矩阵教程):
modelPos = new Vector3f(0f, 0f, -20f);
modelAngle = new Vector3f(15f, 0f, 0f);
modelScale = new Vector3f(1f, 1f, 1f);
cameraPos = new Vector3f(-50f, 0f, -120f);
projectionMatrix = new Matrix4f();
float fieldOfView = 120f;
float aspectRatio = (float)width / (float)height;
float near_plane = 0.01f;
float far_plane = 100f;
float y_scale = DepthMatrixUtility.coTangent(DepthMatrixUtility.degreesToRadians(fieldOfView / 2f));
float x_scale = y_scale / aspectRatio;
float frustum_length = far_plane - near_plane;
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);
显示场景时绑定我的矩阵:
Matrix4f.translate(cameraPos, viewMatrix, viewMatrix);
Matrix4f.scale(modelScale, modelMatrix, modelMatrix);
Matrix4f.translate(modelPos, modelMatrix, modelMatrix);
Matrix4f.rotate(DepthMatrixUtility.degreesToRadians(modelAngle.z), new Vector3f(0, 0, 1), modelMatrix, modelMatrix);
Matrix4f.rotate(DepthMatrixUtility.degreesToRadians(modelAngle.y), new Vector3f(0, 1, 0), modelMatrix, modelMatrix);
Matrix4f.rotate(DepthMatrixUtility.degreesToRadians(modelAngle.x), new Vector3f(1, 0, 0), modelMatrix, modelMatrix);
matrix = new Matrix4f();
Matrix4f.mul(matrix, projectionMatrix, matrix);
Matrix4f.mul(matrix, viewMatrix, matrix);
Matrix4f.mul(matrix, modelMatrix, matrix);
matrix.store(matrix44Buffer);
matrix44Buffer.flip();
matrixLocation = GL20.glGetUniformLocation(pId, "matrix");
GL20.glUniformMatrix4(matrixLocation, false, matrix44Buffer);
我已经通过在片段着色器中存储颜色测试了我的 FBO,高度图正确显示(我将 FBO 纹理绘制到屏幕角落的一个小四边形)并在我更改高度图时更新。
然后我修改了我的 FBO 以在第一遍时将深度存储到纹理中:
depthTexture = GL11.glGenTextures();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, depthTexture);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_DEPTH_COMPONENT, Window.getScreenWidth(), Window.getScreenHeight(), 0, GL11.GL_DEPTH_COMPONENT, GL11.GL_UNSIGNED_BYTE, (ByteBuffer)null);
GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_NEAREST);
GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
fboId = GL30.glGenFramebuffers();
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, fboId);
GL11.glDrawBuffer(GL11.GL_NONE);
GL11.glReadBuffer(GL11.GL_NONE);
GL32.glFramebufferTexture(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, depthTexture, 0);
verifyFBO();
我的第一遍顶点着色器(创建阴影贴图):
#version 330 core
uniform mat4 matrix;
in vec4 in_Position;
void main(void)
{
gl_Position = matrix * in_Position;
}
我的第一遍片段着色器:
#version 330 core
layout(location = 0) out float fragmentdepth;
void main(void)
{
fragmentdepth = gl_FragCoord.z;
}
我的偏差矩阵:
[0.5f, 0.0f, 0.0f, 0.0f]
[0.0f, 0.5f, 0.0f, 0.0f]
[0.0f, 0.0f, 0.5f, 0.0f]
[0.5f, 0.5f, 0.5f, 1.0f]
第二遍的顶点着色器(使用阴影贴图渲染场景):
void main(void)
{
gl_Position = matrix * in_Position;
ShadowCoord = biasMatrix * lightMatrix * in_Position;
}
第二遍的片段着色器:
if (texture(shadowMap, ShadowCoord.xy).z < ShadowCoord.z)
{
vec4 colour = 0.5 * out_Colour;
out_Colour = new vec4(colour[0], colour[1], colour[2], 1.0f);
}