【问题标题】:OpenGL shadow map identical on all objects所有对象上的 OpenGL 阴影贴图相同
【发布时间】:2014-10-18 03:10:32
【问题描述】:

(作业相关问题)

我正在尝试通过this tutorial 实现阴影映射,但是,我遇到了一个奇怪的问题——我场景中的所有对象都应用了相同的阴影,如下所示: (灯光在 -3、5、-3(右下))

我做错了什么?我认为这将与矩阵相关,但我不知道如何解决它......

创建视图矩阵:

viewMatrix = new Matrix4f();
Matrix4f.rotate(MathHelpers.degreesToRadians(verticalRotation), new Vector3f(1f, 0f, 0f), viewMatrix, viewMatrix);
Matrix4f.rotate(MathHelpers.degreesToRadians(horizontalRotation), new Vector3f(0f, 1f, 0f), viewMatrix, viewMatrix);
Matrix4f.translate(position, viewMatrix, viewMatrix);
viewMatrix.store(cameraMatrix);
cameraMatrix.flip();

将数据发送到 GPU:

Mat4 proj2 = Matrices.perspective(90, 1, 3f, 20f);
Mat4 view2 = = MathHelpers.Matrix4fToMat4(lights.get(i).getViewMatrix());
Mat4 model2 = Mat4.MAT4_IDENTITY;
Mat4 mvp = MathHelpers.biasMVP(proj2, view2, model2);
FloatBuffer matBuffer = org.lwjgl.BufferUtils.createFloatBuffer(16);
MathHelpers.Mat4ToMatrix4f(mvp).store(matBuffer);
matBuffer.flip();

深度着色器: http://pastebin.com/SqFaBnSE http://pastebin.com/t5t35XNM

普通着色器: http://pastebin.com/yQhqyAWc http://pastebin.com/2C2sXByz

【问题讨论】:

  • 在您的顶点着色器中,您必须根据模型在阴影贴图创建和模型显示之间的转换来调整阴影坐标:示例 tex[7] 用于阴影贴图转换,modelView 是单个模型转换:ShadowCoord = (gl_TextureMatrix[7] * inverse(modelView) * gl_ModelViewMatrix) * gl_Vertex;
  • 所以如果我理解你的评论是正确的,我需要将pastebin.com/2C2sXByz的第41行更改为:vec4 newShadowCoord = lights[0].matrix * (inverse( viewMatrix * modelMatrix ) ) * pass_Position;?这样做最终会产生随相机移动的阴影,但我已经看到其他有同样问题的问题,所以我会检查这些。感谢您的帮助!
  • 哦,我是个傻瓜,应该是:vec4 newShadowCoord = lights[0].matrix * (inverse( modelMatrix ) ) * pass_Position;,当然。尽管如此,以不同的方式对我来说仍然失败。感谢您的帮助!
  • 我回顾了一下我的代码,我让你感到困惑:modelView 统一保存整个场景的模型矩阵,而我用贬值的 'gl_Matrices' 检索当前 modelMatrix 并从它们之间的区别(对不起,如果我让你感到困惑)

标签: java opengl graphics lwjgl shadow


【解决方案1】:

当您对阴影贴图进行采样时,您应该首先将片段的世界位置(在应用相机变换和透视矩阵之前)转换为

在顶点着色器中,这将是:

attribute vec3 pos;

uniform mat4 shadowTransform;//the MVP you used to create the shadowmap
uniform mat4 MVP;

varying vec4 shadowPos;//you can use the xy/w to sample the shadow map and compare against z/w

main(){
   gl_position = MVP*vec4(pos,1);
   shadowPos = shadowTransform*vec4(pos, 1);
}

【讨论】:

  • 我在片段着色器中执行此操作,因为我有一组灯光(目前只有 1 个正在使用),方法是将 in_Position 作为 out_Position 传递。即使我将变换移动到顶点着色器,我也会得到相同的结果(如预期的那样)(顶点中的 IE pass_Position = lights[1].matrix * in_Position; 与片段中的 vec4 newShadowCoord = lights[0].matrix * pass_Position; 相同)
【解决方案2】:

所以,我最终想通了。这是一个简单的逻辑错误,因为没有使用正确的位置。

public static void setLightUniforms(int program, Matrix4f mat) { Mat4 proj2 = Matrices.perspective(90, 1, 3f, 20f); Mat4 view2 = = MathHelpers.Matrix4fToMat4(lights.get(i).getViewMatrix()); Mat4 model2 = Mat4.MAT4_IDENTITY;

我一直使用单位矩阵作为位置,而不是我正在计算的模型的位置。

现在的代码是(注意参数的用法):

public static void setLightUniforms(int program, Matrix4f mat) { Matrix4f proj = MathHelpers.Mat4ToMatrix4f(Matrices.perspective(90, 1, 3f, 20f)); Matrix4f view = lights.get(i).getViewMatrix(); Matrix4f bias = MathHelpers.Mat4ToMatrix4f(MathHelpers.biasMatrix); Matrix4f MVP = Matrix4f.mul(proj, Matrix4f.mul(view, mat, null), null); Matrix4f.mul(bias, MVP, MVP);

【讨论】:

    猜你喜欢
    • 2018-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多