繁体   English   中英

现代OpenGL投影视图模型转换不起作用

[英]Modern OpenGL Projection View Model transformation not working

我尝试在着色器中仅使用一个变换(及其逆转置),但是我的阴影却显得很奇怪,所以我猜我的法线变换不正确。 许多在线教程建议使用“投影*视图*模型”三阶段变换,并在“视图*模型”变换阶段计算光。 因此,我尝试实现这三个转换,但不仅我的茶壶没有显示,甚至一个简单的三角形也不会显示。

这是我的顶点着色器代码:

#version 410

in vec3 position;  // position of the vertex (and fragment) in world space
in vec3 normal;  // surface normal vector in world space

uniform mat4 model;
uniform mat4 view;
uniform mat4 proj;
uniform mat4 modelView_it;

vec3 l_pos = vec3(10, 10, 10);

out VertexData {
    vec3 normal;
    vec3 eye;
    vec3 lightDir;
} VertexOut;

void main()
{
    vec4 pos = view * model * vec4(position, 1.0);

    VertexOut.normal = normalize(vec3(modelView_it * vec4(normal, 0.0)));
    VertexOut.lightDir = l_pos - vec3(pos);
    VertexOut.eye = vec3(0, 0, 0);

    gl_Position = proj * view * model * vec4(position, 1);
}

这是我的片段着色器代码

#version 150

out vec4 colorOut;

vec3 kd = vec3(0.1, 1, 0.1);
vec3 ka = vec3(1, 1.0, 1.0);
vec3 ks = vec3(0.5, 1, 0.5);
float sp = 90;
vec3 intensity = vec3(1, 1, 1);

in VertexData {
    vec3 normal;
    vec3 eye;
    vec3 lightDir;
} VertexIn;

void main()
{
    vec3 n = normalize(VertexIn.normal);
    vec3 l = normalize(VertexIn.lightDir);
    vec3 e = normalize(VertexIn.eye);

    vec3 diffuse = kd*intensity*max(0, dot(l, n));
    vec3 r = -l + 2*dot(l,n) * n;
    vec3 specular = ks*intensity*max(pow(dot(r, e), sp),0);

// force to be white intentionally to test
    colorOut = vec4(1,1,1,1);
}

这是一些我用来生成投影和视图转换矩阵的函数(代码取自其他一些类似的堆栈溢出问题)

//generate projection matrix
void setPerspective(float fovY, float aspect, float near, float far, Matrix4f& mProjectionMatrix)
{
    float theta = fovY*0.5;
    float range = far - near;
    float invtan = 1./tan(theta);

    mProjectionMatrix(0,0) = invtan / aspect;
    mProjectionMatrix(1,1) = invtan;
    mProjectionMatrix(2,2) = -(near + far) / range;
    mProjectionMatrix(3,2) = -1;
    mProjectionMatrix(2,3) = -2 * near * far / range;
    mProjectionMatrix(3,3) = 0;
}
//generate view matrix
void lookAt(const Vector& position, const Vector& target, const Vector& up, Matrix4f& mViewMatrix)
{
    Matrix3f R;
    R.col(2) = (position-target).normalized();
    R.col(0) = up.cross(R.col(2)).normalized();
    R.col(1) = R.col(2).cross(R.col(0));
    mViewMatrix.topLeftCorner<3,3>() = R.transpose();
    mViewMatrix.topRightCorner<3,1>() = -R.transpose() * position;
}

这是我创建和设置制服的方法

// Create transformation matrices
Transform3fAffine trans = IdentityTransform();
Matrix4f viewMat = Matrix4f::Zero();
Matrix4f projMat = Matrix4f::Zero();
setPerspective(45.0f, //field of view
               4.0f / 3.0f, //aspect ratio
               0.1f, //near clipping
               100.0f, //far clipping
               projMat); //matrix
lookAt(Vector(3,3,3), //camera position
       Vector(0,0,0), //target to look at
       Vector(0,1,0), //up vector
       viewMat);
GLint viewID = glGetUniformLocation(shaderProgram, "view");
GLint modelID = glGetUniformLocation(shaderProgram, "model");
GLint projID = glGetUniformLocation(shaderProgram, "proj");
GLint mvIT_ID = glGetUniformLocation(shaderProgram, "modelView_it");
transformModel(modelID, mvIT_ID, trans.matrix(), viewMat);
transformView(viewID, mvIT_ID, viewMat, trans.matrix());
transformProj(projID, projMat);

这些“ transformXXX”函数看起来像这样

void transformModel(GLint& modelID, GLint& mvIT_ID, Matrix4f& modelMat, Matrix4f& viewMat) {
    glUniformMatrix4fv(modelID, 1, GL_FALSE, modelMat.data());
    glUniformMatrix4fv(mvIT_ID, 1, GL_FALSE, (viewMat*modelMat).inverse().transpose().data());
}

void transformView(GLint& viewID, GLint& mvIT_ID, Matrix4f& viewMat, Matrix4f& modelMat) {
    glUniformMatrix4fv(viewID, 1, GL_FALSE, viewMat.data());
    glUniformMatrix4fv(mvIT_ID, 1, GL_FALSE, (viewMat*modelMat).inverse().transpose().data());
}

void transformProj(GLint& projID, Matrix4f& projMat) {
    glUniformMatrix4fv(projID, 1, GL_FALSE, projMat.data());
}

尽管有所有这些,屏幕只是黑色而已。 甚至在原点也不使用简单的三角形。 如果我在顶点着色器中摆脱了proj * view * (基本上只有“ model”是唯一的变换),则可以看到我的形状并使用键盘事件对其进行很好的变换。 这意味着我的基本管道不应该成为问题,因为我能够看到形状。 只要在“模型”之前添加“ proj * view *”,一切都会变黑。

请帮忙!

更新:现在我找到了一个问题: glUniformMatrix4fv给我GL_INVALID_ENUM错误,并且它根本没有设置统一变量。 (我通过将矩阵硬编码到着色器中来验证了这一点)。 我几乎找不到任何在线问题,而且似乎没有人使用此功能收到INVALID_ENUM错误。 有任何想法吗?

transformXXX函数看起来很奇怪。 为什么会有3种不同的? 通常,模型,视图和投影转换一起使用。 而且transformModel and transformView`都设置了modelview_IT矩阵。

通常,您不会通过模型,也不会将变换矩阵视为单独的制服。 对于优化效果不佳的着色器代码,这将迫使每个顶点执行4×4矩阵矩阵乘法,可以轻松地对结果进行预先计算。

您实际上应该将transformModeltransformView合并为一个单独的transformModelView函数。

看起来很奇怪的另一件事是,您是从零矩阵开始的。 通常,您使用身份初始化矩阵并从那里开始工作。

矩阵运算顺序令人难以置信,我就是其中之一

从理论上讲,您希望对顶点进行建模,查看,投影并将其放到屏幕上。 该代码看起来就是这样做的。

您可能想看看您的投影矩阵

mProjectionMatrix(3,2) = -1;
mProjectionMatrix(2,3) = -2 * near * far / range;
mProjectionMatrix(3,3) = 0;

并尝试移调它。

mProjectionMatrix(2,3) = -1;
mProjectionMatrix(3,2) = -2 * near * far / range;
mProjectionMatrix(3,3) = 0;

您可以做的另一件事是,通过使用gluPerspective设置矩阵,然后通过glGet获取它们,来比较具有gl实现的矩阵。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM