До того, как это будет помечено как дубликат, у меня возникла та же проблема, что и у человека, который задал этот вопрос.
К сожалению, у него нет ответа, который помогвсе, так что, надеюсь, это вызовет лучшую дискуссию.Используя C ++, задача состоит в том, чтобы запрограммировать классический трассировщик лучей.Я использую модель затенения Фонга и могу точно освещать свои сцены до тех пор, пока мне не понадобится отбрасывать теневые лучи.
Просто для справки, вот изображение того, что у меня есть до сих пор без попыток тени:
Следуя традиционному алгоритму трассировки лучей, где я ищу ближайший объект к своей камере-обскуре, я вызываю следующую функцию, которая вычисляет результирующий цвет пикселя:
glm::vec3 Scene::illuminate(Ray* primary, Surface* object, glm::vec3 hitPt)
{
float red, green, blue;
Material m = object->getMaterial();
float p = m.phongCoef;
glm::vec3 kD = m.diffuse;
glm::vec3 kS = m.specular;
glm::vec3 kA = m.ambient;
float iA = m.ambienceIntensity;
float i = lightSrc.lightIntensity;
glm::vec3 n = object->getSurfaceNormalAt(hitPt); //normalized before return.
glm::vec3 viewRay = primary->getDirection(); //normalized class member.
glm::vec3 lightRay = glm::normalize((lightSrc.getOrigin()) - hitPt); //origin not normalized before here
glm::vec3 h = glm::normalize(viewRay + lightRay);
float nDotlightRay = glm::dot(n,lightRay);
float nDoth = glm::dot(n, h);
bool inShadow = false;
Ray shadowRay;
//hitPt = glm::normalize(hitPt);
shadowRay.setOrigin(hitPt);
shadowRay.setDirectionVector(lightRay);
for (int k = 0; k < objects.size(); ++k) {
if (objects.at(k)->intersect(shadowRay)) {
//std::cout<<shadowRay.getDirection().x<<","<< shadowRay.getDirection().y <<","<<shadowRay.getDirection().z<<"\n";
inShadow = true;
break;}}
//plug in to shading model
if (inShadow)
{
red = kA.x*iA;
green = kA.y*iA ;
blue = kA.z*iA ;
}
else{
red = kA.x*iA + kD.x*i*(fmax(0,nDotlightRay)) + kS.x*i*(powf((fmax(0, nDoth)),p));
green = kA.y*iA + kD.y*i*(fmax(0,nDotlightRay)) + kS.y*i*(powf((fmax(0, nDoth)),p));
blue = kA.z*iA + kD.z*i*(fmax(0,nDotlightRay)) + kS.z*i*(powf((fmax(0, nDoth)),p));
}
glm::vec3 pixelColor = glm::vec3(red, green, blue);
return pixelColor;
}
Я пытался использовать описательные имена переменных / функций, чтобы минимизировать объяснение, сопровождающее мой код.glm::vec3
- это просто структура данных из математической библиотеки GLM, которая содержит трехмерный вектор, на котором можно выполнять матричные / векторные манипуляции.
Как и в приведенном выше вопросе, вот как выглядит моя сцена после попытки теней.
Положение света для этой сцены (0, 2,5, -7,75) выражено в системе отсчета камеры (которая имеет начало отсчета (0, 0,0) и обращена в отрицательном направлении z).Для другой сцены источник света находится в точке (4, 6, -1), и для этого выходной сигнал даже не согласуется с проблемами другой сцены, которую я пытался воспроизвести, как вы можете видеть здесь ;у него только тонкая серая линия на вершине сцены, где-то больше нет теней?Я полностью потерян и потратил около 10 часов на эту проблему в одиночку;Будем признательны любому совету.
Пожалуйста, дайте мне знать, если есть какая-либо другая информация, которую я могу предоставить, например, как я вычисляю расстояние и HitPoint ??Я не знаю, стоит ли мне смотреть на них, так как часть затенения работает отлично, или вы, ребята, думаете, что это все еще может вызвать эту проблему?Глубина и тому подобное не должны быть проблемой, поскольку объекты выглядят корректно вплоть до теней?