Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Пояснительная записка к РГР Сокольников,ПС-31.docx
Скачиваний:
21
Добавлен:
20.04.2019
Размер:
274.1 Кб
Скачать

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

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

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

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

a=

b =

c=

Дискриминант d = и, если он не отрицателен, имеются корни:

;

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

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

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

  • N – нормаль к поверхности

  • L – направление к источнику света

  • R – направление отраженного луча

  • V – направление к наблюдателю

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

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

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

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

  • Is – зеркальная составляющая освещенности

  • ks- коэффициент зеркального освещения

  • is- интенсивность зеркального освещения

  • a – коэффициент блеска (свойство материала)

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

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

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

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

#pragma once

#include "GeometryObjectWithInitialTransformImpl.h"

#include "Ray.h"

#include "Intersection.h"

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

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

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

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

class CEllipticParaboloid :

public CGeometryObjectWithInitialTransformImpl

{

public:

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

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

virtual bool 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. Если скалярное произведение направления луча и нормали к точке больше нуля, то поворачиваем нормаль в другую сторону.

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

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

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

#pragma once

#include "GeometryObjectWithInitialTransformImpl.h"

#include "Ray.h"

#include "Intersection.h"

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

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

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

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

class CHyperbolicParaboloid :

public CGeometryObjectWithInitialTransformImpl

{

public:

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

virtual bool Hit(CRay const& ray, CIntersection & intersection)const;

};

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

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

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

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

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

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

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

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

hitNormal1InObjectSpace = -hitNormal1InObjectSpace;