PathTracing ShadowRay问题,球体全黑

时间:2019-07-12 14:52:55

标签: opengl glsl raytracing

因此,我正在基于OpenGL的光线跟踪器中完全基于着色器,而我正努力地了解阴影射线的问题所在。如果我将对象的辐射度乘以shadowRay输出,似乎只有球体的“边缘”变亮了

我多次验证代码,但没有找到问题的根源。

这就是我得到的:

Result

vec3 TraceShadowRay(vec3 hitPoint, vec3 normal, Object objects[3])
{
    Light pointLight;

    pointLight.position = vec3(0, 80, 0);
    pointLight.intensity = 2;

    Ray ShadowRay;
    ShadowRay.origin = hitPoint + normal * 1e-4;
    ShadowRay.dir = normalize(pointLight.position - ShadowRay.origin);
    ShadowRay.t = 100000;
    //ShadowRay.dir = vec3(0, 1, 0);

    for(int i = 0; i < 3; ++i)
    {
        if(objects[i].type == 0)
        {
            if(interectSphere(objects[i].position, objects[i].radius, ShadowRay))
            {
                return vec3(0);
            }
        }
        if(objects[i].type == 1)
        {
            if(intersectPlane(objects[i].normal, objects[i].position, ShadowRay))
            {
                return vec3(0);
            }
        }
    }
    float AngleNormalShadow = dot(ShadowRay.dir, normal);
    clamp(AngleNormalShadow, 0, 1);

    return GetLight(ShadowRay.origin, pointLight);// * AngleNormalShadow;
}

getLight函数:

vec3 GetLight(vec3 origin, Light light)
{
    return vec3(1, 1, 1) * light.intensity;
    //float dist = sqrt( ((origin.x - light.position.x) * (origin.x - light.position.x))  +   ((origin.y - light.position.y) * (origin.y - light.position.y)));
    //return (vec3(1, 1, 1) * light.intensity) / (4 * M_PI * ((origin - light.position).length * (origin - light.position).length));
}

intersectSphere函数:

bool interectSphere(const vec3 center, float radius, inout Ray r)
{
    vec3 o = r.origin;
    vec3 d = r.dir;

    vec3 v = o - center;

    float b = 2 * dot(v, d);
    float c = dot(v, v) - radius*radius;
    float delta = b*b - 4 * c;

    if(delta < 1e-4)
        return false;

    float t1 = (-b - sqrt(delta))/2;
    float t2 = (-b + sqrt(delta))/2;

    if(t1 < t2)
    {
        r.t = t1;
        r.t2 = t2;
    }
    else if(t2 < t1)
    {
        r.t = t2;
        r.t2 = t1;
    }

    r.reflectionNormal = normalize((r.origin + r.dir * r.t) - center);

    return true;
}

预期的结果是一个阴影良好的球体,光线来自球体顶部

1 个答案:

答案 0 :(得分:1)

这可能是一个否定的否定吗?看起来interectSphere()在发生冲突时返回true,但是在TraceShadowRay()中的调用代码在返回true时就会失败。

旧:

        if(interectSphere(objects[i].position, objects[i].radius, ShadowRay))
        {
            return vec3(0);
        }

新:

        if(!interectSphere(objects[i].position, objects[i].radius, ShadowRay))
        {
            return vec3(0);
        }