текстурирование "кубика"
|
|
akzy | Дата: Пятница, 03.05.2013, 01:06 | Сообщение # 16 |
Лейтенант
Группа: Пользователи
Сообщений: 55
Награды: 0
Репутация: 3
Статус: Offline
| Да,сегодня к обеду всё же разобрался с геометрией и её толстостями... насчёт всё - в одном...сейчас работаю над этим на текущий момент сделал генератор (с удалением ненужных граней) с текстурами MC
Очередные пару вопросов: - свет странно проходит сквозь кубики... завтра попробую сам найти, но... может скажете,как поправить? а то с ума сойду) - и ещё- можно ли полученные ноды подключить к bullet?:) (лезу в дебри...)
upd - почти сделал чтоб читал текстуры из 1 файла (работает, но надо всё проверить)
Сообщение отредактировал akzy - Пятница, 03.05.2013, 20:27 |
|
| |
ninth | Дата: Пятница, 03.05.2013, 14:00 | Сообщение # 17 |
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
| С освещением здесь не всё так просто. setLight использует стандартный OpenGL/DirectX источник света, либо имитирует его в автошейдерах. Эти источники света не учитывают затенение от других полигонов - просто освешают поверхность в зависимости от направления на источник и нормали. Майнкрафт же использует свою собственную технику освещения, т.к. на ней завязаны многие игровые механики. Считается уровень освещения каждого блока в зависимости от источников и препятствий, а после при отрисовке в шейдере учитывается этот параметр. К сожалению я не видел нигде подробного описания майнкрафтовской реализации этого дела. Есть только статья на английском в которой человек пытался воспроизвести аналогичный рендеринг http://codeflow.org/entries....clusion
Вообще освещение, выходящее за рамки стандартного минимального - очень обширная тема. Разных техник, хитростей и уловок тут существует более чем дофига и красивое освещение по праву является гордостью любого разработчика )
По второму вопросу, я так понимаю тебе нужен BulletTriangleMesh Код from panda3d.bullet import BulletTriangleMeshShape mesh = BulletTriangleMesh() mesh.addGeom(geom)
|
|
| |
akzy | Дата: Пятница, 03.05.2013, 20:27 | Сообщение # 18 |
Лейтенант
Группа: Пользователи
Сообщений: 55
Награды: 0
Репутация: 3
Статус: Offline
| проанализировал немного свет в МС...там в основном процедурно всё просчитывается как я понял...практически как и в моём случае, обратная сторона кубика тоже освещается... Как думаеш,чтобы удалить 1 кубик из ноды - можно ли сделать удаление вертекса и пересчитать соседей, или такой фишки нет?Сделал, чтобы всё читалось из 1 файла текстур... но теперь задумался- а надо ли делать геомы для каждой текстуры теперь? часть кода Код def loadtextures(self): for i in xrange(self.texturescount): gvd =GeomVertexData('name', GeomVertexFormat.getV3c4t2(),Geom.UHStatic) self.geom =Geom(gvd) prim =GeomTriangles(Geom.UHDynamic) vertex =GeomVertexWriter(gvd, 'vertex') texcoord =GeomVertexWriter(gvd, 'texcoord') color =GeomVertexWriter(gvd, 'color') self.wr =GeomVertexRewriter(gvd, 'color') tex = loader.loadTexture('_data/_img/cu%i.png' % (i)) #tex.setMagfilter(Texture.FTLinearMipmapLinear) #tex.setMinfilter(Texture.FTLinearMipmapLinear) self.geoms.append({ 'geom':self.geom, 'prim'; prim, 'vertex':vertex, 'color':color, 'texcoord':texcoord, 'index':0, 'gvd':gvd, 'texture':tex};) def resetcolor(self,id,color): # нужно попасть с нужный квадрат ещё! #self.geoms[id]['color'].setData4f(color, color, color, 1.0) #self.geoms[id]['color'].setData4f(color, color, color, 1.0) #self.geoms[id]['color'].setData4f(color, color, color, 1.0) #self.geoms[id]['color'].setData4f(color, color, color, 1.0) код закомментил пока что, так как пока не догоню- как выбрать нужный "элемент"... то есть перейти к индексу geoms[1] ['index'] =index и ему уже сделать setData3f ?
пришла мысль, что текстуры же имеют ограничение, и если надо много картинок, то как раз нужно будет несколько геом.. я правильно мыслю?
Сообщение отредактировал akzy - Суббота, 04.05.2013, 19:34 |
|
| |
ninth | Дата: Понедельник, 06.05.2013, 10:09 | Сообщение # 19 |
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
| Насчёт удаления вершины - не получится - построенная моделька отправляется в память видеокарты, поэтому чтобы удалить вершину придётся построить новую модель без этой вершины и заменить ей старую. В майнкрафте сделано так же, т.е. при изменении перестраивается весь кусок чанка (напомню, что они разбиты на несколько кусков)
Геомы с одной текстурой можно объединить в один.
Цитата (akzy) если надо много картинок, то как раз нужно будет несколько геом.. я правильно мыслю? Да, именно так.
|
|
| |
crashtua | Дата: Пятница, 10.05.2013, 18:19 | Сообщение # 20 |
Рядовой
Группа: Пользователи
Сообщений: 2
Награды: 0
Репутация: 0
Статус: Offline
| Пишите клон майнкрафта? Тоже хочу свой написать, только на с++ и вот думаю, что лучше для рендера взять, Огра или Панду. Про текстуры - как говорилось выше - делать атлас(одна большая текстура, в которой сеткой расположены нужные нам текстуры куба). Далее: если Вы действительно делаете клон майнкрафта, то любой, даже очень очень быстрый и дорогой компьютер с использованием вашего подхода(каждый куб отдельным мешем) загнется на 500 кубиков . Тут надо весь мир делить на части(чанки в майнкрафте) допустим на зоны 64х64х64 кубика, и генерировать для каждой зоны 1 меш. Допустим у вас 3 куба идут подряд - грани, которыми они соприкасаются, не должны быть отрисованы. Про освещение - сейчас пробую делать следующее: сцену графически освещаю обычными источниками света, а уровень освещения блока считаю отдельно, в зависимости от параметров источника света. Только вот расчитать уровень освещенности более ли менее правильно как то сложновато
|
|
| |
ninth | Дата: Пятница, 10.05.2013, 20:04 | Сообщение # 21 |
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
| Насчёт чанков тут в процессе обсуждалось ) Я бы не сказал, что в майнкрафте прям совсем правильно освещение считается. Там тоже довольно приближённая модель. Насчёт выбора огр/панда на сях - думаю дело вкуса и знания движка. Преимущество панды, имхо именно в питоне ну и может быть в уже привязанных библиотеках (звук, физика, гуи). Огр вроде как может дать более красивую картинку, но здесь я склонен выразить сомнение, ибо графический апи - один, а значит и возможности должны быть сходными.
|
|
| |
crashtua | Дата: Пятница, 10.05.2013, 21:50 | Сообщение # 22 |
Рядовой
Группа: Пользователи
Сообщений: 2
Награды: 0
Репутация: 0
Статус: Offline
| Ну, освещение я считаю так - за начало отсчета беру куб в котором содержится источник света, все блоки вокруг начального будут иметь освещенность на 0.5 меньше и так далее. Если брать по прямой, то освещенность совпадает, но если по диагонали, то не очень, освещенность распространяется дальше чем свет от источника, пока что не учитываю что диагональ корень с двух. Надо что то мудрить с сферою.
|
|
| |
akzy | Дата: Пятница, 10.05.2013, 23:02 | Сообщение # 23 |
Лейтенант
Группа: Пользователи
Сообщений: 55
Награды: 0
Репутация: 3
Статус: Offline
| тестирую всё на своём компе, оптимизация как я писал выше, есть. для 16 000 000 с заполнением ~70% у меня около 20fps, но это я проверял, будет ли нормально у меня рендерится столько всего. Сейчас грабли с выбором объекта, с пересчётом блоков, про тени и свет я молчу) Вот может подскажите в приложении скрин. луч определяет ближайший куб, его координаты, но КАК вытащить эти координаты? кусок кода: Код def __init__(self):
k=G6() k.rand() k.close() self.cubeRoot= render.attachNewNode(k.node) #base.cam.setPos(0,-50,15) #base.cam.lookAt(15, 15, 0)
# Обработчик столкновений "луча" мышки и объектов ______________________ self.picker = CollisionTraverser() # создаём traverser self.pq = CollisionHandlerQueue() # создаём обработчик столкновений self.pickerNode = CollisionNode('mouseRay') # создаём луч столкновений
self.pickerNP = camera.attachNewNode(self.pickerNode) #
self.pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask()) self.pickerRay = CollisionRay() #собственно создаётся луч self.pickerNode.addSolid(self.pickerRay)
self.picker.addCollider(self.pickerNP, self.pq)
#self.picker.showCollisions(render)
self.mouseTask = taskMgr.add(self.mouseTask, 'mouseTask')
#self.debugConsole() #self.updateDebugConsoleTask=taskMgr.add(self.updateDebugConsoleTask,'updateDebugConsoleTask') self.showmenu() #self.cubeRoot = render.attachNewNode("cubeRoot")
def mouseTask(self,task): if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() self.pickerRay.setFromLens(base.camNode, mpos.getX(),mpos.getY()) #self.menutext[4]=str(base.camNode) self.picker.traverse(self.cubeRoot) #self.menutext[5]=str(self.pq) if self.pq.getNumEntries() > 0: self.menutext[2]=str(self.pq.getNumEntries())+" entries" self.pq.sortEntries() entry = self.pq.getEntry(0) self.menutext[3]=str(entry) #(x,y,z) = entry.getIntoNodePath().getParent().getPos() #self.menutext[4]=str(entry.getIntoNodePath().getParent().getPos()) #self.menutext[0]=str(mpos.getX()) # self.menutext[1]=str(mpos.getY())
return task.cont Добавлено (10.05.2013, 23:02) --------------------------------------------- я (мы в общем, но остальные пока основы изучают) пишем не очередной клон, а кое что поинтереснее. А насчёт того,чтобы написать ОДНОМУ чтото более менее симпатичное - это очень долго или нереально. Поэтому лучше найти единомышленников.
|
|
| |
ninth | Дата: Суббота, 11.05.2013, 04:42 | Сообщение # 24 |
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
| А, ну в майнкрафте освещение всё-же сложнее - учитывается затенение от соседних блоков.
По координатам я в соседней теме ответил.
|
|
| |