Gerenciar carregamento de texturas
3 participantes
Página 1 de 1
Gerenciar carregamento de texturas
Boa noite, ao buildar meu projeto atual percebi que o consumo de RAM está meio alto. Então, habilitei o memory profiler para dar uma olhada e praticamente todo o consumo está ligado ao carregamento de texturas (obviamente). Meu projeto involve geração procedural de uniformes, o que significa que há centenas delas dentro do projeto (por enquanto, cerca de 1000 e esse número com certeza vai aumentar com o tempo). Claro que isso não significa que todas são usadas a todo momento, o que significa que para melhorar a performance eu precisaria criar alguma forma de gerenciamento para evitar que todas as texturas do projeto estejam carregadas na memória ao mesmo tempo.
Atualmente as referências a essas texturas estão ligadas a scriptable objects e eu não sei se isso dificulta, facilita ou é indiferente a esta necessidade de gerenciamento. A maioria delas precisam ser lidas em tempo de execução e tem o seu tamanho dobrado. Quanto a compresão, todas estão como normal, não testei com as outras opções de compressão até então. Finalmente, o tamanho máximo delas varia de 2048x2048 (a maioria) até 128x128, acredito que eu não possa diminuir a resolução das mesmas sob pena de perda de qualidade nas texturas finais que o meu projeto gera. Lembrando que ele é um gerador procedural de uniformes para jogos de futebol AAA, ou seja, as texturas geradas precisam respeitar a resolução e qualidade utilizadas nestes jogos para que o resultado seja satisfatório.
Enfim, não tenho lá muitos conhecimentos em otimização e já tentei procurar uma solução por aí, não encontrando nada, por isso decidi criar o post.
Atualmente as referências a essas texturas estão ligadas a scriptable objects e eu não sei se isso dificulta, facilita ou é indiferente a esta necessidade de gerenciamento. A maioria delas precisam ser lidas em tempo de execução e tem o seu tamanho dobrado. Quanto a compresão, todas estão como normal, não testei com as outras opções de compressão até então. Finalmente, o tamanho máximo delas varia de 2048x2048 (a maioria) até 128x128, acredito que eu não possa diminuir a resolução das mesmas sob pena de perda de qualidade nas texturas finais que o meu projeto gera. Lembrando que ele é um gerador procedural de uniformes para jogos de futebol AAA, ou seja, as texturas geradas precisam respeitar a resolução e qualidade utilizadas nestes jogos para que o resultado seja satisfatório.
Enfim, não tenho lá muitos conhecimentos em otimização e já tentei procurar uma solução por aí, não encontrando nada, por isso decidi criar o post.
Re: Gerenciar carregamento de texturas
Então, é meio difícil otimizar isso, porque texturas obrigatóriamente vão parar na memória RAM... O que você poderia fazer é talvez usar um cash rotativo, apenas para os elementos que estão presentes na tela, ou ativos em cena.
A dúvida principal que tenho é em relação a necessidade de carregar tudo na memória. Não da para separar o projeto em cenas derrepente? E carregar em cada cena apenas as texturas necessárias?
A dúvida principal que tenho é em relação a necessidade de carregar tudo na memória. Não da para separar o projeto em cenas derrepente? E carregar em cada cena apenas as texturas necessárias?
Re: Gerenciar carregamento de texturas
MarcosSchultz escreveu:Então, é meio difícil otimizar isso, porque texturas obrigatóriamente vão parar na memória RAM... O que você poderia fazer é talvez usar um cash rotativo, apenas para os elementos que estão presentes na tela, ou ativos em cena.
A dúvida principal que tenho é em relação a necessidade de carregar tudo na memória. Não da para separar o projeto em cenas derrepente? E carregar em cada cena apenas as texturas necessárias?
Então, o projeto é visualmente simples, é apenas um tela de fundo com algumas opções e alguns assets 3D simbolizando a geometria do uniforme. Dependendo das opções selecionadas pelo usuário, o sistema irá filtrar os SO's que sejam pertinentes e randomizar o resultado. Não é como se eu tivesse uma cena com um monte de coisa, como eu disse, eu preciso das texturas no projeto para que o sistema tenha variabilidade e seja mais interessante e completo, mas as texturas definitivamente não são utilizadas a todo momento e ao mesmo tempo, pelo contrário até, os SO's só são utilizados na geração conforme opções específicas sejam selecionadas pelo user. O projeto já está meio grande e eu tenho todos este assets devidamente organizados e categorizados em suas devidas pastas, talvez isso facilite para construir algum tipo de filtragem.
Tipo, eu tenho uma classe que carrega estes SO's e deixa eles em cache, eu cheguei a cogitar a criação um filtro nessa classe para que ela não permaneça carregando todos estes assets ao mesmo tempo. Porém ao retirar 70% dos SO's carregados como teste, a build ainda assim estava pesada, com uma ínfima redução de 100mb em RAM, o que significa que não é este carregamento que está pesando.
A questão é, se o usuário seleciona uma geração que filtra 150 texturas, eu precisaria fazer com que o sistema carregasse apenas estas 150 texturas ao invés de ficar com todas as texturas do projeto na RAM o tempo todo. Eu até aceito sacrificar um pouco de velocidade de geração (atualmente ela ocorre de maneira praticamente instantânea) para que este gerenciamento ocorra, porque da forma como as coisas estão agora, o sistema não está sustentável...
Atualmente eu não vejo como separar este projeto por cenas, considerando que cada time possui 4 uniformes possíveis (casa, fora, goleiro e alternativo) e que estes, geralmente utilizam várias das categorias que por sua vez contém os SO's com as texturas. A não ser que eu fique trocando de cena sempre que um uniforme seja trocado, o que não me parece especialmente eficiente.
Re: Gerenciar carregamento de texturas
Foi pra resolver esse tipo de problema que a Unity criou os Addressables.
https://docs.unity3d.com/Manual/com.unity.addressables.html
Se me lembro bem, e faz tempo que vi isso, o SO faz o carregamento dos assets referenciados nele mesmo que você não os use. Pois, diferente de uma cena que é carregada e descarregada, o SO não tem um tempo de execução pré-definido, e como a intenção dele é armazenar textos e coisas leves, talvez até um ícone de um item, etc. acaba fazendo sentido que ele funcione quase como uma pasta Resources, que é carregado na iniciação do programa e é mantido pertinente na memória até o fim da execução, independente de mudanças de cena.
O Addressables é a única forma que sei de ter uma referência de um objeto, sem a necessidade de carregá-lo na memória desde o começo, com ele você faz a requisição do carregamento de forma assíncrona e descarrega quando quiser. Pra não carregar tudo e repetir o mesmo problema, você pode implementar um ring buffer como o Marcos sugeriu.
https://docs.unity3d.com/Manual/com.unity.addressables.html
Se me lembro bem, e faz tempo que vi isso, o SO faz o carregamento dos assets referenciados nele mesmo que você não os use. Pois, diferente de uma cena que é carregada e descarregada, o SO não tem um tempo de execução pré-definido, e como a intenção dele é armazenar textos e coisas leves, talvez até um ícone de um item, etc. acaba fazendo sentido que ele funcione quase como uma pasta Resources, que é carregado na iniciação do programa e é mantido pertinente na memória até o fim da execução, independente de mudanças de cena.
O Addressables é a única forma que sei de ter uma referência de um objeto, sem a necessidade de carregá-lo na memória desde o começo, com ele você faz a requisição do carregamento de forma assíncrona e descarrega quando quiser. Pra não carregar tudo e repetir o mesmo problema, você pode implementar um ring buffer como o Marcos sugeriu.
SteveRogers- Instrutor
- PONTOS : 2673
REPUTAÇÃO : 156
Respeito as regras :
Re: Gerenciar carregamento de texturas
SteveRogers escreveu:Foi pra resolver esse tipo de problema que a Unity criou os Addressables.
https://docs.unity3d.com/Manual/com.unity.addressables.html
Se me lembro bem, e faz tempo que vi isso, o SO faz o carregamento dos assets referenciados nele mesmo que você não os use. Pois, diferente de uma cena que é carregada e descarregada, o SO não tem um tempo de execução pré-definido, e como a intenção dele é armazenar textos e coisas leves, talvez até um ícone de um item, etc. acaba fazendo sentido que ele funcione quase como uma pasta Resources, que é carregado na iniciação do programa e é mantido pertinente na memória até o fim da execução, independente de mudanças de cena.
O Addressables é a única forma que sei de ter uma referência de um objeto, sem a necessidade de carregá-lo na memória desde o começo, com ele você faz a requisição do carregamento de forma assíncrona e descarrega quando quiser. Pra não carregar tudo e repetir o mesmo problema, você pode implementar um ring buffer como o Marcos sugeriu.
UUUUU, que massa, não sabia que tinha esse comando.... Não conhecia ele.
Re: Gerenciar carregamento de texturas
Valeu, mais uma coisa para aprender e implementar então. Já tinha ouvido falar de Adressables quando fui atrás de um forma customizada de carregar os SOs, mas me disseram que é algo avançado e meio compliado de mexer, então acabei não indo atrás naquele momento. Por enquanto o consumo de RAM está por volta de 2.5gb, tipo, está alto mas pelo menos é estável. Eu vou acabar lançando o meu próximo alpha deste jeito sabendo que logo a frente eu vou precisar tornar o carregamento de texturas mais eficiente, já que há apenas algumas centenas de variações de uniformes e 10 times por enquanto, ou seja, ainda há muita margem para expansão.SteveRogers escreveu:Foi pra resolver esse tipo de problema que a Unity criou os Addressables.
https://docs.unity3d.com/Manual/com.unity.addressables.html
Se me lembro bem, e faz tempo que vi isso, o SO faz o carregamento dos assets referenciados nele mesmo que você não os use. Pois, diferente de uma cena que é carregada e descarregada, o SO não tem um tempo de execução pré-definido, e como a intenção dele é armazenar textos e coisas leves, talvez até um ícone de um item, etc. acaba fazendo sentido que ele funcione quase como uma pasta Resources, que é carregado na iniciação do programa e é mantido pertinente na memória até o fim da execução, independente de mudanças de cena.
O Addressables é a única forma que sei de ter uma referência de um objeto, sem a necessidade de carregá-lo na memória desde o começo, com ele você faz a requisição do carregamento de forma assíncrona e descarrega quando quiser. Pra não carregar tudo e repetir o mesmo problema, você pode implementar um ring buffer como o Marcos sugeriu.
Me lembrei de outa dúvida, essa acho que não tem jeito mesmo, mas é possível diminuir um pouco o tamanho da build? Tipo, só estou pergutando para confirmar mesmo, considerando que o este projeto precisa de uma grande quantidade de texturas acredito que não tenha muita escapatória...
Re: Gerenciar carregamento de texturas
gabrimo escreveu:Valeu, mais uma coisa para aprender e implementar então. Já tinha ouvido falar de Adressables quando fui atrás de um forma customizada de carregar os SOs, mas me disseram que é algo avançado e meio compliado de mexer, então acabei não indo atrás naquele momento. Por enquanto o consumo de RAM está por volta de 2.5gb, tipo, está alto mas pelo menos é estável. Eu vou acabar lançando o meu próximo alpha deste jeito sabendo que logo a frente eu vou precisar tornar o carregamento de texturas mais eficiente, já que há apenas algumas centenas de variações de uniformes e 10 times por enquanto, ou seja, ainda há muita margem para expansão.SteveRogers escreveu:Foi pra resolver esse tipo de problema que a Unity criou os Addressables.
https://docs.unity3d.com/Manual/com.unity.addressables.html
Se me lembro bem, e faz tempo que vi isso, o SO faz o carregamento dos assets referenciados nele mesmo que você não os use. Pois, diferente de uma cena que é carregada e descarregada, o SO não tem um tempo de execução pré-definido, e como a intenção dele é armazenar textos e coisas leves, talvez até um ícone de um item, etc. acaba fazendo sentido que ele funcione quase como uma pasta Resources, que é carregado na iniciação do programa e é mantido pertinente na memória até o fim da execução, independente de mudanças de cena.
O Addressables é a única forma que sei de ter uma referência de um objeto, sem a necessidade de carregá-lo na memória desde o começo, com ele você faz a requisição do carregamento de forma assíncrona e descarrega quando quiser. Pra não carregar tudo e repetir o mesmo problema, você pode implementar um ring buffer como o Marcos sugeriu.
Me lembrei de outa dúvida, essa acho que não tem jeito mesmo, mas é possível diminuir um pouco o tamanho da build? Tipo, só estou pergutando para confirmar mesmo, considerando que o este projeto precisa de uma grande quantidade de texturas acredito que não tenha muita escapatória...
Diminuir tamanho da build é quase impossível...
Da pra trabalhar com compressão de texturas no seu caso, mas fora isso, não há muito o que fazer. Talvez usar outro formato de textura (A Unity aconselha usar sempre .png)
Mas para ajudar, veja essa referência oficial: https://docs.unity3d.com/Manual/ReducingFilesize.html
Tópicos semelhantes
» Carregamento de caixas
» Carregamento com porcentagem...
» Bug de carregamento de cena
» CENA DE CARREGAMENTO COM IMAGENS
» erro com carregamento de dados
» Carregamento com porcentagem...
» Bug de carregamento de cena
» CENA DE CARREGAMENTO COM IMAGENS
» erro com carregamento de dados
Página 1 de 1
Permissões neste sub-fórum
Não podes responder a tópicos