2

在将其标记为重复之前,我遇到了与提出此问题的人完全相同的问题。

不幸的是,它根本没有帮助的答案,所以希望这会引发更好的讨论。使用 C++,手头的任务是编写经典的光线追踪器。我正在使用 Phong 着色模型,并且能够准确地照亮我的场景,直到我需要投射阴影光线。

仅供参考,这是我到目前为止没有尝试阴影的图片:

遵循传统的光线追踪算法,在该算法中我寻找离我的针孔相机最近的物体,我调用以下函数来计算生成的像素颜色:

glm::vec3 Scene::illuminate(Ray* primary, Surface* object, glm::vec3 hitPt)
{
    float red, green, blue;
    Material m = object->getMaterial();
    float p = m.phongCoef;
    glm::vec3 kD = m.diffuse;
    glm::vec3 kS = m.specular;
    glm::vec3 kA = m.ambient;
    float iA = m.ambienceIntensity;
    float i = lightSrc.lightIntensity;
    glm::vec3 n = object->getSurfaceNormalAt(hitPt); //normalized before return.
    glm::vec3 viewRay = primary->getDirection();   //normalized class member.

    glm::vec3 lightRay = glm::normalize((lightSrc.getOrigin()) - hitPt); //origin not normalized before here
    glm::vec3 h = glm::normalize(viewRay + lightRay);
    float nDotlightRay = glm::dot(n,lightRay);
    float nDoth = glm::dot(n, h);

    bool inShadow = false;
    Ray shadowRay;
    //hitPt = glm::normalize(hitPt);
    shadowRay.setOrigin(hitPt);
    shadowRay.setDirectionVector(lightRay);
    for (int k = 0; k < objects.size(); ++k) {
        if (objects.at(k)->intersect(shadowRay)) {
            //std::cout<<shadowRay.getDirection().x<<","<< shadowRay.getDirection().y <<","<<shadowRay.getDirection().z<<"\n";
            inShadow = true;
            break;}}

    //plug in to shading model
    if (inShadow)
    {
        red = kA.x*iA;
        green = kA.y*iA ;
        blue = kA.z*iA ;
    }
    else{
        red = kA.x*iA  +  kD.x*i*(fmax(0,nDotlightRay))  +  kS.x*i*(powf((fmax(0, nDoth)),p));
        green = kA.y*iA  +  kD.y*i*(fmax(0,nDotlightRay))  +  kS.y*i*(powf((fmax(0, nDoth)),p));
        blue = kA.z*iA  +  kD.z*i*(fmax(0,nDotlightRay))  +  kS.z*i*(powf((fmax(0, nDoth)),p));
    }

    glm::vec3 pixelColor = glm::vec3(red, green, blue);
    return pixelColor;
}

我尝试使用描述性变量/函数名称,以尽量减少伴随我的代码的解释。glm::vec3只是 GLM 数学库中的一个数据结构,它包含一个 3D 向量,可以在其上进行矩阵/向量操作。

正如我上面链接的问题一样,这是我的场景在尝试阴影后的样子。

此场景的光源位置为 (0, 2.5, -7.75),表示为相机参考系(其原点为 (0,0,0),面向负 z 方向)。对于另一个场景,光源位于 (4, 6, -1),因此输出甚至与我尝试渲染的另一个场景的问题不一致,如您在此处看到的那样;它只有一条穿过场景顶部的细灰线,其他任何地方都没有阴影?我完全迷失了,仅在这个问题上就花了大约 10 个小时;任何建议都会很棒。

请让我知道是否还有其他信息可以提供,例如我如何计算距离和生命值?我不知道我是否应该研究这些,因为阴影部分工作得很好,或者你们认为它仍然会导致这个问题吗?深度等应该不是问题,因为物体在阴影之前看起来是正确的?

4

1 回答 1

0

回答我自己的问题:上面提到的特定阴影伪影是在我的相交计算中省略了光线原点的结果。最初我没有打扰,因为我的相机参考帧位于(0,0,0)。但是对于阴影光线,原点不是零向量,因此重用相同的相交测试函数会得到完全不正确的结果。确保使用归一化的方向向量也是关键,否则输出将毫无意义,从而难以缩小错误的范围。

于 2018-11-26T02:37:37.957 回答