[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 3 из 4
  • «
  • 1
  • 2
  • 3
  • 4
  • »
TextureStage и Terrain
serg-kkzДата: Четверг, 21.08.2014, 12:26 | Сообщение # 31
Генерал-полковник
Группа: Модераторы
Сообщений: 803
Награды: 3
Репутация: 18
Статус: Offline
Цитата ninth ()
Да с PIL вполне можно сгенерить с учётом вертикальности стенок. 

smile - как?

Я только слой скал буду генерировать с помощью коллизий. Увы на ум больше ни чего не приходить, кроме как клацать по поверхности и определять ориентацию полигона. Думаю наработка в дальнейшем пригодиться для генерации флоры. Только в данный момент задумался над тем как определить "крутость полигона"  sad вроде нашел закономерность в сумме или разнице X и Y у  направления вектора нормали. В дальнейшем думаю таким же способом освещение сделать, путем обстрела лучем из позиции солнца по террейну.


ООП  -  
 
ninthДата: Четверг, 21.08.2014, 17:06 | Сообщение # 32
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
А поверхность у тебя геомип на основе карты высот или моделька?

з.ы. А вертикальность можно определить скалярным произведением (оно же dotproduct) нормали на up-вектор.
Vec3(0,1,0).dot(myNormal)
 
serg-kkzДата: Четверг, 21.08.2014, 17:20 | Сообщение # 33
Генерал-полковник
Группа: Модераторы
Сообщений: 803
Награды: 3
Репутация: 18
Статус: Offline
На основе карты высот, по ней три слоя песок, земля, трава. Скалы на основе коллизий, еще в разработке, но одна проблема ввела меня в ступор. Не получается без добавления в рендер декектить лучем поверхность.

Пример PIL.

Код
# -*- coding: utf-8 -*-
#!/usr/bin/python
from PIL import Image
import sys

relief = Image.open("data/default.png") # Карта высот
mask = Image.new("RGBA", (512,512), (0,0,0,0)) # Создаем новый файл изображения, с 4-мя каналами.
rgba = mask.split() # Разбиваем на каналы

red = rgba[0] # Переменная для красного канала
green = rgba[1] # Переменная для зеленого канала   
blue = rgba[2] # Переменная для синего канала
alfa = rgba[3] # Переменная для альфа канала

for y in range(512):
    for x in range(512):
          # Определяем уровень песка от 0 до 75
          if 0 <= relief.getpixel((x, y)) < 75:
              red.putpixel((x, y), 255 )
          # Определяем уровень травы от 75 до 120
          if 74 < relief.getpixel((x, y)) < 80:
              green.putpixel((x, y), 255 )
          # Определяем уровень скал от 75 до 170
          if 79 < relief.getpixel((x, y)) < 140:
              blue.putpixel((x, y), 255 )
          # Определяем уровень снега от 170 до 255
          if 139 < relief.getpixel((x, y)) < 255:
              alfa.putpixel((x, y), 255 )

im = Image.merge("RGBA", (red,green,blue,alfa)) # Собираем слои
im.save("data/default_d.png") # И сохраняем





ООП  -  

Сообщение отредактировал serg-kkz - Четверг, 21.08.2014, 19:07
 
serg-kkzДата: Четверг, 21.08.2014, 17:47 | Сообщение # 34
Генерал-полковник
Группа: Модераторы
Сообщений: 803
Награды: 3
Репутация: 18
Статус: Offline
В дальнейшем думаю полность все рисовать с помощью коллизий, так можно будет полностью обработать всю карту. Так как я планирую сделать открытый мир, состоящий из тайлов мешей.

ООП  -  
 
ninthДата: Пятница, 22.08.2014, 08:09 | Сообщение # 35
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
Для геомип есть вариант получать нормаль без коллизий myGeoMipTerrain.getNormal(x,y) x,y - координаты пикселей карты высот
 
serg-kkzДата: Вторник, 26.08.2014, 02:32 | Сообщение # 36
Генерал-полковник
Группа: Модераторы
Сообщений: 803
Награды: 3
Репутация: 18
Статус: Offline
Цитата ninth ()
Для геомип есть вариант получать нормаль без коллизий myGeoMipTerrain.getNormal(x,y) x,y - координаты пикселей карты высот


О, это намного быстрее чем шарить лучем.



Правда ждал не того. Как то странно все это работает. Скалярное произведение местами выводит 0.0 в массиве. Хотя этого быть не должно теоретически.
Прикрепления: 0974636.png (1.32 Mb)


ООП  -  
 
ninthДата: Вторник, 26.08.2014, 08:57 | Сообщение # 37
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
Скрин ничё так. А в дебаг вывести "неправильные" вектора на которых 0 получается?
 
serg-kkzДата: Вторник, 26.08.2014, 10:33 | Сообщение # 38
Генерал-полковник
Группа: Модераторы
Сообщений: 803
Награды: 3
Репутация: 18
Статус: Offline
Цитата ninth ()
Скрин ничё так. А в дебаг вывести "неправильные" вектора на которых 0 получается?


Я не соображу как это сделать? Могу только визуально проследить.

Да скрин хорош, но если в целом посмотреть, то получается как будь-то проталины от солнца, видно относительно одной оси определяется наклонность

И на скрине видно что некоторые точки больше горизонту ближе чем к вертикали.

Прикрепления: 8394592.png (1.88 Mb)


ООП  -  
 
ninthДата: Вторник, 26.08.2014, 10:51 | Сообщение # 39
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
Ммм... результат можно записать в чёрно-белую текстуру чтобы визуально определить. И знаешь что, проверь-ка у тебя вектора нормализуются перед скалярным произведением? Оно корректно работает только на нормализованных векторах.
 
serg-kkzДата: Вторник, 26.08.2014, 10:56 | Сообщение # 40
Генерал-полковник
Группа: Модераторы
Сообщений: 803
Награды: 3
Репутация: 18
Статус: Offline
Код
    def scan1(self, task):
         for x in range(512):
             for y in range(512):
                 n = self.terrain.getNormal(x,y)
                 print Vec3(0,1,0).dot(n)
                 if 0.001 < Vec3(0,1,0).dot(n) < 0.01:  
                     self.red.putpixel((x, y), 0 )
                     self.green.putpixel((x, y), 0 )
                     self.blue.putpixel((x, y), 0 )
                     self.alfa.putpixel((x, y), 255 )


Таким макаром это работает, и вот что выдает.

Прикрепления: 4125076.png (52.2 Kb)


ООП  -  
 
ninthДата: Вторник, 26.08.2014, 11:25 | Сообщение # 41
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
Попробуй так
Код
n = self.terrain.getNormal(x,y)
n.normalize()
dot = abs(Vec3(0,1,0).dot(n))


И ещё, это всё с учётом, что у тебя Y - вертикальная ось. Если вертикаль - Z, то вектор-то должен быть Vec3(0,0,1). Естественно, всё в координатах террайна. Кстати, террайн по вертикальной оси масштабирован перед проверкой нормали?
 
serg-kkzДата: Вторник, 26.08.2014, 11:52 | Сообщение # 42
Генерал-полковник
Группа: Модераторы
Сообщений: 803
Награды: 3
Репутация: 18
Статус: Offline
Цитата ninth ()
Кстати, террайн по вертикальной оси масштабирован перед проверкой нормали?


Код
        self.terrain = GeoMipTerrain("Terrain")
         self.terrain.setHeightfield(Filename('data/land01-map.png'))
         self.terrain.setBlockSize(32)
         self.terrain.setFactor(100)
         #self.terrain.setFocalPoint(base.camera)
         self.terrain.getRoot().reparentTo(render)
         self.terrain.getRoot().setPos(0, 0, -500)
         self.terrain.getRoot().setSz(200)
         self.terrain.generate()


Что-то мне алгебра надоела, вообщем как ноду задать положение пологона, вращение меня интересует. Сделаю по тупому, расположу нод, прицеплю два узла друг над другом(вертикально), и по их разнице в x и y буду считать. Логика если координаты ближе к совпадению, то значит горизонт, чем больше разница, вертикаль.


ООП  -  
 
ninthДата: Вторник, 26.08.2014, 13:10 | Сообщение # 43
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
Можешь мне целиком скинуть с ресурсами? Гляну.
 
serg-kkzДата: Вторник, 26.08.2014, 13:21 | Сообщение # 44
Генерал-полковник
Группа: Модераторы
Сообщений: 803
Награды: 3
Репутация: 18
Статус: Offline
Вот, с нормалью разобрался. Думаю нужно будет применить какие нибудь фильтры, чтоб убрать полосы.

Запускай генератор, потом просмотр.

Прикрепления: 9420760.png (1.55 Mb) · GenTerr.7z (1.45 Mb)


ООП  -  

Сообщение отредактировал serg-kkz - Вторник, 26.08.2014, 13:36
 
ninthДата: Вторник, 26.08.2014, 16:07 | Сообщение # 45
Admin
Группа: Администраторы
Сообщений: 1582
Награды: 5
Репутация: 46
Статус: Offline
Альтернативная версия. Здесь полосы будут чуть сглажены.
Изначально маска создаётся с заполненным синим каналом (трава)
Код
self.mask = Image.new("RGBA", (512,512), (0,0,255,0)) # Создаем новый файл изображения, с 4-мя каналами.


генерация камня
Код
    def scan1(self, task):
         for x in range(512):
             for y in range(512):
                 n = self.terrain.getNormal(x,y)
                 n = Vec3(n.x*150, n.y*150, n.z) # 150 - масштаб террайна по высоте
                 n.normalize()
                 dot = abs(Vec3(0,0,1).dot(n))
                 r,g,b,a = self.mask.getpixel((x,y))
                 a = 255 - min(255, int(255 * dot ** 4 * 1.5)) # последние два коэффициента влияют на вертикальность и яркость прорисовки камней
                 r = max(0, r-a)
                 g = max(0, g-a)
                 b = max(0, b-a)
                 self.mask.putpixel((x, y), (r,g,b,a))
         self.mask.save("data/default_d.png")
         sys.exit()
 
  • Страница 3 из 4
  • «
  • 1
  • 2
  • 3
  • 4
  • »
Поиск: