- •Учебник
- •Оглавление
- •Введение
- •Глава 1
- •I. Установка
- •II. Удаление
- •Глава 2. Первый проект
- •Глава 3. Создание сцены в режиме design time
- •Создание объектов:
- •Глава 4. Примитивные объекты. Вкладка Basic geometry.
- •Глава 5. Ориентация, координаты.
- •Глава 6. Движение.
- •Глава 7. Как узнать, сколько сейчас fps?
- •Глава 8. Полноэкранный режим.
- •Глава 9. Работа с материалами.
- •I. Прямое обращение к .Material
- •Глава 10. Использование 3d моделей.
- •I. Форматы моделей
- •Глава 11. Прокси объекты.
- •Глава 12. Создание земной поверхности с glTerrainRenderer.
- •Глава 13. Создание земной поверхности с glFreeForm.
- •Глава 14. Итоги работы с glTerainrender и glFreeForm.
- •Глава 15. Создание земной поверхности с glHeightField.
- •Глава 15. Создание неба.
- •Глава 16. GlAtmosphere.
- •Глава 17. Спецэффекты.
- •I. Огонь
- •II. Молния
- •III. Дождь
- •IV. Снег
- •VI. Блики от источников света
- •Глава 18. Растительность.
- •I. Деревья и кустарники
- •II. Трава
- •Глава 19. Работа со шрифтами и вывод надписей.
- •I. Вывод текста через компонент glWindowsBitmapFont
- •II. Проблема с glWindowsBitmapFont в Windows Vista
- •Глава 20. Выделение объекта мышкой.
- •Глава 21. Создание сцены в режиме runtime.
- •Глава 22. Тени.
- •Глава 23. Туман.
- •Глава 24. Vbo или расширение arb_vertex_buffer_object в OpenGl.
- •Глава 25. Fbo или расширение ext_framebuffer_object в OpenGl.
- •Глава 26. Рисование на канве.
- •Глава 27. Использование чистого OpenGl.
- •Глава 28. Звуки.
- •I. Проигрывание звуков с помощью bass
- •II. Проигрывание звуков с помощью fmod
- •III. Проигрывание звуков с помощью OpenAl
- •Глава 29. Игровое меню.
- •Глава 30. Примитивная физика dce.
- •Глава 31. Физика ode.
- •II. Основы библиотеки ode(: tglodeManager и tglodeJointList) на примере создания подобия боулинга.
- •Глава 32. Физика Newton.
- •Глава 33. Ручная проверка коллизий.
- •V. Ручная проверка коллизии
- •Глава 34. Шейдеры. Терменология.
- •Глава 35. Шейдеры. История и компоненты.
- •Глава 36. Шейдеры glsl. Введение.
- •Глава 37. Шейдеры glsl. Использование без компонентов. Самый примитивный шейдер.
- •Глава 38. Шейдеры glsl. Немного о спецификации. Типы данных и переменные
- •Стандартные функции
- •Поддерживаемые компоненты векторов
- •Глава 40. Шейдеры glsl. Текстурирование.
- •Глава 41. Шейдеры glsl. Использование без компонентов. Мультитекстурирование. Смешение трёх цветов по базовой карте.
- •Глава 42. Шейдеры glsl. Использование через компонент glslShader. Часть первая – Первые шаги.
- •Глава 43. Шейдеры glsl. Использование через компонент glslShader. Часть вторая – знакомимся со светом. Передача параметров в шейдер.
- •Глава 44. Шейдеры glsl. Использование через компонент glslShader. Часть третья – текстуры.
- •Глава 45. RenderMonkey.
- •Глава 46. Оптимизация программы.
- •Глава 47. Практика. Создание мира
- •Приложение
- •I. Типы векторов и матриц
- •II. Работа с векторами
- •III. Работа с матрицами
- •IV. Методы объектов glScene
- •Предметный указатель по компонентам glScene
Глава 22. Тени.
I. ShadowPlane
ShadowPlane похож на обычный GLPlane. Особенностью ShadowPlane является то, что он поддерживает тени.
Создадим примитивное приложение, использующее ShadowPlane:
1. Создайте камеру, свойство Position.Z сделайте равным 10
2. Создайте GLSceneViewer, присвойте свойству Camera нашу камеру
3. Создайте инспектор объектов сцены (GLScene)
4. Создайте в сцене шарик (GLSphere)
5. Создайте источник света (LightSource)
В общем, всё как обычно.
6. Добавляем ShadowPlane, свойству ShadowLight присваиваем наш источник света (LightSource), свойству ShadowingObject присваиваем объект, который будет отбрасывать тень (GLSphere).
Всё! Запускаем и наслаждаемся тенями. Внизу расположена отлично иллюстрирующая картинка.
Если объектов, от которых должна идти тень, много, то свойству ShadowingObject следует представить DummyCube, предварительно поместив в него все объекты, от которых должна идти тень.
Неплохой пример можно посмотреть в стандартной папке demos по такому пути: …\Demos\specialsFX\shadowplane
II. GLShadowVolume
Тени можно строить при помощи стандартного компонента GLScene GLShadowVolume. Алгоритм этого компонента используется в “Doom 3” и в "Chronicles of Riddick". Тени выглядят достаточно хорошо, но требуют немало ресурсов. Компонент весьма заморочен, но разобраться можно! Создавать тени, используя GLShadowVolume, так:
1. Ставим в сцену объект GLShadowVolume. 2. Все, на что падает тень, вставляем в GLShadowVolume (то есть он должен быть родительским типом). 3. Создаём источник света и добавляем его в список GLShadowVolume1.Ligths. 4. Добавляем все объекты, которые отбрасывают тень, в список GLShadowVolume1.Occluders (во время выполнения так - GLShadowVolume1.Occluders.AddCaster(obj: TGLSceneBaseObject;)).
5.Не забывайте всегда присваивать GLSceneViewer1.Buffer.ContextOptions.roStencilBuffer:= True;
Совсем неплохие тени даёт компонент GLShadowVolume.
Пример можно посмотреть в стандартной папке demos по такому пути: Demos\specialsFX\shadowvolumes
III. GLZShadows
GLZShadows обеспечивает хорошие, но некудышно реализованные тени (подобные были в SplinterCell3). ZShadow рендерит в текстуру с положения источника света, потом эту текстуру накидывает на объекты.
А теперь сделаем пример с использованием GLZShadows
1. Кидаем на форму GLMemoryViewer (вкладка GLScene), в нем Width и Height это разрешение рендеримой текстуры (текстуры самой тени) 2. В сцену добавляем еще одну камеру, ставим в MemoryViewere (в свойство Camera) эту камеру.
3. Добавляем источник света (GLLightSource) 4. Добавляем объект GLPlane, открываем у него вкладку Material, затем вкладку Texture, выставляем Disabled=false, а TextureMode=tmModulate 5. Добавляем ZShadows; здесь свойство Viewer - вьювер, которым ты видишь сцену (при создании он называется GLSceneViewer1), и Caster - только что созданный MemoryViewer. 6. Теперь каждый раз, когда будет вызван метод GLZShadows.CastShadow, тени будут рендерится. Создайте каденсер и поместите это (GLZShadows.CastShadow) в его событие OnProgress.
Хороший пример можно скачать тут http://userlink.ru/glscene/download.php?view.103
Ещё один пример можно взять в стандартной демке по пути: Demos\specialsFX\shadows, но там демка прямо скажу “не ахти”.
Вот такие тени у меня получились.
IV. Lightmap
Lightmap (лайтмап, лайтмэп, в переводе с англ. — карта освещения) — метод освещения пространства в 3D-приложениях, заключающийся в том, что создается текстура, содержащая информацию об освещённости трехмерных моделей.
Этот метод значительно экономит ресурсы системы, так как не приходится рассчитывать падение света в режиме реального времени, но при этом проигрывает динамическому освещению в реалистичности.
Почти всегда карты освещения выравниваются с обычными текстурами полигонов, и каждый пиксель карты соответствует 4-32 текселам текстуры. Размеры карты определяются размерами минимального, ограничивающего полигон прямоугольника, стороны которого параллельны текстурным векторам. Этот метод применяется для создания всего статического освещения сцены. Освещение генерируется для статической геометрии до начала цикла рендеринга, и во время рендеринга в основном не изменяется. На современном оборудовании реализация полностью динамического освещения с использованием карт освещения невозможна из-за большой ресурсоемкости процесса создания лайтмэпов. Этот подход рассматривается как основа для большинства других алгоритмов рендеринга теней в реальном времени.
При создании карта заполняется черными пикселями. Далее, для каждого тексела карты освещения находятся трехмерные координаты точки на полигоне. Для этой точки необходимо построить список всех источников света, которые влияют на ее освещение: вектора из данной точки до источников света проверяются на пересечение с геометрией сцены, и если пересечение имеет место — то этот источник света не освещает точку (относительно него точка в тени). Остальные источники увеличивают значение тексела Lightmap на величину, зависящую от используемой модели освещения и положения источника света относительно точки. В целях улучшения внешнего вида картинки, к картам освещения часто применяется билинейная фильтрация. Эти операции повторяются для каждого освещаемого полигона сцены.
Во время рендеринга, карты освещения могут накладываться вторым проходом, с использованием альфа-блендинга. При наличии мультитекстурного оборудования можно накладывать текстуру и карту освещения за один проход.
Итак, как же это вложить в GLScene? Ответ прост. Начнём!
Для удачного запуска проекта необходимо создать в папке, из которой запускается проект, файл House.3DS. В нём придётся провести некоторую подготовительную работу. Я использовал 3DS max. Итак, нужно:
1. Создать модель.
2. Те полигоны, которые имеют различные материалы – поместить в отдельные объекты.
3. Расставить источники света.
4. Всем обьектам назначить материал.
5. С отдельных объектов нужно отрендить карты освещения. Выберите в меню Render\Render to texture (или кнопка “0”), в открывшейся форме выбираем линейку “Output ”, в ней кнопку “Add”, там выбираем Lightmap. Далее меняем настройки, если нужно, и жмём Render. Затем нужно расставить текстурные координаты. Для расстановки текстурных координат нужно для определённой области EditMesh/PolyMesh назначить “UVW Map”
6. Склейте все отделные объекты в один без изменения material ID (кнопка Attach).
7. Вернитесь к назначеным материалам, в закладке Self-Illumination присвойте карты освещения.
А теперь в Delphi:
1)Создадим:
GLSceneViewer
GLScene и здесь создадим объект GLFreeForm, назовём его map (наша карта для хранения объектов), свойство UseMeshMaterials присвоим true.
Создадим, соответственно, GLCamera, присвоив свойству Position.Z:=5; Position.X:=5; Position.Y:=5;
Поместим на форму GLMaterialLibrary, назовём её Materials и будем грузить сюда материалы, от которых должна идти тень.
Теперь поместим ещё одну GLMaterialLibrary, назовём её LightMaps и будем грузить сюда текстуру с тенью, саму LightMap.
И на последок бросьте на форму GLCadencer.
Теперь создаём в LightMaps материал. Потом запишите в событии FormCreate следующий код:
procedure TForm1.FormCreate(Sender: TObject);
begin
Materials.TexturePaths:=ExtractFilePath(Paramstr(0));
LightMaps.TexturePaths:=ExtractFilePath(Paramstr(0));
Map.MaterialLibrary:=Materials; //Присваиваем GLFreeForm’ у материал
Map.LightmapLibrary:=LightMaps; //Присваиваем GLFreeForm’ у материал (карту теней, LightMap)
Map.LoadFromFile('House.3DS');
with Materials.Materials.FindItemID(2)do begin
TextureScale.scale(15); //Растягиваем текстуру
Material.Texture.TextureMode:=tmDecal;
end;
with Materials.Materials.FindItemID(1)do begin
TextureScale.scale(6); //Растягиваем текстуру
Material.Texture.TextureMode:=tmDecal;
end;
with Materials.Materials.FindItemID(0)do begin
TextureScale.scale(2); //Растягиваем текстуру
Material.Texture.TextureMode:=tmDecal;
end;
Map.Scale.Scale(0.02); //Растягиваем текстуру
END;
Всё! Можете запустить и посмотреть, что получилось!
А готовый пример можно взять отсюда: http://www.glscene.ru/download.php?view.165