Перейти к содержимому


Свернуть чат Чат Открыть чат во всплывающем окне

Yakim (Watco... : (2 недель назад) ?
Yandersen : (2 недель назад) Проблемы?..
Yakim (Watco... : (2 недель назад) Какие проблемы?
lz : (2 недель назад) Какие проблемы? Проблемы с другими движками?
GranMinigun : (2 недель назад) Где я предлагал заняться рефакторингом? Я спрашивал, в чём именно проблемы.
Гость : (2 недель назад) пускай они там как нибудь сами, без меня)
GranMinigun : (3 недель назад) Анрил с видимым исходным кодом таки. Но да, у СруДвижка только сырцы самого движка и свободны. А что конкретно за проблемы в коде СруДвижка? Я видел, что у них в планах провести рефакторинг в ближайший апдейт или два. С точки зрения инструментария, к слову, СруДвижок серьёзно подтянулся в последних версиях, я даже решил таки поближе ознакомиться. (А вообще, мне он понравился графическими технологиями, особенно подходом к освещению.)
Yakim (Watco... : (3 недель назад) люто плюсую Егор)
lz : (3 недель назад) Движок большой, функционала много, код качественный (не как у крузис енгине) и всё такое.
lz : (3 недель назад) Анреал открытый, взрослый, на С++. Пока проект некоммерческий денег заносить никому не надо.
lz : (3 недель назад) Да не, на самом деле у меня даже где-то описано, что графический движок можно заменить при необходимости.
lz : (3 недель назад) Потому что анреал - офигенная тема.
GranMinigun : (3 недель назад) Кстати, Егор. А почему выбор движка пал именно на UE4? Какие-то предпосылки к этому были?
lz : (3 недель назад) Я подумал на карту механоидов побольше добавить для фана, а надо ж запаковывать ещё.
lz : (3 недель назад) Спс, это я и писал)
GranMinigun : (3 недель назад) Только распаковщик. Сторонний. Точнее, его создал lz.
Гость : (3 недель назад) а интересно, есть ли где упаковщик для м1? в сдк или может где встроен в саму игру или редактор
Folgen : (4 недель назад) Спс.
GranMinigun : (4 недель назад) Готово. Добро пожаловать на форум, механоид.
GranMinigun : (4 недель назад) Указать, кого именно активировать, например.
Гость : (4 недель назад) Активируйте акк. Хз, нужно что-либо указывать дополнительно для этого в чате, или админы сами всех подряд активируют, кто в очереди на активацию?
GranMinigun : (13 Январь 2018 - 05:42) https://forums.unrea...sed-on-gis-data
Yakim (Watco... : (09 Январь 2018 - 00:24) Аа да? Ну окей)
GranMinigun : (08 Январь 2018 - 20:06) А это даже не обсуждается!
Yakim (Watco... : (08 Январь 2018 - 19:55) А кто сказал что мы пьянели?)
GranMinigun : (08 Январь 2018 - 19:48) Ну что, товарищи, протрезвели?
Yakim (Watco... : (02 Январь 2018 - 20:56) сяп)
Гость : (01 Январь 2018 - 23:57) Егорыч на праздники с каникул вернулся. За это тост! Всем маны!
lz : (30 Декабрь 2017 - 23:52) Наоборот.
Гость : (30 Декабрь 2017 - 23:16) Позвольте уточнить, для будущего наркомана прошлое это будущее или наоборот?
lz : (30 Декабрь 2017 - 22:08) Как ты его поймаешь, когда он знает, где ты его будешь ловить?
GranMinigun : (30 Декабрь 2017 - 09:12) Ловите наркомана из будущего!
PA3UJIb : (30 Декабрь 2017 - 06:37) С новым 2018 годом! А то старый-то 2018 мы и не видели даже
Yakim (Watco... : (29 Декабрь 2017 - 19:46) С наступающим)
Yakim (Watco... : (29 Декабрь 2017 - 19:45) гы
lz : (29 Декабрь 2017 - 18:34) Посоны, с наступающим всех!
Yakim (Watco... : (28 Декабрь 2017 - 21:55) +
lz : (28 Декабрь 2017 - 20:22) Много капитанства.
lz : (28 Декабрь 2017 - 20:22) +
Yakim (Watco... : (28 Декабрь 2017 - 18:56) ну такое
Gaantro : (28 Декабрь 2017 - 03:41) Описывает принцип работы.
Gaantro : (28 Декабрь 2017 - 03:41) Антиграв*
Gaantro : (28 Декабрь 2017 - 03:41) Система Grable в Star Citizen (Антигуа) : https://youtu.be/2VkzHbJiCAo
Yakim (Watco... : (26 Декабрь 2017 - 17:38) Ага :lol:
lz : (26 Декабрь 2017 - 17:35) Чё там у нас? Пошла жара? Главное, чтобы не такое генерилось https://youtu.be/RvAwB7ogkik

Фотография
- - - - -

[Camera.hpp] - камера с реалистичными свойствами

OpenGL Camera FBO Deferred shading

  • Авторизуйтесь для ответа в теме
В этой теме нет ответов

#1 OFFLINE   Yandersen

Yandersen

    Диванный теоретик

  • Админ
  • 454 сообщений
  • Откуда:Canada
  • Настоящее имя:Ян

Отправлено 21 Апрель 2015 - 02:18

Класс камеры CCamera, реализующий перспективную проекцию с реалистичными свойствами (нет дальней плоскости отсечения, сверхмалая ближняя плоскость отсечения):

 

Camera.hpp

 

:!: Требует LoadGL.h, GLSL.hpp, Origin.hpp, FBO.hpp. Плюс необходима поддержка OpenGL4.5 (DSA, ARB_clip_control).

 

Кидаем файл в проект, подключаем:

#include "Camera.hpp"

Изменяем настройку glClipControl:

glClipControl(<...>, GL_ZERO_TO_ONE);

:!: С дефолтной настройкой (GL_NEGATIVE_ONE_TO_ONE) камера не будет работать корректно!

 

Каждая камера класса CCamera имеет свой собственный FBO и использует floating-point depth buffer (буффер глубины). Буффера трафарета (stencil buffer) нет. Цветовых буфферов может быть до 8. В качестве буфферов используются текстуры (создаются и удаляются классом CCamera):

GLuint CCamera::AddDepthBuffer(int Width, int Height, bool WithMipmaps = true);
GLuint CCamera::AddColorBuffer(unsigned ID, GLenum internalFormat,
                               int Width, int Height, bool WithMipmaps = true);

Width и Height - размеры требуемого буффера, флаг WithMipmaps определяет, будут ли у текстуры мипмапы (если false, то мипмапов не будет). В случае создания буффера цвета нужно указать индекс ID создаваемого буффера (0...7) и формат пикселя текстуры (значения internalFormat см. тут). Возвращённое значение - имя созданной текстуры или 0 если создать текстуру не удалось.

:!: Свойства текстуры позволяется менять (glTexPartameter), но изменять размеры или удалять - нельзя. Для удаления требуемого буффера используйте 0 в качестве аргумента Width или Height.

 

Для изменения размеров сразу всех буфферов используйте

bool CCamera::ResizeBuffers(int Width, int Height);

:!: Все свойства каждого из буфферов будут воссозданы, но имена текстур могут измениться.

Чтобы узнать имя текстуры конкретного буффера используйте

inline GLuint GetColorBufferTextureName(unsigned ID)const;
inline GLuint GetDepthBufferTextureName()const;

Эффективные размеры фреймбуффера равны минимуму размеров всех его буфферов. Узнать можно так:

inline ivec2 GetFrameSize()const;

Геометрические свойства камеры показаны на следующей схеме:

 

Camera.png

 

Используемая матрица перспективной проекции имеет следующий вид:

     | 2*zNear                      |
     | -------    0      0      0   |
     |  xSize                       |
     |         2*zNear              |
     |    0    -------   0      0   |
     |          ySize               |
 P = |                              |
     |    0       0      0    zNear |
     |                              |
     |                              |
     |    0       0     -1      0   |
     |                              |

Перспектива задаётся следующей функцией:

inline bool CCamera::SetupPerspective(float FOVy, float NearClippingPlane);

FOVy - угол обзора (по вертикали). NearClippingPlane - это расстояние до ближней плоскости отсечения (zNear на рисунке). FOVy должен быть больше 0 и меньше 180 градусов, а NearClippingPlane (zNear) - больше нуля. Геометрические размеры проекционной плоскости (xSize, ySize) будут вычислены автоматически и их отношение будет соответствовать отношению ширины и высоты фреймбуффера.

:!: При изменении размеров фреймбуффера размеры проекционной плоскости и zNear могут измениться, однако угол обзора по вертикали останется тем же.

 

Угол обзора можно менять так:

inline void CCamera::ChangeFOV(float FOVy);

Изменение угла обзора будет достигнуто за счёт приближения/удаления проекционной плоскости (изменение zNear); размеры проекционной плоскости (xSize, ySize) при этом останутся неизменными.

Узнать размеры проекционной плоскости можно так:

inline vec2 CCamera::GetPlaneSize()const;

Изменить размеры проекционной плоскости можно функцией SetPlaneSize, принимающей в качестве параметра желаемый размер проекционной плоскости - её текущие размеры будут отмасштабированы таким образом, что наибольшее из измерений станет равно заданной величине:

CCamera MyCamera;
... //Setup buffers, configure perspective
vec2 Dims = MyCamera.GetPlaneSize(); //Assume that Dims.x==640.f, Dims.y==480.f

float SquareApertureWidth = 0.01f; //Aperture has square shape, 1cm in width
MyCamera.SetPlaneSize(SquareApertureWidth);
Dims = MyCamera.GetPlaneSize(); //Dims.x==0.01f, Dims.y==0.0075f

:!: zNear при этом изменится, а угол обзора останется прежним.

 

Расстояние до проекционной плоскости (ближняя плоскость отсечения, zNear) читается так:

inline float CCamera::GetNearClippingPlane()const;

Угол обзора по диагонали всегда больше угла обзора по вертикали. Узнать его можно так:

float CCamera::GetViewAngleMax()const;

:!: Половина этого значения - это угол между высотой и образующей конуса видимости, в который вписана усечённая пирамида видимого камерой объёма.

 

Класс CCamera содержит указатель на объект класса COriginf (система координат). Ориентация камеры в пространстве привязана к ориентации системы координат Origin. Если указателя нет, то используется ориентация по-умолчанию: Ox={1,0,0}, Oy={0,1,0},Oz={0,0,1}, Center={0,0,0}.

Направление взгляда - это ось -Oz, направление направо - ось Ox, вверх - Oy. Узнать направление взгляда можно так:

inline vec3 CCamera::GetViewDirection()const;

Узнать координаты вектора, соответствующего направлению от центра координат до пикселя фреймбуффера с указанными координатами можно так:

inline vec3 CCamera::PixelToRay(const ivec2& PixelCoordinates)const;

:!: Учтите, что перед вычислением этого направления указанные координаты пикселя будут ограничены нулём, шириной и высотой фреймбуффера.

 

CCamera умеет работать с тремя матрицами:

mat4 ModelViewMatrix: трансформация из мировой системы координат в систему координат камеры (поворот, смещение);

mat4 ProjectionMatrix: из системы координат камеры в проеционное пространство (проекция);

mat4 TransformationMatrix: из мировой системы координат в проекционное пространство (поворот, смещение, проекция).

А также соответствующими им обратными матрицами ModelViewMatrixInverse, ProjectionMatrixInverse, TransformationMatrixInverse.

Конструируют эти матрицы следующие функции класса:

//Return ModelView matrix
inline mat4 CCamera::GetModelViewMatrix()const;
//Return Inverse of the ModelView matrix
inline mat4 CCamera::GetModelViewMatrixInverse()const;
//Return the Projection matrix
mat4 CCamera::GetProjectionMatrix()const;
//Return inverse of the Projection matrix
mat4 CCamera::GetProjectionMatrixInverse()const;
//Return the full transformation matrix
inline mat4 CCamera::GetTranformationMatrix()const;
//Return inverse of the full transformation matrix
inline mat4 CCamera::GetTranformationMatrixInverse()const;

Перенаправляем рендер во фреймбуффер требуемой камеры так:

inline void CCamera::StartCapturing()const;

Очистка буфферов:

//Clear one of the color buffers (it's index is specified as BufferID); color
//must be specified as vec4, ivec4 or uvec4
template<class T>
inline void CCamera::ClearColorBuffer(unsigned int ID, const T& tvecRGBA);
//Clear all of the color buffers simultaneously with the same value
inline void CCamera::ClearColorBuffers(const vec4& vecRGBA){ FBO.ClearColor(vecRGBA); }
//Clear the depth buffer
inline void CCamera::ClearDepthBuffer(GLfloat Value=0.f){ FBO.ClearDepth(Value); }
//Clear all of the color buffers and the depth buffer
inline void CCamera::ClearBuffers(const vec4& ColorRGBA, float Depth=0.f);

По оканчании рендера скопировать картинку на экран можно с помощью этой функции:

inline void CCamera::ShowFrame(unsigned ColorBufferID=0,
                               GLint ScreenWidth=0, GLint ScreenHeight=0)const;

Тут ColorBufferID - индекс буффера цвета, в котором находится желаемое изображение. ScreenWidth, ScreenHeight - размеры экрана: если указаны (отличны от нуля), то картинка будет растянута/сжата под размер экрана; если же размер экрана не указан, то копирование пойдёт пиксель-в-пиксель, и если размеры фреймбуффера камеры и экрана не равны, картинка либо обрежется, либо не замостит весь экран.







Темы с аналогичным тегами OpenGL, Camera, FBO, Deferred shading

Количество пользователей, читающих эту тему: 0

0 пользователей, 0 гостей, 0 анонимных