1

所以我在使用 Phong 模型时遇到了问题,特别是漫反射分量,并且使用了正确的法线向量和光向量的方向。这是一个学校项目,但我不在乎我是否没有完成它,只要有人能告诉我我做错了什么。我已经尝试了一些事情,我做的最好的就是让一半的较大球体遮蔽,但方向错误。最亮的强度位于半圆的外边缘,当它向中心移动时会变暗,而应该是相反的方向。当我看到看起来像在空圆圈中着色的模型时,它看起来像是在线条上对球体进行着色。

第二个球体的阴影可能很难看到。 阴影球体

相关结构:

struct Ray
{
    vec3 origin;        // origin of the ray
    vec3 dir;           // direction of the ray
};

struct Sphere
{   
    vec3 center;
    float radius;       
    vec3 ka, kd, ks;
    vec3 reflectivity;
    float alpha;        

    Sphere(const vec3& ic=vec3(0.0f), const float& ir=0.0f, const vec3& ika=vec3(0.0f), const vec3& ikd=vec3(0.0f), const vec3& iks=vec3(0.0f), const float& ireflectivity=0.1f, const float& ialpha=1.0f):
    center(ic), radius(ir), ka(ika), kd(ikd), ks(iks), reflectivity(ireflectivity), alpha(ialpha)
    {}

    bool intersect(const Ray& ray, float& t0, float& t1);
};

struct PointLight
{
    vec3 location;
    vec3 id, is;    

    PointLight(const vec3& iloc=vec3(0.0f), const vec3& iid=vec3(0.0f), const vec3& iis=vec3(0.0f)):
    location(iloc), id(iid), is(iis)
    {}

};

    vec3 color;
    vec3 amb = my_sphere.ka* my_ambient_light.ia;   // I = ka * ia  ambient component
    int temp = my_point_lights.size() - 1;
    color += amb;

    vec3 diff;
    for (int i = my_point_lights.size() - 1; i >= 0; i--) {
        vec3 n = (ray.origin + ray.dir - my_sphere.center);
        normalize(n);

        vec3 L = (my_point_lights[temp].location - ray.origin);
        normalize(L);

        diff += my_sphere.kd * my_point_lights[temp].id * std::max(dot(n, L), 0.0f);
    }
    color += diff;
4

1 回答 1

1

您基本上似乎想要在着色器中做的是计算球体上给定点的漫反射着色。为此,您基本上需要两件事:首先,您要遮蔽的球体上该点的表面法线,其次,光线落在您要遮蔽的点的方向。现在,在您继续计算给定点的对象着色之前,您通常需要知道要着色的特定点的实际位置。由于您并没有真正提供任何解释ray.dir,您的代码中究竟代表什么,我将不得不求助于猜测。我假设您正在做的是片段着色器中的某种光线追踪。我不得不假设ray.dir不仅仅是指向在您感兴趣的点上击中球体的光线的大致方向的某个向量,而且它实际上是将您从光线的起点带到球体上的确切击中点向量. 否则,您将缺乏真正做任何事情的最重要信息,即您想要遮蔽的点的坐标。在这种情况下,您首先必须计算光线和球体的实际交点所在的位置。

现在,如果我们做出所有这些假设,并且我们进一步假设您拥有的所有这些向量实际上表示同一坐标系中的坐标,那么ray.origin + ray.dir - my_sphere.center确实应该产生一个从球体中心指向您想要着色的点的向量。并且该向量确实应该在您要着色的点处指向球体表面法线的方向。但是,您需要计算漫反射着色的第二个向量是一个向量,该向量指向光线从该方向照射到您要着色的点的方向。即从点到阴影指向光源的向量。但是,my_point_lights[temp].location - ray.origin它似乎是一个从光线原点指向光源的向量。

除此之外,可能应该提请您注意,与您的印象相反,该函数normalize(x)不会修改您作为参数传递的向量。它只是返回另一个向量,它是您提供给它的任何向量的规范化版本。所以,最有可能的是,你真正想要写的是

n = normalize(n);
…
L = normalize(L);

color此外,您在和中累积值diff,但您从未将这些向量初始化为任何东西。您可能打算将它们初始化为零……

于 2018-12-08T01:15:39.253 回答