C++ 光线跟踪器,阴影光线产生黑圈?

C++ 光线跟踪器,阴影光线产生黑圈?,c++,3d,shadow,raytracing,C++,3d,Shadow,Raytracing,正如你在图片中看到的,我在球体的顶部画了一个黑色的圆圈,图片看起来是颗粒状的。这应该是更尖锐的,但有这些小的黑色和白色斑点 这是阴影光线的代码 int pos = 0; float intersect(const ray &r, vector<unique_ptr<object>> &obj) { //gives closest object hit point and position; float closest = numeric_

正如你在图片中看到的,我在球体的顶部画了一个黑色的圆圈,图片看起来是颗粒状的。这应该是更尖锐的,但有这些小的黑色和白色斑点

这是阴影光线的代码

int pos = 0;

float intersect(const ray &r, vector<unique_ptr<object>> &obj)
{
    //gives closest object hit point and position;
    float closest = numeric_limits<float>::max();
    for(int j = 0; j < obj.size(); j++)
    {
        float t = obj[j]->intersect(r);
        if(t > 1e-6 && t < closest)
        {
            closest = t;
            pos = j;
        }
    }
    return closest;
}
vec color(const ray& r, vector<unique_ptr<object>> &shape,  vector<unique_ptr<Light>> &lighting, int depth)
{   
    vec background_color( .678, .847, .902);
    vec total{0.0, 0.0, 0.0};
    vec ambient{0.125, 0.125, 0.125};

    float t_near = intersect(r, shape);

    if(t_near == numeric_limits<float>::max())
            return background_color;
    else
    {
        total += ambient;
        for(int i = 0; i < lighting.size(); i++){
        total += shape[pos]->shade(lighting[i]->position(), t_near, r);//gives specular + diffuse
        vec shadow_dir = unit_vector(lighting[i]->position() - r.p_at_par(t_near));
        ray shadowRay(r.p_at_par(t_near), shadow_dir);
        float dist = shadow_dir.lenght();
        float a = intersect(shadowRay, shape);
        if(a != numeric_limits<float>::max())
                return vec(0.0, 0.0, 0.0);
        }
        return total;
    }
}
int pos=0;
浮点相交(常量光线和r、向量和对象)
{
//给出最近的目标命中点和位置;
浮动最近=数值_限制::max();
对于(int j=0;j相交(r);
如果(t>1e-6和&t阴影(照明[i]->position(),t_near,r);//提供镜面反射+漫反射
vec shadow_dir=单位向量(照明[i]->position()-r.p_在_par(t_near));
射线阴影射线(r.p\U在par(t\U近),阴影方向);
浮动距离=阴影方向长度();
浮动a=相交(阴影线、形状);
如果(a!=数值限制::max())
返回向量(0.0,0.0,0.0);
}
返回总数;
}
}
好的,明白了

对于黑色圆,必须测试阴影光线的距离是否小于点与光源之间的距离。此外,对于距离,阴影方向不应标准化。为了处理黑白点,也就是从杜德到阴影的交叉点,你必须在命中点上加上N*偏差,比如1e-4。偏差不应该太小

        vec shadow_dir = lighting[i]->position() - r.p_at_par(t_near);
        float dist = shadow_dir.lenght();
        vec N = unit_vector(shape[pos]->normal(r, t_near));
        shadow_dir = unit_vector(shadow_dir);
        ray shadowRay(r.p_at_par(t_near) + N*1e-4, shadow_dir);
        float a = intersect(shadowRay, shape);
        if(a != numeric_limits<float>::max()){
            float m = shadowRay.p_at_par(a).lenght();
            if(a < dist)
                return vec(0.0, 0.0, 0.0);
            }
        }
vec shadow\u dir=lighting[i]->position()-r.p\u at\u par(t\u near);
浮动距离=阴影方向长度();
vec N=单位向量(形状[pos]->法线(r,t_近));
shadow_dir=单位向量(shadow_dir);
射线阴影射线(r.p\U在par(t\U近)+N*1e-4,阴影方向);
浮动a=相交(阴影线、形状);
如果(a!=数值限制::max()){
float m=阴影光线.p_在第(a)段长度();
if(a
好的,明白了

对于黑色圆,必须测试阴影光线的距离是否小于点与光源之间的距离。此外,对于距离,阴影方向不应标准化。为了处理黑白点,也就是从杜德到阴影的交叉点,你必须在命中点上加上N*偏差,比如1e-4。偏差不应该太小

        vec shadow_dir = lighting[i]->position() - r.p_at_par(t_near);
        float dist = shadow_dir.lenght();
        vec N = unit_vector(shape[pos]->normal(r, t_near));
        shadow_dir = unit_vector(shadow_dir);
        ray shadowRay(r.p_at_par(t_near) + N*1e-4, shadow_dir);
        float a = intersect(shadowRay, shape);
        if(a != numeric_limits<float>::max()){
            float m = shadowRay.p_at_par(a).lenght();
            if(a < dist)
                return vec(0.0, 0.0, 0.0);
            }
        }
vec shadow\u dir=lighting[i]->position()-r.p\u at\u par(t\u near);
浮动距离=阴影方向长度();
vec N=单位向量(形状[pos]->法线(r,t_近));
shadow_dir=单位向量(shadow_dir);
射线阴影射线(r.p\U在par(t\U近)+N*1e-4,阴影方向);
浮动a=相交(阴影线、形状);
如果(a!=数值限制::max()){
float m=阴影光线.p_在第(a)段长度();
if(a