Собственная LOD система - Форум Игроделов
Чт, 02 Май 2024, 10:24 
 
Приветствую Вас Гость Главная | Регистрация | Вход
Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Форум Игроделов » UNITY3D » СКРИПТИНГ » Собственная LOD система (Лод)
Собственная LOD система
PasterLakДата: Вт, 01 Сен 2015, 12:41 | Сообщение # 1
 
Сообщений: 8
Награды: 0
Репутация: 0
Статус: Offline
Всем привет!

Делаю на данный момент свою sanbox игру, мир в которой состоит из блоков, и на днях взялся за их оптимизацию. Попробовал стандартную LOD систему и она мне не понравилась, так-как нельзя настроить float определённое расстояние для прорисовки блоков. Скачивал пару LOD систем с посторонних ресурсов, и они тоже не соответствовали моим требованиям. И тогда пришлось написать собственный скрипт для LODа.

Собственно к чему это всё?

Я хотел бы спросить у знающих людей насколько эффективен мой скрипт и получить рекомендации по его улучшению с целью получить более качественную оптимизацию блоков в игре.

Вот сам скрипт с пояснениями:

Код

private var dis : float; // Дистанция между игроком и блоком
static var lod1 : float = 10; // Расстояния для включения 1 лода
static var lod2 : float = 20; // Расстояния для включения 2 лода
static var lod3 : float = 30; // Расстояния для включения 3 лода
static var lod4 : float = 40; // Расстояния для включения 4 лода

public var material : Material[]; // Материалы для лодов 32на 32 пикселя, 16, 8 и 4.
private var player : GameObject;

function Start()    
{
    player = GameObject.Find("MainCamera"); //Поиск игрока
}

function Update()    
{
       
    dis = Vector3.Distance(transform.position, player.transform.position); // определение дистанции между игроком и блоком.
       
    if(dis < lod1)                             
    {                   
     this.gameObject.renderer.sharedMaterial = material[0];
     this.gameObject.GetComponent(BoxCollider).enabled = true;    
    }
       
    if(dis >= lod1)
    {
     this.gameObject.renderer.sharedMaterial = material[1];
     this.gameObject.GetComponent(BoxCollider).enabled = false;    
    }
       
    if(dis >= lod2)
    {
     this.gameObject.renderer.sharedMaterial = material[2];
    }
    if(dis >= lod3)
    {
        
     this.gameObject.renderer.sharedMaterial = material[3];
    }

if(dis >= lod4)
{
     this.gameObject.GetComponent(MeshRenderer).enabled = false;    
        
}
if(dis < lod4)
{
     this.gameObject.GetComponent(MeshRenderer).enabled = true;    
        
}
}


В общем лод изменяет материал куба на менее качественный когда расстояние до игрока увеличивается. Коллизия на расстоянии отключается.
Когда блок совсем далеко, то renderer отключается и блок не видимый для игрока.

Кстати, я сгенерировал 8000 блоков со своей лод системой, и игра выдавала 60 фпс, со стандартный лодом 8000 блоков выдавали 30-35 фпс при меньшей дальности прорисовки. Помоги как можно ещё улучшить скрипт.

Вот скриншот лода 8000 кубов.



Сообщение отредактировал PasterLak - Вт, 01 Сен 2015, 12:47
 
СообщениеВсем привет!

Делаю на данный момент свою sanbox игру, мир в которой состоит из блоков, и на днях взялся за их оптимизацию. Попробовал стандартную LOD систему и она мне не понравилась, так-как нельзя настроить float определённое расстояние для прорисовки блоков. Скачивал пару LOD систем с посторонних ресурсов, и они тоже не соответствовали моим требованиям. И тогда пришлось написать собственный скрипт для LODа.

Собственно к чему это всё?

Я хотел бы спросить у знающих людей насколько эффективен мой скрипт и получить рекомендации по его улучшению с целью получить более качественную оптимизацию блоков в игре.

Вот сам скрипт с пояснениями:

Код

private var dis : float; // Дистанция между игроком и блоком
static var lod1 : float = 10; // Расстояния для включения 1 лода
static var lod2 : float = 20; // Расстояния для включения 2 лода
static var lod3 : float = 30; // Расстояния для включения 3 лода
static var lod4 : float = 40; // Расстояния для включения 4 лода

public var material : Material[]; // Материалы для лодов 32на 32 пикселя, 16, 8 и 4.
private var player : GameObject;

function Start()    
{
    player = GameObject.Find("MainCamera"); //Поиск игрока
}

function Update()    
{
       
    dis = Vector3.Distance(transform.position, player.transform.position); // определение дистанции между игроком и блоком.
       
    if(dis < lod1)                             
    {                   
     this.gameObject.renderer.sharedMaterial = material[0];
     this.gameObject.GetComponent(BoxCollider).enabled = true;    
    }
       
    if(dis >= lod1)
    {
     this.gameObject.renderer.sharedMaterial = material[1];
     this.gameObject.GetComponent(BoxCollider).enabled = false;    
    }
       
    if(dis >= lod2)
    {
     this.gameObject.renderer.sharedMaterial = material[2];
    }
    if(dis >= lod3)
    {
        
     this.gameObject.renderer.sharedMaterial = material[3];
    }

if(dis >= lod4)
{
     this.gameObject.GetComponent(MeshRenderer).enabled = false;    
        
}
if(dis < lod4)
{
     this.gameObject.GetComponent(MeshRenderer).enabled = true;    
        
}
}


В общем лод изменяет материал куба на менее качественный когда расстояние до игрока увеличивается. Коллизия на расстоянии отключается.
Когда блок совсем далеко, то renderer отключается и блок не видимый для игрока.

Кстати, я сгенерировал 8000 блоков со своей лод системой, и игра выдавала 60 фпс, со стандартный лодом 8000 блоков выдавали 30-35 фпс при меньшей дальности прорисовки. Помоги как можно ещё улучшить скрипт.

Вот скриншот лода 8000 кубов.


Автор - PasterLak
Дата добавления - 01 Сен 2015 в 12:41
seamanДата: Вт, 01 Сен 2015, 12:55 | Сообщение # 2
Гуру
 
Сообщений: 1748
Награды: 10
Репутация: 660
Статус: Offline
Если уж оптимизировать, то:
1. gameObject.GetComponent(BoxCollider) - вынести в Start
2. Сравнивать квадраты длины вектора, т.е.
dis = (transform.position - player.transform.position).sqrMagnitude;
Добавляем переменные:
float lod1Sqr;
float lod1Sqr;
float lod1Sqr;
float lod1Sq;
в Start:
float lod1Sqr = lod1 * lod1;
float lod1Sqr = lod2 * lod2;
float lod1Sqr = lod3 * lod3;
float lod1Sqr = lod4 * lod4;
и сравниваем с новыми переменными

ЗЫ: но вообще-то лод все же первое что должен делать - подменять меши на менее полигональные.
 
СообщениеЕсли уж оптимизировать, то:
1. gameObject.GetComponent(BoxCollider) - вынести в Start
2. Сравнивать квадраты длины вектора, т.е.
dis = (transform.position - player.transform.position).sqrMagnitude;
Добавляем переменные:
float lod1Sqr;
float lod1Sqr;
float lod1Sqr;
float lod1Sq;
в Start:
float lod1Sqr = lod1 * lod1;
float lod1Sqr = lod2 * lod2;
float lod1Sqr = lod3 * lod3;
float lod1Sqr = lod4 * lod4;
и сравниваем с новыми переменными

ЗЫ: но вообще-то лод все же первое что должен делать - подменять меши на менее полигональные.

Автор - seaman
Дата добавления - 01 Сен 2015 в 12:55
seamanДата: Вт, 01 Сен 2015, 13:23 | Сообщение # 3
Гуру
 
Сообщений: 1748
Награды: 10
Репутация: 660
Статус: Offline
Далее.
Проверять луше не в Update, а в FixedUpdate, например. Или в корутине, которая автозапускается с нужным периодом (больщим чем кадр!), например раз в 0.1 секунды.
_________
Если Вы делаете МайнКрафт, то никакие ЛОД не помогут.
 
СообщениеДалее.
Проверять луше не в Update, а в FixedUpdate, например. Или в корутине, которая автозапускается с нужным периодом (больщим чем кадр!), например раз в 0.1 секунды.
_________
Если Вы делаете МайнКрафт, то никакие ЛОД не помогут.

Автор - seaman
Дата добавления - 01 Сен 2015 в 13:23
PasterLakДата: Вт, 01 Сен 2015, 14:28 | Сообщение # 4
 
Сообщений: 8
Награды: 0
Репутация: 0
Статус: Offline
Спасибо за советы!

Цитата seaman ()
ЗЫ: но вообще-то лод все же первое что должен делать - подменять меши на менее полигональные.


Да, полностью согласен, но тем не менее эффект от LOD присутствует. Я ради интереса провёл тест:
Нагрузил сцену в 16.000 блоков, чтобы нагляднее сравнить и сделал два билда игры с LOD и без него.

В результате без LOD-а фпс составил в среднем 40, а с LOD-ом с того же ракурса и вовсе 60, чего собственно я и хотел добиться.
 
СообщениеСпасибо за советы!

Цитата seaman ()
ЗЫ: но вообще-то лод все же первое что должен делать - подменять меши на менее полигональные.


Да, полностью согласен, но тем не менее эффект от LOD присутствует. Я ради интереса провёл тест:
Нагрузил сцену в 16.000 блоков, чтобы нагляднее сравнить и сделал два билда игры с LOD и без него.

В результате без LOD-а фпс составил в среднем 40, а с LOD-ом с того же ракурса и вовсе 60, чего собственно я и хотел добиться.

Автор - PasterLak
Дата добавления - 01 Сен 2015 в 14:28
Форум Игроделов » UNITY3D » СКРИПТИНГ » Собственная LOD система (Лод)
  • Страница 1 из 1
  • 1
Поиск:
Загрузка...

Game Creating CommUnity © 2009 - 2024