Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   forum.boolean.name > Программирование игр для компьютеров > Blitz3D > 3D-программирование

3D-программирование Вопросы, касающиеся программирования 3D мира

Ответ
 
Опции темы
Старый 21.04.2012, 23:01   #1
burovalex
Разработчик
 
Аватар для burovalex
 
Регистрация: 04.04.2012
Сообщений: 468
Написано 37 полезных сообщений
(для 60 пользователей)
Оптимизированный перебор Type'а

Обратил внимание что использование For Each с проверкой всех полей, при большом количестве записей начинает напрягать проц. Написал выход.

1. Обычный перебор (при 15к записей 1 кадр высчитавает 30-31 мс)
For grass.grass=Each grass
	grass\timer=grass\timer+time
	If grass\growed=False Then
	grass\scale=grassMaxScale*(grass\timer/Float(grassIntervalGrow))
	ScaleSprite grass\entity,grass\scale,grass\scale
	PositionEntity grass\entity,EntityX(grass\entity),grass\y+grass\scale,EntityZ(grass\entity)
	If grass\scale>grassMaxScale Then grass\growed=True 
	EndIf 
Next
2. Мой вариант перебора (при 15к записей 1 кадр высчитавает 16-17 мс)
Function GrassUpdate()
For grass.grass=Each grass
	grass\timer=grass\timer+time
Next 
End Function 

Function GrassCheck(n)
For i=1 To n
	If Not grassHandle Then
	  grassHead.grass=First grass
	  grassHandle=Handle(grassHead)
	Else
	  grass.grass=Object.grass(grassHandle)
	  If grass\growed=False Then
	  grass\scale=grassMaxScale*(grass\timer/Float(grassIntervalGrow))
	  ScaleSprite grass\entity,grass\scale,grass\scale
  	  PositionEntity grass\entity,EntityX(grass\entity),grass\y+grass\scale,EntityZ(grass\entity)
	  If grass\scale>grassMaxScale Then grass\growed=True 
	EndIf 
	grass.grass=After grass
	grassHandle=Handle(grass)
	EndIf
Next 
End Function
В кратце смысл такой, если у вас будет несколько тысяч записей, то можно одной функцией применять изменения к "моментальным полям" всех записей (т.е. те поля, которые необходимо изменять каждый кадр), а остальные поля (которые не требуется проверять моментально) проверять в n-ом количестве, например не сразу 2000 записей за кадр, а по 100 записей.
Посмотрите пожалуста, у меня в другом коде этот метод не работает, хотя должно было работать после копи-паст.
Поделитесь какие тут недостатки

Прикреплены примеры
Вложения
Тип файла: rar testSprite.rar (55.0 Кб, 428 просмотров)
__________________
(Offline)
 
Ответить с цитированием
Старый 21.04.2012, 23:18   #2
burovalex
Разработчик
 
Аватар для burovalex
 
Регистрация: 04.04.2012
Сообщений: 468
Написано 37 полезных сообщений
(для 60 пользователей)
Ответ: Оптимизированный перебор Type'а

Визуально работают поразному, потому что трава не должна вырастать за 30 секунд
__________________
(Offline)
 
Ответить с цитированием
Старый 22.04.2012, 05:07   #3
Платон Александрович
Нуждающийся
 
Аватар для Платон Александрович
 
Регистрация: 05.10.2011
Адрес: Россия, Южно-Сахалинск
Сообщений: 66
Написано 42 полезных сообщений
(для 83 пользователей)
Ответ: Оптимизированный перебор Type'а

В твоем случае достаточно увеличить шаг роста травы в N раз и обновлять ее не каждый кадр, а раз в N кадров, тогда и общий FPS будет больше соответственно.
Ну и код оптимальнее пиши, как минимум в твоем случае:
- деление на float число заменять, по возможности, на умножение на обратное ему число.
- пользоваться Object только там, где это действительно необходимо. Некоторые думают что это работает так-же быстро как доступ к массиву, так вот это не так. Стоит знать что это поиск экземпляра по hash-map, который в лучшем случае имеет алгоритмическую сложность O(log N), а его реализация скорее всего это С++ый std::map, который основан на красно-черном дереве (т.е. при частом использовании получаем промахи кеша что дополнительно снижает быстродействие)

ЗЫ
Спрайт это отдельный энтити, а много энтитей для блица плохо, лучше тут подойдет single-surface техника, где-то здесь была даже библиотека для этого, поищи.
(Offline)
 
Ответить с цитированием
Эти 3 пользователя(ей) сказали Спасибо Платон Александрович за это полезное сообщение:
burovalex (22.04.2012), Crayzi (22.04.2012), HolyDel (23.04.2012)
Старый 22.04.2012, 13:25   #4
Halk-DS
Разработчик
 
Аватар для Halk-DS
 
Регистрация: 09.08.2006
Адрес: Украина
Сообщений: 431
Написано 65 полезных сообщений
(для 53 пользователей)
Ответ: Оптимизированный перебор Type'а

Я в таких ситуациях люблю 100%трави/фпс и апдейтить только некий процент травы за тик. И как я уже гдето постил, отличная статейка по списках, рекомендую!
(Offline)
 
Ответить с цитированием
Старый 22.04.2012, 22:32   #5
burovalex
Разработчик
 
Аватар для burovalex
 
Регистрация: 04.04.2012
Сообщений: 468
Написано 37 полезных сообщений
(для 60 пользователей)
Ответ: Оптимизированный перебор Type'а

Сообщение от Платон Александрович Посмотреть сообщение
- деление на float число заменять, по возможности, на умножение на обратное ему число.
- пользоваться Object только там, где это действительно необходимо. Некоторые думают что это работает так-же быстро как доступ к массиву, так вот это не так. Стоит знать что это поиск экземпляра по hash-map...
Ну если обратите внимание на код, то Object я использую только в том случае, если Handle() вернул ноль, а это происходит только при запуске и в конце цикла.

А про float я не понял, вы имеете ввиду использовать Integ*1.0?

Я в таких ситуациях люблю 100%трави/фпс и апдейтить только некий процент травы за тик. И как я уже гдето постил, отличная статейка по списках, рекомендую!
Вы так коротко написали, не пойму, правильно подумал или нет. Т.е. как в моем коде менять N=countGrass/fps ??

А вот связанные списки для меня вообще темный лес пока ) Вообще путаюсь

Ну а так, что скажете по коду, нет косяков?
__________________
(Offline)
 
Ответить с цитированием
Старый 23.04.2012, 04:08   #6
Платон Александрович
Нуждающийся
 
Аватар для Платон Александрович
 
Регистрация: 05.10.2011
Адрес: Россия, Южно-Сахалинск
Сообщений: 66
Написано 42 полезных сообщений
(для 83 пользователей)
Ответ: Оптимизированный перебор Type'а

Сообщение от burovalex Посмотреть сообщение
Ну если обратите внимание на код, то Object я использую только в том случае, если Handle() вернул ноль, а это происходит только при запуске и в конце цикла.
В функции GrassCheck, 6 строчка
grass.grass=Object.grass(grassHandle)
и строчка 14
Handle(grass)
будут выполнятся "n - 1" раз
Сообщение от burovalex Посмотреть сообщение
А про float я не понял, вы имеете ввиду использовать Integ*1.0?
Я имею ввиду "X / Y" заменять на "X * Z", где Z - заранее расчитанная обратная величина от Y, т.е. "Z = 1.0 / Y".
(Offline)
 
Ответить с цитированием
Старый 23.04.2012, 05:07   #7
Halk-DS
Разработчик
 
Аватар для Halk-DS
 
Регистрация: 09.08.2006
Адрес: Украина
Сообщений: 431
Написано 65 полезных сообщений
(для 53 пользователей)
Ответ: Оптимизированный перебор Type'а

Сообщение от burovalex Посмотреть сообщение
Вы так коротко написали, не пойму, правильно подумал или нет. Т.е. как в моем коде менять N=countGrass/fps ??
Я имел ввиду следующее. Есть у тебя 100 травинок. И есть у тебя 30 кадров в секунду.
100/30 = 3.3 В таком случае каждый кадр обновляешь не всю траву а 3.3 травинки. И ты равномерно на целую секунду распределишь всю нагрузку в обновлении травы. Даже в случае падения фпс. Только цифры эти я назвал теоретически, на практике у каждого они будут свои. просто возможно ты хочешь что б в секунду трава обновлялась не 1 раз а 3. Тогда 3.3 * 3 = примерно 10 травинок за раз апдейтишь. Таким образом ты избавишь комп от лишнего простоя. А если ты будешь апдейтить сразу всю траву раз в 1 секунду - будет скачок производительности. Короче не по программистски это
Так что пробуй уже учись оптимизировать программы распределяя ресурсы процессора равномерно!
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
tormoz (23.04.2012)
Старый 23.04.2012, 19:55   #8
burovalex
Разработчик
 
Аватар для burovalex
 
Регистрация: 04.04.2012
Сообщений: 468
Написано 37 полезных сообщений
(для 60 пользователей)
Ответ: Оптимизированный перебор Type'а

А если ты будешь апдейтить сразу всю траву раз в 1 секунду - будет скачок производительности.
Hulk-DS, если вы внимательнее посмотрите второй пример, то увидите что это и есть смысл заведённой темы )
Я именно так и сделал, что я не всю траву перебираю, а только n-ое её количество.
А на основной вопрос вы так и не ответили, нет ли тут косяков?

Платон Александрович
Я имею ввиду "X / Y" заменять на "X * Z", где Z - заранее расчитанная обратная величина от Y, т.е. "Z = 1.0 / Y".
Объясните пожалуйста, а чем будет отличаться
Z = 1.0 / Y
R=X*Y
от варианта (который я понял)
R=X/(Y*1.0)
?
__________________
(Offline)
 
Ответить с цитированием
Старый 24.04.2012, 05:22   #9
Жека
Дэвелопер
 
Регистрация: 04.09.2005
Адрес: Красноярск
Сообщений: 1,376
Написано 491 полезных сообщений
(для 886 пользователей)
Ответ: Оптимизированный перебор Type'а

Я не Платон, но влезу первый.
Смысл умножения на обратную величину в том, что умножение работает быстрее. Вместо деления на 2.0 можно использовать умножение на 0.5 - результат будет одинаковый, но умножение выполнится быстрее.

> Объясните пожалуйста, а чем будет отличаться
Z = 1.0 / Y <- это нужно делать "вне игрового цикла" (кавычки означают: бывает смена значения в цикле, но она по событию, т.е. пересчёт не в каждой итерации цикла)
R=X*Y <- это внутри цикла, только не Y там а Z должен быть, R=X*Z
> от варианта (который я понял)
R=X/(Y*1.0) <- Y*1.0 - бесполезная операция, делить и умножать на единицу нет надобности

Если в выражении у тебя в знаменателе идёт переменная, которая по ходу работы программы меняется, то смысла сначала делить 1.0 на эту переменную, а затем результат умножать на что-то - нет. Используй 1.0/X только в случае, когда Х хранит постоянное значение хотя бы какое-то время (потом при смене Х пересчитаешь заново Z=1.0/X и снова постоянное Z использовать будешь).
(Offline)
 
Ответить с цитированием
Эти 2 пользователя(ей) сказали Спасибо Жека за это полезное сообщение:
Старый 24.04.2012, 09:10   #10
Halk-DS
Разработчик
 
Аватар для Halk-DS
 
Регистрация: 09.08.2006
Адрес: Украина
Сообщений: 431
Написано 65 полезных сообщений
(для 53 пользователей)
Ответ: Оптимизированный перебор Type'а

Сообщение от burovalex Посмотреть сообщение
Hulk-DS, если вы внимательнее посмотрите второй пример, то увидите что это и есть смысл заведённой темы )
Я именно так и сделал, что я не всю траву перебираю, а только n-ое её количество.
А на основной вопрос вы так и не ответили, нет ли тут косяков?
?
Косяков тут хватает. Я не в курсе видел ли ты свой фпс.
Кроме того 2-го примера я не вижу я вижу один.
Если б ко мне пришел человек и спросил как правильно воткнуть юзб флешку в сетевой слот(там де коннектор), то по твоей логике я должен был б дать ему молоток.
Как парни уже тебе подметили - ты юзаешь на каждую травинку по отдельному ентити. Зачем мне тебе помогать делать неправильно? Делай не спрайтами делай все в одном меше/сурфейсе. Я прикрипил для изучения тебе аттач.
Заметь пару вещей:
1. Намного фпс выше.
2. трава не крутится вечно к камере и выглядит более естественно.
3. если ты в пределах функции введешь не 15к травинок а припустим 20к то вылетит Memory Acces Violation - ошибка, а она вылетит потому, что максимальное количество вершин(или треугольников, точно не помню) в одном сурфейсе перевышено. А 1 функция как там видно крепит все на 1 сурфейс. Поэтому следи за количеством трисов на меше.
Ну а так, учись сделать тоже что я тебе аттачнул, только чтоб трава генерировалась в некотором радиусе от игрока. Другими(образными) словами, не игрок бегает по полю с травой, а трава бегает за игроком по полю. Это не тупость - это оптимизация....

upd: Я сообразил где 2-й пример. Уже лень смотреть, но походу там тоже фпс маленький - значит тоже спрайтами.
п.с. Я может в своем примере натупил с синусами косинусами, но это ничего, если надо будет сам сможешь подумать и выправить.
Вложения
Тип файла: rar SingleSurf.rar (7.6 Кб, 445 просмотров)
(Offline)
 
Ответить с цитированием
Эти 4 пользователя(ей) сказали Спасибо Halk-DS за это полезное сообщение:
burovalex (24.04.2012), Markova (24.04.2012), RBK (24.04.2012), St_AnGer (24.04.2012)
Старый 24.04.2012, 22:56   #11
burovalex
Разработчик
 
Аватар для burovalex
 
Регистрация: 04.04.2012
Сообщений: 468
Написано 37 полезных сообщений
(для 60 пользователей)
Ответ: Оптимизированный перебор Type'а

И фпс не маленький - это пишется время на кадр (т.е. 16-17 норма) Может вы хапустили первый пример - где обычный перебор, который тормозит.
Да дело в том, что случайная генерация травы мне не подходит, т.к. трава должна рости и размножаться если в радиусе r свободное пространство.

Пример я посмотрел, и быстрее он работает только из-за того, что вы уменьшили размер травы с 52 кб до 8 кб., при 52 кб. в вашем примере тормозить начинает сразу, даже закомментировав 45000 и оставив 15000. Так что вы меня не убедили что лучше использовать сёрфы ) , НО пример очень хороший много для себя взял и смотрится конечно такая травка намного симпатичнее. Так что всё равно, спасибо!
Просто то что я сейчас делаю наоборот направлено на простоту.

Я только не понимаю, на счет сурфейса я понял что больше 20000 трианглов будет MAV, а вот почему со спрайтом после 17000 MAV выпрыгивает на строке RenderWorld?

И сразу еще один вопрос чтоб тему не создавать
Есть куча ентити, Можно ли как-нибудь проверить что рядом с определенным объектом есть свободное место, не перебирая все ентити??
__________________
(Offline)
 
Ответить с цитированием
Старый 24.04.2012, 23:30   #12
moka
.
 
Регистрация: 05.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений
(для 6,863 пользователей)
Ответ: Оптимизированный перебор Type'а

Также пространство нужно кластеризовать, разбив на секторы, и списки держать в секторах. Таким образом не нужно будет перелистывать траву совсего участка x * y километров, а только сектора которые входят в обзор видимости. Таким образом можно держать сколько угодно травы, и её количество основанное на размере мира не будет влиять сильно на логику просчётов.
(Offline)
 
Ответить с цитированием
Эти 2 пользователя(ей) сказали Спасибо moka за это полезное сообщение:
Hulk-DS (25.04.2012), mauNgerS (25.04.2012)
Старый 25.04.2012, 03:02   #13
Halk-DS
Разработчик
 
Аватар для Halk-DS
 
Регистрация: 09.08.2006
Адрес: Украина
Сообщений: 431
Написано 65 полезных сообщений
(для 53 пользователей)
Ответ: Оптимизированный перебор Type'а

Сообщение от burovalex Посмотреть сообщение
И фпс не маленький - это пишется время на кадр (т.е. 16-17 норма) Может вы хапустили первый пример - где обычный перебор, который тормозит.
Может у тебя видеокарта за 3к баксов, но я не могу посмотреть в сторону травы без слайд шоу, и показатель 16-17 я даже не видел.

Сообщение от burovalex Посмотреть сообщение
Да дело в том, что случайная генерация травы мне не подходит, т.к. трава должна рости и размножаться если в радиусе r свободное пространство.
Я понимаю. Я тебе не написал то что тебе нужно не потому что не понял твой задачи, а потому что ты должен это сам сделать. Я всего лишь скинул пример с более правильной техникой использования травы. А про то что ты говоришь тебе уже и я и Мока писали.

Сообщение от burovalex Посмотреть сообщение
Пример я посмотрел, и быстрее он работает только из-за того, что вы уменьшили размер травы с 52 кб до 8 кб.,
А вот и нет. Он быстрее работает потому что я все травинки объеденил в один сурфейс(одну поверхность) в одной модели. Когда я применю MoveEntity GrussMesh[0],x,y,z - у меня переместится не одна травинка. А целое поле травы которое генерировала функция в которой указана модель GrussMesh[0], а это потому что целое поле - единый сурфейс, единая модель, единая поверхность. Не представляю как тебе это по другому объяснить. Пойми одно, твой метод со спрайтами - неправильный!!! Это тут тебе любой скажет.
п.с. я не размер файла с 52 кб до 8 кб. уменьшил. У тебя трава 512х512пикселей изображение. Для такой травы и 64х64 хватит. Но я сделал тогда 128х128.

Сообщение от burovalex Посмотреть сообщение
при 52 кб. в вашем примере тормозить начинает сразу, даже закомментировав 45000 и оставив 15000.
Ничего подобного. Если хочешь использовать свою огромную. Так оно и есть - это очень, нафик, ОГРОМНАЯ текстура травы, то сделай вместо моей текстуры:
Global GrassTex=LoadTexture("Grass.png",1+4+8+256)
Свою, но с другими циферками в конце:
Global GrassTex=LoadTexture("Grass1.png",1+4+8 )
И мой пример даже 120 000 травинок выдержит. Прикрепил в аттаче где пример с твоей текстурой и 120 тисяч травинок работают при 60 фпс. Стоко ФПСа тебе еще долго убивать твоей травой.

Сообщение от burovalex Посмотреть сообщение
Так что вы меня не убедили что лучше использовать сёрфы )
Жаль, надеюсь в свете новых улик ты примешь правильное решение отказаться от спрайтов. И кстате, я не пытаюсь тебя ничему убедить. Я говорю прямо так, как тебе будет лучше, но кого слушать - дело твое.

Сообщение от burovalex Посмотреть сообщение
НО пример очень хороший много для себя взял и смотрится конечно такая травка намного симпатичнее. Так что всё равно, спасибо!
Просто то что я сейчас делаю наоборот направлено на простоту.
Я не понимаю как первое предложение можна перечеркнуть третьим.
Зачем учится табуреткой забивать гвозди, если 99.999999999999% тебе это в жизни не пригодится. Трава спрайтами - это для меня выглядит как если человек отказываясь от молотка берет табуретку для забивания гвоздей.
Хотя я тебе скажу, когда я учился делал вещи и по ужасней

Сообщение от burovalex Посмотреть сообщение
Я только не понимаю, на счет сурфейса я понял что больше 20000 трианглов будет MAV, а вот почему со спрайтом после 17000 MAV выпрыгивает на строке RenderWorld?
Я не скажу точной причины. Но 17тыщь моделей это перебор. В играх когда их 1тыщя - это уже мощная игра.

Я не "Вы" говори на меня - "Ты"
Вложения
Тип файла: rar SingleSurf.rar (51.9 Кб, 435 просмотров)
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
mauNgerS (25.04.2012)
Старый 25.04.2012, 21:10   #14
burovalex
Разработчик
 
Аватар для burovalex
 
Регистрация: 04.04.2012
Сообщений: 468
Написано 37 полезных сообщений
(для 60 пользователей)
Ответ: Оптимизированный перебор Type'а

После твоего примера сложно остаться с прежним мнением )
Только мне твой пример
Global GrassTex=LoadTexture("Grass.png",1+4+8+256)
Свою, но с другими циферками в конце:
Global GrassTex=LoadTexture("Grass1.png",1+4+8 )
просто вынес моск )
Я всегда думал "если поместить текстуру в видеопамять - будет на 100% работать быстрее", теперь я понял что я ничего не понимаю Объясни пожалуста как так получается?

И на счет тормозов, я недавно переставил винду и запустил свой пример, он у меня очень тормозил (не понял в чем дело), потом установил блитц 1.99 и опять начал нормально идти )
И тестю я на буке с урезанным i3 и радик средненький
__________________
(Offline)
 
Ответить с цитированием
Старый 25.04.2012, 23:04   #15
Wegox
Бывалый
 
Аватар для Wegox
 
Регистрация: 17.12.2011
Сообщений: 862
Написано 443 полезных сообщений
(для 1,133 пользователей)
Ответ: Оптимизированный перебор Type'а

Сообщение от burovalex Посмотреть сообщение
После твоего примера сложно остаться с прежним мнением )
Только мне твой пример

просто вынес моск )
Я всегда думал "если поместить текстуру в видеопамять - будет на 100% работать быстрее", теперь я понял что я ничего не понимаю Объясни пожалуста как так получается?
Ну да ты прав, только вот, виде-память не безгранична, 765 метров это сильно!
у тебя пара Сапфиров что-ли стоит
(Offline)
 
Ответить с цитированием
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Часовой пояс GMT +4, время: 02:19.


vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com