3d in Pixilang

Pixilang по русски
Post Reply
User avatar
Al_Rado
Posts: 239
Joined: Tue Dec 04, 2007 2:33 pm
Location: Krasnodar
Contact:

3d in Pixilang

Post by Al_Rado »

Уважаемые господа программисты, кодеры, дизайнеры!
Назрел вопрос о применении 3d в Пиксиленге. Хочется получить нечто похожее на это http://www.wayofthepixel.net/pixelation ... pic=7588.0 Т.е. низкополигональная графика с небольшими текстурами.
Возможность отображения затекстуренных треугольников в пространстве и преобразования присутствуют в языке давно, но как ими пользоваться до сих пор не ясно. На сегодняшний день есть несколько примеров использования 3d в пикси - в одном используется векторная графика, в другом используются воксели, в остальных применяются кубики без текстур либо отображение 2d в пространстве. http://wiki.pixi.su/examples
Итак, вопросы:
1. Каким образом лучше всего хранить данные о 3d объекте, как их снимать (вручную, експортеры из Blender'а или еще какие-либо варианты).
2. Каков механизм развертки текстуры. Описание есть( http://ru.wikibooks.org/wiki/Pixilang ), но не совсем ясно. Нужны примеры.
3. Что делать с искажениями перспективы (чем дальше объект, тем меньше выглядит).
4. Способы анимации.
Если у вас нет готовых решений, поделитесь мыслями, ссылками, идеями.

P.S. Естественно эти вопросы и к создателю языка адресуются :)
ВекторКодПиксельПолигон - ВотЧтоЯЛюблю!
goglus
Posts: 122
Joined: Tue Dec 04, 2007 4:19 pm
Contact:

Re: 3d in Pixilang

Post by goglus »

тк как я 80% всего делаю на кпк хилой мощности добавлю свои 2 копейки
простяцкий 3д редактор из кубиков былоб оч классно - 3д пиксельных уродов делать
что бы простой прикольный и удобный
User avatar
NightRadio
Site Admin
Posts: 3941
Joined: Fri Jan 23, 2004 12:28 am
Location: Ekaterinburg. Russia
Contact:

Re: 3d in Pixilang

Post by NightRadio »

К сожалению, в pixi1 (и 2) реализация полигональной графики весьма примитивная. То есть, задумывалось все масштабно, но в результате получилось немного не то :) Я планирую исправить этот момент в pixi3.

И тем не менее. Что имеем на текущий момент.


1) Самый простой способ - юзать команды pixi_triangle() или triangle(). Они просто рисуют текстурированный или одноцветный треугольник в 2D-пространстве. То есть, все что касается перспективы, удаления невидимых граней - это на ваши плечи :) То бишь, через набор несложных математических выражений - в сети полно инфы. Если что, могу найти и выложить.
В команде pixi_triangle() при помощи параметров tx1, ty1, tx2, ty2, tx3, ty3 задаются текстурные координаты для каждой вершины треугольника: tx1 ty1 - для первой вершины; tx2 ty2 - для второй, и т.д. Текстурные координаты могут быть в диапазоне от 0 до ширины или высоты текстуры. Например: 0x0 - координата левого верхнего угла текстуры; 320x240 - правый нижний угол текстуры размером 320x240.
Если нужно нарисовать два-три треугольника, то этот вариант в самый раз.


2) Способ посложнее - юзать команды triangles3d() и sort_triangles().
Тут принцип такой. Заранее создаются два числовых массива - один для вершин (вертексов), а другой для треугольников, которые строятся на основе этих вершин.

//Структура массива вершин - "vertexes":
X, Y, Z, texture_X, texture_Y, 0, 0, 0, //Первая вершина
X, Y, Z, texture_X, texture_Y, 0, 0, 0, //вторая
... //третья
... // и т.д.
Здесь X, Y, Z - это координаты вершины в 3D-пространстве. Ноль - в центре экрана. Координаты - fixed point, то есть, одна экранная точка равна 256.
texture_X, texture_Y - координаты на текстуре для данной вершины. Они выбираются так же, как в команде pixi_triangle().

//структура массива треугольников - "triangles":
V1, V2, V3, COLOR, TRANSPARENCY, 0, 0, ORDER, //первый треугольник
V1, V2, V3, COLOR, TRANSPARENCY, 0, 0, ORDER, //второй
... // третий
... // и т.д.
Здесь v1, v2, v3 - это номера трех вершин в предыдущем массиве. По этим вершинам и построится треугольник.
COLOR - цвет треугольника.
TRANSPARENCY - прозрачность (от 0 до 256)
ORDER - номер треугольника; треугольники с меньшими номерами рисуются первее; это поле заполнится автоматом при помощи команды sort_triangles().

Этот вариант подходит при рисовании сложных 3d-объектов. Обычно в 3D-форматах данные так и хранятся: набор вершин и набор треугольников на основе этих вершин.
Как рисовать?
Сначала вызываем команду sort_triangles(), которая отсортирует все треугольники по глубине (координата Z), в результате чего далекие треугольники будут рисоваться первее близких - это наиболее простой способ удаления невидимых граней.
Далее вызываем triangles3d (одноцветные) или pixi_triangles3d (текстурированные) и вот уже ваша сцена отобразилась на экране. Но БЕЗ перспективы.
Для различных поворотов и искажений предварительно вызываем команды трансформации (t_xxx).

А теперь, что касается перспективы. Повороты, масштабирование, перемещение, перспектива - это все одна песня. А точнее - матричные преобразования. В пикси я их назвал трансформациями (команды с префиксом t_). Для более глубокого понимания, опять же, в сети есть огромное количество инфы по этому поводу. Конкретно для перспективы нам нужно всего лишь установить правый нижний коэфицент матрицы преобразования в какое-нибудь отличное от нуля число. В пикси это делаем так:
matrix = new_array( 4 * 4 ) //Матрица преобразования 4х4
t_reset //Сбрасываем все трансформации
t_get_matrix( matrix ) //Получаем текущую матрицу
matrix[ 2 * 4 + 3 ] = 4 //Устанавливаем коэфицент перспективы (все числа в матрице - fixed-point)
t_set_matrix( matrix ) //Применяем измененную матрицу
//Теперь можно рисовать в перспективе
Всё как бы более-менее хорошо, за исключением одного момента. Если при включенной перспективе применить трансформацию поворота, то координаты будут искажаться - это потому что не хватает точности fixed-point вычислений в pixilang. Решение проблемы очевидно - использовать числа с плавающей запятой. В pixi3 так и будет.
Кроме того, в пикси3 планирую ввести Z-буфер для более реалистичного удаления невидимых объектов и пересечений.
Перспективной коррекции пока нет. Но теоретически её можно сэмулировать, поделив треугольник на несколько более мелких.

Кстати, в OpenGL тоже матричные преобразования. Почти такие же как в pixi :)

Из blender-а вполне можно наловчиться выгружать модельки. При помощи питоновских скриптов. Там в стандартном комплекте есть скрипт экспорта в RAW формате - это чисто координаты вершин выгружаются в файл. Скрипт довольно простой и на его основе можно собрать что-нибудь посложнее и поуниверсальнее.
Zuf
Posts: 110
Joined: Fri Dec 21, 2007 7:30 pm
Location: Msc
Contact:

Re: 3d in Pixilang

Post by Zuf »

Ну, автор языка все уже рассказал )

Отмечу лишь еще раз, что основная помеха для 3д в пикси - отсутствие чисел с плавающей запятой.
И если в пикси3 будет быстрая "настоящая" математика, то можно будет хоть с нуля 3д движочек сделать, исключительнос встроенными средствами пикси.

Вот вам небольшой тест 3д полигонов с текстурой (примерно это же есть в pixilang benchmark):

Code: Select all


clear(back_color)
rand_seed(8)

// "vertexes":
//X, Y, Z, texture_X, texture_Y, 0, 0, 0,
//X, Y, Z, texture_X, texture_Y, 0, 0, 0,
...
// "triangles":
//V1, V2, V3, COLOR, TRANSPARENCY, 0, 0, ORDER, 
//V1, V2, V3, COLOR, TRANSPARENCY, 0, 0, ORDER,

TRIANGLES=1000/3
VERTEX_COUNT=TRIANGLES*3
vertexes = new_array(8*VERTEX_COUNT)
distance_sq = new_array(TRIANGLES)

TEXTURE_SIZE=256
texture0 = new_pixi( TEXTURE_SIZE, TEXTURE_SIZE, 1 )

y=0
while(y<TEXTURE_SIZE)
{
  x=0
  while(x<TEXTURE_SIZE)
  {
    texture0[TEXTURE_SIZE*y+x] = get_color(x^y, x^y, x^y)
    x+1
  }
  y+1
}

n=0
while(n<VERTEX_COUNT*8)
{
  x = rand-rand
  y = rand-rand
  z = rand-rand
  tx=rand/(256)
  ty=rand/(256)
  vertexes[n+0]=x
  vertexes[n+1]=y
  vertexes[n+2]=z
  vertexes[n+3]=tx
  vertexes[n+4]=ty
  vertexes[n+5]=0
  vertexes[n+6]=0
  vertexes[n+7]=0
  n+8
}

triangles = new_array(8*TRIANGLES)
n=0
i=0
while(n<8*VERTEX_COUNT/3)
{
  triangles[n+0]=i i+1
  triangles[n+1]=i i+1
  triangles[n+2]=i i+1
  triangles[n+3]=rand+rand*256 //#a8948a
  triangles[n+4]=256
  triangles[n+6]=1
  triangles[n+7]=1
  n+8
}

start_timer( 0 )

wx = get_window_xsize()
wy = get_window_ysize()
hwx = wx/2
hwy = wy/2

frame_counter=0
begin_time = get_timer( 0 )
frames_count=0
main:
  transp( 64 )
  clear(#888888)
  //transp( 256 )
  //print("test 3d",0,0, #ff0000)

  //t_reset
  t_rotate_z( t, 0, 0 )
  //t_rotate_x( t * 2, 0, 0 )
  //pixi_triangles3d (vertexes,triangles,texture0,0)
pixi (texture0,0,0,1,0)

  t = get_timer( 0 ) / 32
  c = get_color( csin( t ) + 168, ccos( t ) + 180, csin( t / 2 ) + 198 )

  t_reset
  t_scale( 256, 256, 256 )
  t_rotate_z( t, 0, 0 )
  t_rotate_x( t * 2, 0, 0 )
  t_rotate_y( t * 3, 0, 0 )
  //transp( 128 )

  sort_triangles (vertexes, triangles)
  pixi_triangles3d (vertexes,triangles,texture0,0)
  //triangles3d (vertexes, triangles)
  //pixi_triangles3d (vertexes,triangles,texture0,0)

  t_reset  
  t_scale( frame_counter, frame_counter, frame_counter )
  frame_counter+8
  if frame_counter>256*16 {frame_counter = 0}
  print( "3d bench", -32, 0, #FFFFFF )
  t_reset
  //transp( 256 )

  transp( 256 )
  f = fps
  avgfps= (avgfps+fps*256)/2
  af = avgfps/256
  print( "fps: $f avg fps: $af $avgfps", -hwx, -hwy, #FFFFFF )
  frames_count+1
  frame
go main
А вот еще примерчик-недоделка из-загашников:

Image

Кстати можельку этой рыбки я вручную делал.

Думаю эти картинки, оставшиеся от процесса "сборки" объяснят лучше слов:

Image

Image
User avatar
Al_Rado
Posts: 239
Joined: Tue Dec 04, 2007 2:33 pm
Location: Krasnodar
Contact:

Re: 3d in Pixilang

Post by Al_Rado »

Спасибо за быструю реакцию на потребности пользователей языка! :)
Goglus, простенький редактор кубиков в 3d пространстве можно конечно написать уже сейчас, насколько он будет удобным и прикольным зависит от вложенного в него времени и внимания. Но то, что такой подход не будет эффективным без полноценного использования 3d возможностей пикси - однозначно. Работая на полигональном уровне, можно достичь куда более интересных результатов(не исключая и построения объектов из "объёмных пикселей")
Отличные примеры и разъяснения, теперь можно приступить к практике ;) Конечно надеемся на "улучшенный" подход к расчетам в новых версиях языка, но принципы все равно останутся теже и ждать релиза, для того чтобы начать изучать эту область будет неправильно.
Zuf, отличные вспомогательные материалы! Всё очень наглядно. Пример с рыбкой потрясный )
ВекторКодПиксельПолигон - ВотЧтоЯЛюблю!
goglus
Posts: 122
Joined: Tue Dec 04, 2007 4:19 pm
Contact:

Re: 3d in Pixilang

Post by goglus »

да рыбка отжгла!!!!!!!!!!!!!!!!!
для демок надо конечно юзать полноценные полигоны и тд, а для рисования пиксельного - конструирование из кубиков-пикселей
былоб крайне круто
User avatar
Al_Rado
Posts: 239
Joined: Tue Dec 04, 2007 2:33 pm
Location: Krasnodar
Contact:

Re: 3d in Pixilang

Post by Al_Rado »

Воплотил на пиксиленге идею отсюда http://www.wayofthepixel.net/pixelation ... pic=6977.0
Эдакий 3d-pixelart :)
Моделил в Blender'е, данные о вершинах переносил вручную (copy/paste), использовал текстуру пользователя сайта http://www.wayofthepixel.net по имени Kennethfejer (спасибо ему за классную графику).
http://narod.ru/disk/5205821000/3d_car.zip.html
Правда, при определенных углах странно отображаются некоторые полигоны ( В чем может быть загвоздка?

P.S. Скриншоты выложу чуть позже.
ВекторКодПиксельПолигон - ВотЧтоЯЛюблю!
User avatar
NightRadio
Site Admin
Posts: 3941
Joined: Fri Jan 23, 2004 12:28 am
Location: Ekaterinburg. Russia
Contact:

Re: 3d in Pixilang

Post by NightRadio »

Классно =)
А пропадание полигонов объясняется неправильной сортировкой полигонов в команде sort_triangles(). Более того, бывают случаи, когда правильно отсортировать полигоны вообще невозможно. Поэтому в Pixilang3 будет другой метод взамен сортировке - Z-buffer.
Zuf
Posts: 110
Joined: Fri Dec 21, 2007 7:30 pm
Location: Msc
Contact:

Re: 3d in Pixilang

Post by Zuf »

Ждем ремейка the need for speed на пикси ;)
User avatar
Al_Rado
Posts: 239
Joined: Tue Dec 04, 2007 2:33 pm
Location: Krasnodar
Contact:

Re: 3d in Pixilang

Post by Al_Rado »

Спасибо :)
Некоторые подробности: из-за особенностей развертки текстуры пришлось сделать 30 вершин вместо 12, т.к. каждая вершина может иметь только одно место на текстуре.
Если делать текстуру только для одной модельки, развертку можно сделать пооптимальнее. Координаты для вершин брал из окна развертки.
Пробовал экспортировать данные о вершинах через RAW - координаты вершин выводятся, только их потом все равно перетягивать вручную + исправлять (т.к. они там с дробной частью), опять же данные для координат текстур и сами треугольники все равно вручную делать.

Да, Z-buffer просто необходим. А поддержка альфа-каналов в текстурах для 3d предполагается?
Attachments
Скриншот из Блендера
Скриншот из Блендера
скрин_в_блене.gif (30.47 KiB) Viewed 9252 times
Номера вершин
Номера вершин
скрин.jpg (30.86 KiB) Viewed 9253 times
ВекторКодПиксельПолигон - ВотЧтоЯЛюблю!
User avatar
NightRadio
Site Admin
Posts: 3941
Joined: Fri Jan 23, 2004 12:28 am
Location: Ekaterinburg. Russia
Contact:

Re: 3d in Pixilang

Post by NightRadio »

Альфа-канал - обязательно. Хотя, он и в текущем пикси есть :)
Просто сейчас, как мне кажется, не очень рационально используется память для графики. Например, при 32-битном цвете с альфой на один пиксель отдается 8 (!) байт вместо 4, так как альфа это тоже 32-битная картинка. В пикси3 это постараюсь исправить.
User avatar
Al_Rado
Posts: 239
Joined: Tue Dec 04, 2007 2:33 pm
Location: Krasnodar
Contact:

Re: 3d in Pixilang

Post by Al_Rado »

Да, действительно, альфа канал уже работает как и с обычными 2d картинками )
Т.е. в новом пикси не будет pixi_alpha (image,new_alpha), а останется только pixi_transp (image,transp,transp_color) ? Или дело во "внутренних" преобразованиях?
ВекторКодПиксельПолигон - ВотЧтоЯЛюблю!
User avatar
NightRadio
Site Admin
Posts: 3941
Joined: Fri Jan 23, 2004 12:28 am
Location: Ekaterinburg. Russia
Contact:

Re: 3d in Pixilang

Post by NightRadio »

Затрудняюсь пока ответить =) Сейчас как раз это придумываю
Post Reply