Processing:Библиотеки/Processing for Android/Руководства/Введение в VR
Содержание | Среда разработки Processing | Справочник языка Processing | Библиотеки | Примеры | Режимы программирования |
Введение в VR[1]
В этом руководстве описываются основы для написания VR-приложений при помощи Google VR и Processing.
Google VR
Платформа Google VR позволяет сделать ваш смартфон быстрой отправной точкой в виртуальную реальность. Режим программирования Android в PDE поддерживает платформы Google Cardboard и Google Daydream, поэтому с его помощью можно писать 3D-скетчи, которые можно будет запустить на телефоне как Cardboard-приложения в стерео-режиме и с возможностью отслеживать движения головы. Если вы ранее не делали 3D-скетчи в Processing, то советуем сначала пройти это руководство.
Требования
Чтобы использовать VR-приложения при помощи Cardboard, вам понадобится Cardboard-совместимый телефон с Android 4.1 или выше, гироскоп для отслеживания движений головы и Cardboard-устройство для просмотра виртуальной реальности. Если у вас такого устройства нет, вы все еще сможете просматривать скетч в моно-режиме (подробнее о нем будет рассказано ниже). Для Daydream понадобятся шлем View и Daydream-совместимый телефон.
Если вы используете режим программирования Android версии 4.0-beta3 или новее, все дополнительные пакеты, необходимые для разработки VR-приложений, в этой версии уже есть, поэтому никакой дополнительной возни в этом случае не потребуется. Если вы используете более старую версию режима программирования Android, тогда вам нужно будет отдельно установить библиотеку «processing-cardboard». Она оснащена специальными стерео- и моно-визуализаторами, работающими совместно с датчиками телефона для автоматического обновления камеры Processing. В меню Contribution Manager этой библиотеки нет, поэтому ее нужно будет установить вручную. Для этого сначала установите последнюю версию библиотеки в виде ZIP-архива отсюда, распакуйте ее и скопируйте в папку «/libraries/cardboard» в вашей папке скетчей (т.е. в скетчбуке). Затем перезапустите Processing.
С чего начать
Чтобы скетч создавался как VR-приложение, в PDE нужно выбрать опцию Android > VR:
В базовый скетч для VR необходимо импортировать библиотеку VR и визуализатор STEREO:
import processing.vr.*;
void setup() {
fullScreen(STEREO);
}
void draw() {
}
Этот код создаст на вашем телефоне пустую стерео-картинку:
Стерео-визуализатор рендерит каждый кадр дважды – по одному для каждого глаза. Для проверки того, какой именно глаз рендерится в текущем вызове draw(), воспользуйтесь в VR-визуализаторе переменной eyeType:
import processing.vr.*;
void setup() {
fullScreen(STEREO);
}
void draw() {
PGraphicsVR pvr = (PGraphicsVR)g;
if (pvr.eyeType == PVR.LEFT) {
background(200, 50, 50);
} else if (pvr.eyeType == PVR.RIGHT) {
background(50, 50, 200);
} else if (pvr.eyeType == PVR.MONOCULAR) {
background(50, 200, 50);
}
}
Вы, возможно, заметили, что значением eyeType также может быть MONOSCOPIC – на тот случай, если вы вместо визуализатора STEREO используете MONO. Моно-визуализатор рисует кадр только один раз, но камера по-прежнему реагирует на движения телефона.
В добавлении в сцену 3D-объектов нет ничего необычного – просто используйте те же функции для рисования 3D-примитивов и фигур, что и при использовании визуализатора P3D. Вы также можете добавить текстуры, источники света и шейдерные эффекты – например, как в скетче ниже (полный код доступен по этой ссылке):
import processing.vr.*;
PShader toon;
boolean shaderEnabled = true;
void setup() {
fullScreen(STEREO);
noStroke();
fill(204);
toon = loadShader("ToonFrag.glsl", "ToonVert.glsl");
}
void draw() {
if (shaderEnabled == true) shader(toon);
translate(width/2, height/2);
background(80);
directionalLight(204, 204, 204, 1, 1, -1);
sphere(150);
}
void mousePressed() {
if (shaderEnabled) {
shaderEnabled = false;
resetShader();
} else {
shaderEnabled = true;
}
}
Обратите внимание на функцию translate(width/2, height/2) – она необходима для того, чтобы правильно отцентрировать сцену перед глазами пользователя. Это необходимо, потому что Processing по умолчанию помещает начало координат в левый верхний угол экрана, что удобно для 2D-рисования, но для VR – нет. Результат будет выглядеть примерно так:
Создание более сложной сцены
В этом примере мы создадим 3D-сцену, в которой будет чуть больше объектов. Давайте начнем с создания 2D-решетки, которая послужит нам ориентиром для расстановки объектов.
Поскольку производительность очень важна в VR, чтобы частота кадров оставалась как можно выше, а пользователь не испытывал «морской болезни», мы можем положиться на объекты PShape для хранения статичной геометрии и таким образом избежать повторного рендеринга этих объектов в новых кадрах.
import processing.vr.*;
PShape grid;
void setup() {
fullScreen(STEREO);
grid = createShape();
grid.beginShape(LINES);
grid.stroke(255);
for (int x = -10000; x < +10000; x += 250) {
grid.vertex(x, +1000, +10000);
grid.vertex(x, +1000, -10000);
}
for (int z = -10000; z < +10000; z += 250) {
grid.vertex(+10000, +1000, z);
grid.vertex(-10000, +1000, z);
}
grid.endShape();
}
void draw() {
background(0);
translate(width/2, height/2);
shape(grid);
}
Обратите внимание, что значения Y у вершин объекта «grid» равны «+1000». Дело в том, что в Processing значения оси Y перевернуты вверх ногами (если сравнивать с традиционной системой координат), поэтому объекты, расположенные в виртуальной реальности ниже нашей зрительной оси, должны иметь положительные значения оси Y.
Теперь можно добавить немного объектов! Чтобы оптимизировать производительность, мы можем сгруппировать несколько 3D-фигур внутри одной группы объектов PShape, что быстрее, чем если бы мы обрабатывали каждый объект по отдельности. Получится примерно так:
import processing.vr.*;
PShape grid;
PShape cubes;
void setup() {
fullScreen(STEREO);
grid = createShape();
grid.beginShape(LINES);
grid.stroke(255);
for (int x = -10000; x < +10000; x += 250) {
grid.vertex(x, +1000, +10000);
grid.vertex(x, +1000, -10000);
}
for (int z = -10000; z < +10000; z += 250) {
grid.vertex(+10000, +1000, z);
grid.vertex(-10000, +1000, z);
}
grid.endShape();
cubes = createShape(GROUP);
for (int i = 0; i < 100; i++) {
float x = random(-1000, +1000);
float y = random(-1000, +1000);
float z = random(-1000, +1000);
float r = random(50, 150);
PShape cube = createShape(BOX, r, r, r);
cube.setStroke(false);
cube.setFill(color(180));
cube.translate(x, y, z);
cubes.addChild(cube);
}
}
void draw() {
background(0);
lights();
translate(width/2, height/2);
shape(cubes);
shape(grid);
}
Итоговый результат должен выглядеть примерно так (зависит от точки обзора):
См.также
Внешние ссылки
Примеры на Processing | |
---|---|
Основы |
|
Продвинутые графические эффекты |
|
Примеры из сторонних библиотек |