【问题标题】:For mouse click ray casting a line, why aren't my starting rays updating to my camera position after I move my camera?对于鼠标点击光线投射一条线,为什么在我移动相机后我的起始光线没有更新到我的相机位置?
【发布时间】:2022-01-11 07:29:03
【问题描述】:

当相机四处移动时,为什么我的起始光线仍然停留在原点 0、0、0,即使相机位置已经更新?

如果我启动程序并且我的相机位置默认为 0、0、0,它工作正常。但是一旦我将相机移动到右侧并单击更多,线条仍然来自 0 0 0什么时候应该从相机所在的地方开始。我做错了什么吗?我已经检查以确保它们在主循环中得到更新。我使用了以下引用的代码片段:
picking in 3D with ray-tracing using NinevehGL or OpenGL i-phone

// 1. Get mouse coordinates then normalize
float x = (2.0f * lastX) / width - 1.0f;
float y = 1.0f - (2.0f * lastY) / height;

// 2. Move from clip space to world space
glm::mat4 inverseWorldMatrix = glm::inverse(proj * view);
glm::vec4 near_vec = glm::vec4(x, y, -1.0f, 1.0f);
glm::vec4 far_vec = glm::vec4(x, y, 1.0f, 1.0f);
glm::vec4 startRay = inverseWorldMatrix * near_vec;
glm::vec4 endRay = inverseWorldMatrix * far_vec;

// perspective divide
startR /= startR.w;
endR /= endR.w;

glm::vec3 direction = glm::vec3(endR - startR);

// start the ray points from the camera position
glm::vec3 startPos = glm::vec3(camera.GetPosition());
glm::vec3 endPos = glm::vec3(startPos + direction * someLength);

第一个屏幕截图我点击了一些光线,第二个我将相机向右移动并点击了一些,但初始的起始光线仍然在 0、0、0。我正在寻找的是光线来相机位置在第三张图像中的任何位置,即红色光线抱歉造成混乱,红线应该射出并射入远处而不是向上。

// and these are my matrices
// projection
glm::mat4 proj = glm::perspective(glm::radians(camera.GetFov()), (float)width / height, 0.1f, 100.0f);
// view
glm::mat4 view = camera.GetViewMatrix(); // This returns glm::lookAt(this->Position, this->Position + this->Front, this->Up);
// model
glm::mat4 model = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 0.0f));

【问题讨论】:

    标签: c++ opengl glm-math


    【解决方案1】:

    很难说问题出在代码的什么地方。但是,我使用这个函数进行光线投射,该函数改编自从头开始的代码和 learnopengl:

    vec3 rayCast(double xpos, double ypos, mat4 projection, mat4 view) {
        // converts a position from the 2d xpos, ypos to a normalized 3d direction
        float x = (2.0f * xpos) / WIDTH - 1.0f;
        float y = 1.0f - (2.0f * ypos) / HEIGHT;
        float z = 1.0f;
        vec3 ray_nds = vec3(x, y, z);
        vec4 ray_clip = vec4(ray_nds.x, ray_nds.y, -1.0f, 1.0f);
        // eye space to clip we would multiply by projection so
        // clip space to eye space is the inverse projection
        vec4 ray_eye = inverse(projection) * ray_clip;
        // convert point to forwards
        ray_eye = vec4(ray_eye.x, ray_eye.y, -1.0f, 0.0f);
        // world space to eye space is usually multiply by view so
        // eye space to world space is inverse view
        vec4 inv_ray_wor = (inverse(view) * ray_eye);
        vec3 ray_wor = vec3(inv_ray_wor.x, inv_ray_wor.y, inv_ray_wor.z);
        ray_wor = normalize(ray_wor);
        return ray_wor;
    }
    

    您可以使用startPos = camera.PositionendPos = camera.Position + rayCast(...) * scalar_amount 划定界限。

    【讨论】:

    • 是的,这太奇怪了。我也用过它,它也在做同样的事情。我到处移动我的相机,但起始光线都来自同一个原点。就像现在我有一个尖刺球..
    • 呃……我真是个$#@!笨蛋。事实证明这两种方法都可以正常工作。我的问题来自更新glBufferSubData(...) 的缓冲区数据。我使用的是glBufferSubData(GL_ARRAY_BUFFER, coordinates.size() * sizeof(glm::vec3), sizeof(glm::vec3),&endRay);,这解释了为什么我一直在同一个位置开始我的所有光线。固定到glBufferSubData(GL_ARRAY_BUFFER, sizeof(startRay), coordinates.size() * sizeof(startRay), (const void*)(coordinates.data())); 现在无论我的相机在哪里都可以拍摄光线。我不敢相信我花了两个星期的时间,我现在需要躺下......
    • 我在使用glBuffer... 电话时经常犯这个错误。每当某些东西绘制不正确时,我都会期待它,尽管出于某种原因我并没有首先怀疑这是这里的问题……嗯,至少它现在已经排序了! :)
    猜你喜欢
    • 1970-01-01
    • 2011-08-29
    • 1970-01-01
    • 1970-01-01
    • 2014-07-24
    • 1970-01-01
    • 1970-01-01
    • 2021-03-21
    • 1970-01-01
    相关资源
    最近更新 更多