c++光线追踪算法中ray函数是否存在问题

C++运行光线追踪代码,camera类如下:

class camera {
public:

    camera( const vec3 &eye, const vec3 &ref, const int width, const int height, const double tanfovy = tan( 45.0 / 360 * M_PI ) ) : m_eye( eye ), m_ref( ref ), m_width( width ), m_height( height ), m_tanfovy( tanfovy ), m_p( 2 * m_tanfovy / m_height ) {}
    vec3 eye() const { return m_eye; }
    vec3 ref() const { return m_ref; }
    int width() const { return m_width; }
    int height() const { return m_height; }

    inline ray generate_ray( const double x, const double y ) const
    {
        const auto dx = x;
        const auto dy = y;
      
        return ray( m_eye, normalize( vec3( dx, dy, - 1.0 ) ) );
    }

private:
    vec3    m_eye; //視点
    vec3    m_ref; 
    int     m_width;  
    int     m_height;   
    double  m_tanfovy;
    double  m_p;      
};

其中,要求修改generate_ray函数让其实装

  inline ray generate_ray( const double x, const double y ) const
    {
        const auto dx = x;
        const auto dy = y;
      
        return ray( m_eye, normalize( vec3( dx, dy, - 1.0 ) ) );
    }

结果要求应为下图所示

img

我使用了VS2022运行整个代码。我没有觉得这个generate_ray有什么问题,但实际运行的结果却如下图所示

img

我想知道这个generate_ray函数是否存在问题,以及这两种不同结果的产生是否是由generate_ray引起的。

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 以下回答来自chatgpt:

    对于这个问题,我们有以下的解决方案:

    1. 首先,需要对generate_ray函数进行检查,确认它是否符合预期的功能要求。可以从以下几个方面进行检查:

    2. 参数传递是否正确,特别是摄像机位置和视野参数是否正确;

    3. 是否正确计算光线方向;
    4. 是否对光线进行了归一化处理。

    5. 如果generate_ray函数不是问题的原因,那么需要重新审视其他代码,看看是否有可能出现别的问题。可以从以下几个方面入手:

    6. 确认场景中的三维模型是否正确;

    7. 检查光线与物体相交的部分是否存在问题;
    8. 检查材质参数设置是否正确。

    9. 如果以上两个方面都没有问题,可以通过输出调试信息等方式进行进一步的排查分析,以确定问题出在哪里。

    以下是一些示例代码来说明generate_ray函数的实现:

    class Camera {
    public:
        Camera() {}
        virtual ~Camera() {}
    
        virtual Ray generate_ray(float x, float y) const = 0;
    
    };
    
    class PerspectiveCamera : public Camera {
    public:
        PerspectiveCamera(Vec3f center, Vec3f direction, Vec3f up, float angle)
            : m_center(center), m_direction(direction), m_up(up), m_angle(angle) 
        {
            m_direction.Normalize();
            m_up = m_up - m_direction * Dot(m_up, m_direction);
            m_up.Normalize();
            m_horizontal = Cross(m_direction, m_up);
            m_horizontal.Normalize();
            m_scale = tan(m_angle / 2.0 * M_PI / 180.0);
        }
        virtual ~PerspectiveCamera() {}
    
        virtual Ray generate_ray(float x, float y) const {
            Vec3f direction = m_direction * m_scale + 
                              m_horizontal * (x - 0.5) + 
                              m_up * (0.5 - y) / m_aspectRatio;
            direction.Normalize();
            return Ray(m_center, direction);
        }
    
    protected:
        Vec3f m_center;
        Vec3f m_direction;
        Vec3f m_up;
        Vec3f m_horizontal;
        float m_scale;
        float m_aspectRatio;
        float m_angle;
    };
    

    在这个示例代码中,我们定义了一个Camera类和一个PerspectiveCamera类。PerspectiveCamera类是Perspective摄像机的一个实现,它通过中心点、方向、朝向和视角等参数来生成光线。generate_ray函数根据传入的点坐标x和y来计算相应的光线方向,然后返回一条从中心点出发的光线。

    希望这些示例代码能够对您更好的理解和解决问题有所帮助。如果您需要更多的帮助,请不要犹豫,随时与我联系。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^