所以我在使用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;
答案 0 :(得分:1)
您基本上想在着色器中执行的操作是计算球体上给定点的漫反射着色。为此,您基本上需要做两件事:首先,要阴影的球体上该点的表面法线,其次,光线落在要阴影的点上的方向。现在,在继续计算给定点的对象的阴影之前,通常需要知道要阴影的特定点的实际位置。由于您并未真正提供任何解释,因此ray.dir
之类的东西实际上在您的代码中真正代表了什么,因此,我将不得不依靠猜测。我假设您正在做的是片段着色器中的某种射线追踪。而且我必须假设ray.dir
不仅是指向您感兴趣的点击中球体的射线的大方向的矢量,它实际上是 the 向量,它将使您从射线的起点到球体上的确切命中点。否则,您将缺少最重要的信息来真正执行任何操作,这是您想要遮挡的点的坐标。在这种情况下,您首先必须计算射线与球体的实际交点在哪里。
现在,如果我们进行所有这些假设,并且进一步假设您拥有的所有这些向量实际上都代表同一坐标系中的坐标,那么ray.origin + ray.dir - my_sphere.center
实际上应该产生一个从球体中心指向要遮挡的点。该矢量确实应该指向您要着色的点的球体表面法线方向。但是,您需要计算漫反射着色的第二个矢量是指向光线从其射到要着色的点的方向的矢量。即,从点到阴影指向光源的向量。但是,my_point_lights[temp].location - ray.origin
似乎是从射线原点指向光源的向量。
除此之外,应该提醒您注意,与您似乎对它的印象相反,函数normalize(x)
不会修改您作为参数传递的向量。它只是返回另一个向量,该向量是您提供给它的任何向量的规范化版本。因此,最有可能的是,您真正要写的是
n = normalize(n);
…
L = normalize(L);
此外,您在color
和diff
中累积值,但从未将这些向量初始化为任何值。您可能打算将它们初始化为零…