Буковое дерево (использованное на этой и последующих иллюстрациях) - это высокодетальная модель (свыше 30,000 граней), созданная Yorik van Havre с помощью свободного пакета моделирования растений ngPlant. (Смотри его вебсайт для большего количества отличных примеров: http://yorik.uncreated.net/ greenhouse.html). Далее первый набор изображений показывает буковое дерево спереди и результирующий рендер передней грани билборда слева. (немного темнее из-за premultiplication).
Следующий набор скриншотов показывает то же буковое дерево, отрендеренное справа вместе с рендером правой грани билборда слева. Как может быть заметно, исполнение конечно, не идеально с этой точки зрения, но это крупный план, а разумный трехмерный аспект сохраняется.
Чтобы показать, как устроена конструкция билбордов, следующий скриншот показывает две грани с наложенными отрендеренными изображениями. Прозрачность умышленно уменьшена, чтобы было видно отдельные грани.
Нашей первой проблемой будут некоторые ранее используемые функции, которые мы писали для презентации модели с несколькими видами. Эти функции находятся в текстовом буфере с именем combine.py, и мы не сохраняли его во внешний файл. Мы создадим наш скрипт cardboard.py как новый текстовый буфер в том же .blend файле, где и combine.py, и хотим ссылаться на последний так же, как на внешний модуль. Блендер позволяет это делать, так как он ищет модуль в текущих текстовых буферах, если он не может найти внешний файл.
Поскольку внутренние текстовые буферы не имеют информации о том, когда они последний раз изменялись, мы должны убедиться, что загружена самая последняя версия. Об этом позаботится функция reload(). Если мы её не выполним, Блендер не сможет обнаружить возможных изменений в combine.py, что могло бы провести нас к использованию его более старой скомпилированной версии:
import combine
reload(combine)
Мы не будем использовать заново функцию render() из combine.py, поскольку сейчас у нас другие требования для рендеренных изображений, которые мы наложим на билборды. Как уже объяснялось, мы должны убедиться, что мы не получим никаких светлых краёв в местах с частичной прозрачностью, так что мы заранее включаем premultiply в альфа-канале (выделено). Мы восстанавливаем контекст рендера в 'рендер неба' (rendering the sky) обратно до возврата из этой функции, поскольку легко забыть установить его обратно вручную, и Вы можете потратить время на удивление, куда подевалось ваше небо:
def render(camera):
cam = Object.Get(camera)
scn = Scene.GetCurrent()
scn.setCurrentCamera(cam)
context = scn.getRenderingContext()
frame = context.currentFrame()
context.endFrame(frame)
context.startFrame(frame)
context.displayMode=0
context.enablePremultiply()
context.renderAnim()
filename= context.getFrameFilename()
camera = os.path.join(os.path.dirname(filename),camera)
try:
os.remove(camera) # удаление, в противном случае
# переименование
# потерпит неудачу в windows
except:
pass
os.rename(filename,camera)
context.enableSky()
return camera
Каждое отрендеренное изображение должно быть преобразовано в подходящий материал, чтобы наложить его на квадрат с UV-отображением. Функция imagemat() будет делать это просто; она принимает объект Блендера Image в качестве аргумента и возвращает объект Материала. Этот материал будет сделан полностью прозрачным (выделено), но эта прозрачность и цвет модифицируются текстурой, которую мы назначаем в первый текстурный канал (вторая выделенная строка). Тип текстур установлен в Image и, поскольку мы визуализировали эти изображения с premultiplied альфа-каналом, мы используем метод setImageFlags(), чтобы указать, что мы хотим использовать этот альфа-канал, и устанавливаем атрибут premul изображения в Истину:
def imagemat(image):