Пересечение лучей с гиперболическим параболоидом

Пересечение лучей с гиперболическим параболоидом - student2.ru Слева изображен гиперболический параболоид. Его уравнение имеет вид:

x2-z2-y=0. Пересечение луча и гиперболоида можно изобразить так:

Пересечение лучей с гиперболическим параболоидом - student2.ru

Коэффициенты a,b,c:

a= Пересечение лучей с гиперболическим параболоидом - student2.ru

b = Пересечение лучей с гиперболическим параболоидом - student2.ru

c= Пересечение лучей с гиперболическим параболоидом - student2.ru

Дискриминант d = Пересечение лучей с гиперболическим параболоидом - student2.ru и,если он не отрицателен, имеются корни:

Пересечение лучей с гиперболическим параболоидом - student2.ru ; Пересечение лучей с гиперболическим параболоидом - student2.ru

Для вычисления нормали к точке также используется градиент.

Модель освещения Фонга

Модель освещения Фонга расширяет стандартную модель диффузного освещения, добавляя в нее зеркальную компоненту.

Пересечение лучей с гиперболическим параболоидом - student2.ru

  • N – нормаль к поверхности
  • L – направление к источнику света
  • R – направление отраженного луча
  • V – направление к наблюдателю

Причем каждый из векторов является единичным.

Зеркальная компонента освещения зависит от расположения наблюдателя. В реальной жизни можно заметить, что когда в солнечный день мы смотрим на «зеркальные» объекты (металл, вода, стекло и т.д.) освещенность объекта зависит на нашей точки обзора. При определенных углах заметны яркие блики.

С точки зрения физики, происходит примерно следующее: луч света отражается от гладкой поверхности, если этот луч попадает на сетчатку глаза, то мы видим яркий блик.

Таким образом, можно ввести некоторые дополнительные обозначения:

Пересечение лучей с гиперболическим параболоидом - student2.ru

  • Is– зеркальная составляющая освещенности
  • ks- коэффициент зеркального освещения
  • is- интенсивность зеркального освещения
  • a – коэффициент блеска (свойство материала)

Суммарная освещенность объекта будет определяться как сумма всех трех компонент освещенности.

Практическая часть

Эллиптический параболоид

Реализовать возможность построения с использованием трассировки лучей геометрический объект «Базовый геометрический параболоид»

#pragmaonce

#include"GeometryObjectWithInitialTransformImpl.h"

#include"Ray.h"

#include"Intersection.h"

/************************************************************************/

/* Геометрический объект "Элиптический параболоид" */

/* Ось цилиндра совпадает с осью z. Основание находится в плоскости z=0 */

/************************************************************************/

class CEllipticParaboloid :

public CGeometryObjectWithInitialTransformImpl

{

public:

CEllipticParaboloid(CVector3d const& pos, CMatrix4d const& transform);

/*пересечение луча с параболоидом*/

virtualbool Hit(CRay const& ray, CIntersection & intersection)const;

};

Вычисление нормали происходит следующим образом:

// Координатынормаликточке

CVector3d hitNormal1InObjectSpace = CVector3d(2*hitPoint1InObjectSpace.x, -1, 2*hitPoint1InObjectSpace.z);

if(Dot(hitNormal1InObjectSpace, ray.GetDirection()) > 0)

hitNormal1InObjectSpace = -hitNormal1InObjectSpace;

1. Вычисляется градиент

2. Если скалярное произведение направления луча и нормали к точке больше нуля, то поворачиваем нормаль в другую сторону.

Гиперболический параболоид

Реализовать возможность построения поверхности базового гиперболического параболоида, заданного на диапазоне координат x и y от -1 до +1. Точка пересечения луча с гиперболическим

параболоидом должна вычисляться аналитически.

#pragmaonce

#include"GeometryObjectWithInitialTransformImpl.h"

#include"Ray.h"

#include"Intersection.h"

/************************************************************************/

/* Геометрический объект "Гиперболический параболоид" */

/* Ось цилиндра совпадает с осью z. Основание находится в плоскости z=0 */

/************************************************************************/

class CHyperbolicParaboloid :

public CGeometryObjectWithInitialTransformImpl

{

public:

CHyperbolicParaboloid(CVector3d const& pos, CMatrix4d const& transform);

virtualbool Hit(CRay const& ray, CIntersection & intersection)const;

};

Вычисление нормали:

После вычисления корней уравнения, сортируем их в порядке возрастания

//сортировка

t1<t0?std::swap(t0,t1):false;

А дальше аналогично элиптическому параболоиду, только изменяем формулу градиента

// Координатынормаликточке

CVector3dhitNormal1InObjectSpace = CVector3d(2*hitPoint1InObjectSpace.x, -1, -2*hitPoint1InObjectSpace.z);

if(Dot(hitNormal1InObjectSpace, ray.GetDirection()) > 0)

hitNormal1InObjectSpace = -hitNormal1InObjectSpace;

Тени и составляющие света

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);

Наши рекомендации