【问题标题】:Ray tracer reflections grainy光线追踪器反射颗粒状
【发布时间】:2016-06-14 09:47:08
【问题描述】:

我刚刚在我的光线追踪器中实现了反射,这里是处理反射的代码,但是我已将所有代码上传到github repository 以便更好地阅读:

Color finalColor = closestObjectMaterial.GetColor() * AMBIENTLIGHT; // Add ambient light to the calculation

// Reflections
if(closestObjectMaterial.GetSpecular() > 0 && closestObjectMaterial.GetSpecular() <= 1)
{
    Vector scalar = closestObjectNormal * (closestObjectNormal.Dot(intersectingRayDir.Negative()));
    Vector resultantReflection = intersectingRayDir.Negative() + ((scalar + (intersectingRayDir)) * 2);
    Vector reflectionDirection = resultantReflection.Normalize();

    Ray reflectionRay(intersectionRayPos, resultantReflection);

    // determine what the ray intersects with first
    std::vector<FPType> reflectionIntersections;
    for(auto sceneObject : sceneObjects)
    {
        reflectionIntersections.push_back(sceneObject->GetIntersection(reflectionRay));
    }

    int closestObjectWithReflection = ClosestObjectIndex(reflectionIntersections);

    if(closestObjectWithReflection != -1)
    {
        // reflection ray missed everthing else
        if(reflectionIntersections[closestObjectWithReflection] > TOLERANCE)
        {
            // determine the position and direction at the point of intersection with the reflection ray
            // the ray only affects the color if it reflected off something
            Vector reflectionIntersectionPosition = intersectionRayPos + (resultantReflection * (reflectionIntersections[closestObjectWithReflection]));
            Vector reflectionIntersectionRayDirection = resultantReflection;
            Color reflectionIntersectionColor = GetColorAt(reflectionIntersectionPosition, reflectionIntersectionRayDirection, sceneObjects, closestObjectWithReflection, lightSources);
            finalColor += (reflectionIntersectionColor * closestObjectMaterial.GetReflection());
        }
    }
}

我在所有反射中都看到了这些颗粒状的伪影(这是放大的 16k 分辨率渲染):

但是,在 1920x1080 等较低分辨率下,这一点更加明显:

【问题讨论】:

    标签: c++ graphics 3d rendering raytracing


    【解决方案1】:

    我认为问题在于反射光线会撞击自身。我没有重新编译代码来确认这一点。您可以尝试在反射光线的起始位置添加一些偏移量。

    Vector offset = resultantReflection * 0.001;
    Ray reflectionRay(intersectionRayPos + offset, resultantReflection);
    

    【讨论】:

    • 我最终使用了这个,resultantReflection 也需要标准化。 Vector offset = reflectionDirection * 0.001; Ray reflectionRay(intersectionRayPos + offset, resultantReflection);
    • 在您添加的 cmets 中 // 添加偏移以抵消反射中的颗粒感实际问题是,从反射对象 A 开始的光线被认为是撞击自身,因为它是离射线起始位置最近的物体。因此,为了避免这种情况,我们将光线从物体 A 的表面稍远处开始。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-11
    • 2017-05-03
    • 2018-05-31
    • 2017-03-30
    相关资源
    最近更新 更多