Способ поднятия fps и их применение на Blitz3D
Данная статья затрагивает особенности графического движка Blitz3D, в принципе эта статья написана исключительно для него, но, тем не менее, может содержать полезную информацию и для разработчиков на других графических движках.
Сейчас мы рассмотрим наиболее очевидный и часто применяемый способ поднятия fps, а также его применение. Я хочу затронуть тему, а точнее проблему, с которой сталкиваются многие начинающие разработчики. Многие из них, а возможно и вы задавались вопросом: «Я создаю уровень со ста деревьями и домами, но все жутко тормозит, а в других играх нет, помогите мне, как мне посадить на уровень сто миллионов деревьев без тормозов?». В этой статье я расскажу как.
Тормоза от количества объектов
Blitz3D обладает одной особенностью, он тормозит не столько от количества полигонов, как от количества обсчитываемых рендером объектов.
Для него огромная разница, что рендерить: 100 объектов по 1000 полигонов, или 1000 объектов по 100 полигонов.
Для этого я представляю вашему вниманию 2 теста:
Первый тест.
Скопируйте данный исходный код себе в редактор Blitz3D.
Запустите его. Запомните то количество fps, которое выдал вам тест.
Теперь найдите строчку Global Select_=0 и замените значение с 0 на 1. И запустите тест еще раз.
Обратите внимание на количество fps. Оно стало гораздо выше. Теперь давайте разберем исходный код, почему так происходит?
В первом случае у нас создаются кубики и просто парентяться к пивоту, который мы и вращаем. При этом каждый кубик является отдельным объектом и сохраняет свою независимость, мы можем его двигать или удалять.
Во втором случае мы создаем пустой меш. После позиционирования кубиков мы приаттачиваем наши кубики к данному мешу, а после удаляем их. Таким образом у нас остается один объект, который и облегчает работу рендера, тем самым повышая fps.
Недостаток такого способа очевиден. Объекты теряют независимость, зато fps повышается в несколько раз.
Graphics3D 800,600,32,2
SetBuffer BackBuffer()
SetFont LoadFont ("Arial Cyr",16)
cam=CreateCamera()
PositionEntity cam,0,0,-50
l=CreateLight()
Global frames_,render_time_,fps_
Global count=0
Global telo
Global Select_=0
;================================
; Pivot
;================================
If Select_=0 Then
telo=CreatePivot()
For x = - 15 To 15 Step 3
For y = - 15 To 15 Step 3
For z = - 15 To 15 Step 3
count=count+1
cube=CreateCube()
PositionEntity cube,x,y,z
EntityParent cube,telo
Next
Next
Next
EndIf
;================================
; Addmesh
;================================
If Select_=1 Then
telo=CreateMesh()
For x = - 15 To 15 Step 3
For y = - 15 To 15 Step 3
For z = - 15 To 15 Step 3
count=count+1
cube=CreateCube()
PositionMesh cube,x,y,z
AddMesh cube,telo
FreeEntity cube
Next
Next
Next
EndIf
Repeat
TurnEntity telo,1,1,1
UpdateWorld
RenderWorld
Text 10,10,"fps: "+FPS_Show()+" Objects: "+count+" Tris: "+TrisRendered()
Flip 0
Until KeyHit(1)
End
Function FPS_Show()
frames_=frames_+1
If MilliSecs()-render_time_=>1000 Then fps_=frames_ : frames_=0 : render_time_=MilliSecs()
Return fps_
End Function
Но всегда ли так происходит? А что если вы хотите сделать объекты интерактивными?
Рассмотрим второй пример исходного кода.
Вам знакома команда CameraRange? Правильно, она устанавливает радиус обзора камеры, все объекты, которые находятся за пределом радиуса, не поступают на рендеринг. Зачем я ее привел? Дело в том, что при объединении объектов в один меш, он всегда рендерится полностью, даже если большая его часть не видна. Это и станет нам полезным.
Скопируйте нижеследующий код:
Запустите его с параметром Global Select_=1 где все объекты объединяются в один меш. Объекты размещены таким образом, что напоминают нам лес или домики. У автора этой статьи тест показал максимальное значение fps=163. Прошу заметить, что в кадре рендерится постоянно 60018 полигонов, т.к. все объекты объединены в один меш.
Теперь изменим состояние переменной Select_ на 0. В данном режиме все объекты отдельны и рендерится каждый раз разное количество полигонов. Fps в данном случае 242. Улучшение есть, хоть и небольшое. Но огромный плюс данного метода это то, что все объекты интерактивны, вы можете к примеру сделать ломаемые деревья или разносимые в клочья дома. Так получается потому, что в камере рендерится меньшее количество полигонов. В своей игре вы должны настроить правильное расстояние в
CameraRange, которое вам угодно. Теперь вы сможете смело ставить на карту кучу интерактивных объектов.
Graphics3D 800,600,32,2
SetBuffer BackBuffer()
SetFont LoadFont ("Arial Cyr",16)
Global cam
cam=CreateCamera()
l=CreateLight()
;======================
; !
;======================
CameraRange cam,1,100
;======================
PositionEntity cam,0,3,0Global frames_,render_time_,fps_
Global telo
Global plane=CreatePlane()
Global count=0
Global Select_=0
;================================
; Pivot
;================================
If Select_=0 Then
telo=CreatePivot()
For x = - 450 To 450 Step 42
For z = - 450 To 450 Step 42
count=count+1
cube=CreateCylinder(32)
ScaleEntity cube,5,5,5
PositionEntity cube,x,0,z
EntityParent cube,telo
Next
Next
EndIf
;================================
; Addmesh
;================================
If Select_=1 Then
telo=CreateMesh()
For x = - 450 To 450 Step 42
For z = - 450 To 450 Step 42
count=count+1
cube=CreateCylinder(32)
ScaleMesh cube,5,5,5
PositionMesh cube,x,0,z
AddMesh cube,telo
FreeEntity cube
Next
Next
EndIf
Repeat
TurnEntity telo,0,.5,0
UpdateWorld
RenderWorld
Text 10,10,"fps: "+FPS_Show()+" Objects: "+count+" Tris: "+TrisRendered()
Flip 0
Until KeyHit(1)
End
Function FPS_Show()
frames_=frames_+1
If MilliSecs()-render_time_=>1000 Then fps_=frames_ : frames_=0 : render_time_=MilliSecs()
Return fps_
End Function

(7 votes, average: 4,14 из 5)
3 Комментариев на «Способ поднятия fps и их применение на Blitz3D»
Вот это действительно полезно! Здорово!
Ответить
Офигеть! И правда работает О_о
Ответить
спасибо, было очень инересно и полезно, особенно про мэш.
Ответить