В предыдущем уроке мы запустили самолётик, который летает по некоторой (пусть и примитивной) траектории. Это хороший повод добавить в сцену фон с текстурой неба, ведь любой уважающий себя самолёт должен летать в небе.
Фон в DDD – это почти такой же 3D-объект (или даже несколько объектов), как мы встречали ранее. Основные особенности этого объекта, отличающие его от «обычных» объектов:
Меш объекта фона обычно должен закрывать пространство целиком. Как правило (и в этом уроке именно такой случай), это некая сфера с наложенной на неё текстурой, а камера располагается в центре этой сферы.
Нормали этого объекта должны быть направлены вовнутрь, т. к. мы будем его наблюдать изнутри.
Обычно размеры этого объекта больше всей сцены, но фактически это необязательно, достаточно чтобы он попадал в «объём видимости» (см. ниже). При отрисовке фона выключен тест глубины, поэтому любой объект, выведенный на экран позже фона обычным способом (не как фон), будет отображён перед ним, невзирая на соотношение расстояний от этих объектов до камеры.
Впрочем, никто не запрещает вывести в качестве фона несколько обычных объектов, таким образом можно отобразить «далёкие» объекты, к которым камера не сможет приблизиться. Но надо иметь ввиду, что так как тест глубины отключен, а порядок вывода объектов на экран случаен, то лучше, чтобы различные фоновые объекты не загораживали друг друга.
Ладно, хватит болтовни, приступим:
Перейдите в конец функции сцена и загрузите объект неба:
auto объект_небо = менеджер.получить_объект("небо сфера");
В этом пункте будет основное отличие от «обычных» объектов. Создаём объект Место через менеджер.место_фона а не через менеджер.начальное_место:
auto место_неба = менеджер.место_фона.создать_ребёнка("Место неба", Вектор3.НОЛЬ, Кватернион.НОЛЬ);
Собственно на этом почти всё. Осталось только присоединить загруженный объект к Месту:
место_неба.присоединить_объект(объект_небо);
После компиляции и запуска программа должна отобразить что-то подобное:
На этом практическая часть урока закончена.
Осталось только пояснить про упомянутый ранее «объём видимости». У объекта Камера есть два числовых свойства: ближнее_отсечение и дальнее_отсечение. Они определяют так называемый «объём видимости», все объекты (или их части) которые находятся ближе ближнего отсечения или дальше дальнего отсечения, не выводятся на экран. По-умолчанию значения этих свойств такие:
ближнее_отсечение = 2.0f; дальнее_отсечение = 100.0f;
Эти значения достаточно разумны, если мы отображаем объекты с линейными размерами от 0.1 и до примерно 80 (в DDD, конечно же, нет никаких метров и прочих единиц измерения, единицы расстояния – это просто «условные единицы», хотя для себя вы можете их считать «условными метрами», если вам так удобнее). При необходимости можно изменить значения расстояний до плоскостей отсечений, но будьте осторожны: при сильном увеличении величины соотношения дальнее_отсечение/ближнее_отсечение на краях экрана будут проявляться сильные искажения проецирования. Вот как выглядит экран 11-го урока, если туда добавить такую пару строк (по-умолчанию камера расположена на позиции Вектор3(0,0,5), тут мы её немного приближаем к объектам):
менеджер.камера.ближнее_отсечение = 1.0f; менеджер.место_камеры.задать_позицию(Вектор3(0,0,3));
Собственно, и раньше, если приглядеться, мячики не были идеально круглыми, но сейчас они настолько вытянуты около углов экрана, что изображение не выдерживает никакой критики.