- •Задание
- •Аннотация
- •1.2 Пересечение лучей с эллиптическим параболоидом
- •1.3 Пересечение лучей с гиперболическим параболоидом
- •1.3 Модель освещения Фонга
- •2. Практическая часть
- •2.1 Эллиптический параболоид
- •2.2 Гиперболический параболоид
- •Тени и составляющие света
- •Визуализация объектов, отражающих свет
- •Заключение
- •Список используемых ресурсов
Тени и составляющие света
1. Расчет фоновой и зеркальной (с использованием модели освещения Фонга) составляющих отраженного света.
Необходимо реализовать возможность учета фоновой (ambient) и зеркальной (specular) составляющих отраженного света при расчете цвета поверхности
Для выполнения этой задачи в классы CSimpleMaterial и LightSourceImpl были добавленны следующие свойства:
CVector4d m_diffuseIntensity;
CVector4d m_specularIntensity;
CVector4d m_ambientIntensity;
А так же методы, позволяющие изменять и получать значения этих свойств.
В класс SimpleDiffuseShader были добавлены формулы для вычисления составляющих света, взятые из прошлых лабораторных работ:
CVector3d reflectedLight = lightDirection - 2 * Dot(n, lightDirection) * n;
CVector3d eye = -shadeContext.GetRayDirection();
double specularFactor = max(Dot(-reflectedLight, eye), 0.0);
double materialShiness = m_material.GetShiness();
double specularIntensity = pow(specularFactor, materialShiness / 100) * 0.001;
CVector4d specularColor = light.GetDiffuseIntensity() * m_material.GetDiffuseColor() * specularIntensity;
specularColor.w = 1.0;
CVector4d ambientColor = light.GetAmbientIntensity() * m_material.GetAmbientColor() * lightIntensity;
CVector4d diffuseColor = nDotL * light.GetDiffuseIntensity() * m_material.GetDiffuseColor()* lightIntensity;
2. Визуализация теней.
Необходимо реализовать визуализацию трехмерной сцены с учетом теней, отбрасываемых
объектами сцены. Для этого при расчете освещения точки поверхности проверить отсутствие
препятствий на пути света от источника к данной точке.
При выполнении этой задачи был изменен класс SimpleDiffuseShader.
Наличие тени определялось условием, если объект находится за объектом, то для него вычислялась только фоновая составляющая света.
CIntersection bestIntersection;
CSceneObject const * pSceneObject = NULL;
if(scene.GetFirstHit(CRay(point, lightDirection), bestIntersection, &pSceneObject)
&& bestIntersection.GetHit(0).GetHitTime() <= 1)//проверяем, чтобы находилось за объектом
{
shadedColor += (ambientColor);
}
else
shadedColor += (diffuseColor + specularColor + ambientColor);
И класс CheckerShader. В него было внесено подобное изменение, только вместо вычисления фоновой составляющей, объекту придавался черный цвет
if(scene.GetFirstHit(CRay(point, lightDirection), bestIntersection, &pSceneObject)&& bestIntersection.GetHit(0).GetHitTime() <= 1)//проверяем, чтобы находилось за объектом
return CVector4d(0, 0, 0, 1);
Визуализация объектов, отражающих свет
В процессе осуществления этой цели был разработан класс CReflectShader
#pragma once
#include "ishader.h"
#include "SimpleMaterial.h"
class CReflectShader :
public IShader
{
public:
CReflectShader(CSimpleMaterial const& material = CSimpleMaterial(), int recLevel = 3);
void SetMaterial(CSimpleMaterial const& material);
/*
Вычисление цвета с объекта
*/
virtual CVector4d Shade(CShadeContext const & shadeContext, int recLevel)const;
private:
CSimpleMaterial m_material;
bool m_dual;
};
Отличительной особенностью данного класса является контроль вложенности рекурсии. В функцию Shade параметром передается максимальное возможное число вложенности. И с каждой итерацией это число декрементируется:
CScene const& scene = shadeContext.GetScene();
// Результирующий цвет
CVector4d shadedColor;
CVector3d point = shadeContext.GetSurfacePoint();
CVector3d normal = shadeContext.GetSurfaceNormal();
CVector3d dir = shadeContext.GetRayDirection();
CVector3d reflectedDir = dir - 2 * Dot(normal, dir) * normal;
if(recLevel > 0)
{
shadedColor = scene.Shade(CRay(point, reflectedDir), recLevel-1);
}
else
shadedColor = CVector4d(0, 0, 0, 1);
Естественно, что зеркало не может отразить весь свет, падающий на него, поэтому в данном шейдере также расчитываются составляющие света, зависящие от материала, и в конце концов, итоговый цвет суммируется.