Raytracing / Phong Model Diffuse компонент

Поэтому у меня возникли проблемы с моделью Фонга, в частности с диффузным компонентом, и с использованием правильного вектора нормали и вектора направления света. Это для школьного проекта, но мне все равно, если я не закончу его, пока кто-то может сказать мне, что я делаю неправильно. Я уже попробовал несколько вещей, и лучшее, что я могу сделать, это заставить половину большей сферы заштриховать, но в неправильном направлении. Самая яркая интенсивность находится на внешнем крае половины круга и становится темнее, когда он идет к центру, когда это должно быть наоборот. Это выглядит как затенение сферы в линии, когда я видел модели, которые выглядят как затенение в пустых кругах.

Затенение второй сферы может быть трудно увидеть.
Затененные сферы

Соответствующие структуры:

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;

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Тем не менее, вы никогда не инициализируете эти векторы. Вы, вероятно, хотели инициализировать их нулем … ��

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]