Ir para conteúdo
  • Quem está por aqui   0 membros estão online

    • Nenhum usuário registrado visualizando esta página.

Prompt para melhoria do fps Tmproject dx9


azkar
 Compartilhar

Posts Recomendados

Prompt para melhoria do fps e identificação de pilhas de acúmulo na treenode principal.

 

O seguinte prompt foi gerado por Sherlin em nosso grupo do wpp após a explicação do problema que identifiquei nos acúmulos de pilhas de renderização.

O mesmo relata que a IA conseguiu melhorar bastante o FPS do cliente dx9 chegando a 180fps.

 

Ressalva 1: A solução que implementei em meu cliente não foi desenvolvida com esse prompt, portando, criem um backup de seu projeto para que caso algo de errado possam retornar ao ponto de estabilidade.

 

Ressalva 2: Moderadores, por gentileza mover o tópico para a área correta caso não seja essa.

 

"Estou trabalhando na source do cliente de WYD e preciso que você faça uma análise profunda do sistema de renderização para identificar e corrigir um possível acúmulo progressivo de objetos, efeitos, partículas, nós de cena, buffers ou draw calls.

 

O problema aparece principalmente quando existem muitos jogadores, monstros, magias, auras, flechas e efeitos simultaneamente, como em guerras/eventos com muita gente.

 

NÃO quero uma solução superficial como simplesmente diminuir gráficos, remover efeitos ou colocar um limite global baixo de partículas.

 

Quero encontrar a causa estrutural do problema.

 

CONTEXTO DO PROBLEMA

 

O cliente possui uma estrutura de cena onde vários elementos do mundo são registrados/processados:

 

* terreno;

* prédios;

* árvores;

* personagens;

* NPCs;

* monstros;

* equipamentos;

* partículas;

* magias;

* auras;

* projéteis;

* flechas;

* efeitos temporários;

* outros objetos renderizáveis.

 

Suspeito que durante a execução do cliente algum desses elementos esteja permanecendo registrado na estrutura de cena, em listas, arrays, TreeNodes, filas de renderização, buffers ou estruturas auxiliares mesmo depois de deixar de ser necessário.

 

Isso pode causar crescimento progressivo do trabalho realizado por frame.

 

Quero que você investigue principalmente:

 

1. SCENE TREE / TREE NODE

 

Encontre onde a árvore/estrutura de cena é criada.

 

Identifique:

 

* classe da Scene;

* TreeNode/SceneNode;

* filhos de cada Node;

* listas de objetos renderizáveis;

* funções Add/Insert/Register;

* funções Remove/Delete/Destroy/Release;

* iteração da árvore durante Render/Draw/Update.

 

Verifique se elementos temporários são corretamente removidos da árvore.

 

Procure especificamente casos onde:

 

AddNode()

 

RegisterObject()

 

AddEffect()

 

AddParticle()

 

AddChild()

 

ou equivalentes são chamados repetidamente sem uma remoção correspondente.

 

Não suponha os nomes acima; encontre os nomes reais utilizados pelo projeto.

 

2. CICLO DE VIDA DOS OBJETOS

 

Mapeie o ciclo completo:

 

Create

→ Register

→ Update

→ Render

→ Expire

→ Remove

→ Destroy/Release

 

Para:

 

* partículas;

* efeitos;

* auras;

* magias;

* projéteis;

* flechas;

* objetos temporários.

 

Quero saber se algum objeto expirado continua:

 

* dentro de vector/list/map;

* ligado a um TreeNode;

* sendo atualizado;

* sendo percorrido pelo renderer;

* enviando draw calls;

* mantendo Vertex Buffer;

* mantendo Index Buffer;

* mantendo textura;

* mantendo referência para algum recurso gráfico.

 

3. ACÚMULO DE PARTÍCULAS/EFEITOS

 

Procure funções relacionadas a:

 

Particle

Effect

Magic

Aura

Projectile

Arrow

MeshEffect

VisualEffect

Emitter

 

Descubra:

 

* onde são criados;

* onde são atualizados;

* como seu lifetime é controlado;

* onde são destruídos;

* onde são removidos das estruturas de renderização.

 

Verifique especialmente erros como:

 

if (effect->life <= 0)

delete effect;

 

mas o ponteiro continuar armazenado em alguma lista.

 

Ou:

 

effect->enabled = false;

 

mas ele continuar dentro da lista que é percorrida a cada frame.

 

Desabilitar um objeto não significa necessariamente removê-lo da estrutura.

 

4. DRAW CALLS

 

Localize o loop principal de renderização.

 

Quero saber quantos Render()/Draw() potencialmente são executados por frame.

 

Procure oportunidades SEGURAS para:

 

* evitar renderização de objetos invisíveis;

* frustum culling;

* distance culling;

* evitar processamento de efeitos expirados;

* evitar state changes redundantes;

* reduzir chamadas repetidas de SetTexture;

* reduzir SetRenderState repetido;

* reduzir SetTransform repetido;

* agrupar objetos que utilizam o mesmo material/textura quando possível.

 

NÃO faça batching agressivo antes de entender como o renderer funciona.

 

Primeiro encontre o gargalo real.

 

5. CULLING

 

Verifique se o cliente está renderizando objetos:

 

* atrás da câmera;

* muito longe do jogador;

* fora do frustum;

* completamente fora da tela.

 

Se não existir culling adequado, proponha uma implementação compatível com a arquitetura atual.

 

Separar:

 

Update lógico

 

de

 

Render visual.

 

Um objeto importante para gameplay pode continuar recebendo Update, mas não precisa gerar draw call quando estiver fora da área visível.

 

6. OBJECT POOL

 

Analise se partículas, projéteis e efeitos estão sendo constantemente criados/destruídos com new/delete.

 

Se isso estiver acontecendo, avalie implementar Object Pool.

 

Exemplo conceitual:

 

ParticlePool

EffectPool

ProjectilePool

 

Mas NÃO implemente pool antes de descobrir o ciclo de vida real das classes.

 

O pool deve reutilizar memória sem manter objetos ativos dentro da Scene Tree.

 

7. CONTADORES DE DEBUG

 

Antes de realizar grandes alterações, quero instrumentação.

 

Adicione, preferencialmente apenas em DEBUG, contadores como:

 

SceneNodes ativos

 

Characters ativos

 

Monsters ativos

 

Effects ativos

 

Particles ativas

 

Projectiles ativos

 

RenderObjects processados

 

RenderObjects realmente desenhados

 

DrawCalls por frame

 

Objetos descartados por distância

 

Objetos descartados pelo frustum

 

Effects criados por segundo

 

Effects destruídos por segundo

 

Particles criadas por segundo

 

Particles destruídas por segundo

 

O objetivo é descobrir se algum contador cresce continuamente sem retornar ao normal.

 

Exemplo esperado:

 

Players: 80

SceneNodes: 1250

Effects: 520

Particles: 3100

DrawCalls: 1800

 

Depois que a batalha acabar:

 

Players: 5

SceneNodes: 300

Effects: 20

Particles: 80

DrawCalls: 350

 

Se Effects/Particles/SceneNodes continuarem crescendo indefinidamente, encontre de onde vem o vazamento/acúmulo.

 

8. NÃO CONFUNDIR CPU COM GPU

 

Analise separadamente:

 

CPU:

 

* tamanho das listas;

* Scene Tree traversal;

* Update;

* animações;

* partículas;

* ordenação;

* criação/destruição;

* chamadas de Render.

 

GPU/API gráfica:

 

* draw calls;

* Vertex Buffers;

* Index Buffers;

* texturas;

* state changes;

* locks/unlocks;

* criação de recursos;

* liberação de recursos.

 

Não quero explicações genéricas dizendo apenas que "a GPU acumula draw calls".

 

Normalmente os comandos são enviados novamente a cada frame.

 

Quero descobrir se o CLIENTE está mantendo estruturas que crescem e, consequentemente, aumentando o número de comandos enviados por frame.

 

9. DIRECTX

 

Identifique qual API essa source utiliza, por exemplo:

 

DirectX 7

DirectX 8

DirectX 9

OpenGL

 

e trabalhe especificamente com ela.

 

Se for Direct3D, procure chamadas como:

 

DrawPrimitive

 

DrawIndexedPrimitive

 

SetTexture

 

SetRenderState

 

SetTextureStageState

 

SetTransform

 

SetFVF

 

SetVertexShader

 

SetStreamSource

 

CreateVertexBuffer

 

CreateIndexBuffer

 

Lock

 

Unlock

 

Release

 

ou os equivalentes existentes na versão utilizada.

 

Não invente uma modernização para DirectX 11/12.

 

Preciso manter compatibilidade com o renderer atual do WYD.

 

10. VERIFICAR VAZAMENTO DE RECURSOS

 

Procure recursos criados mas não liberados.

 

Especialmente:

 

VertexBuffer

 

IndexBuffer

 

Texture

 

Surface

 

Mesh

 

Particle

 

Effect

 

SceneNode

 

Object

 

Procure assimetrias do tipo:

 

Create / Release

 

new / delete

 

new[] / delete[]

 

Add / Remove

 

Register / Unregister

 

Load / Unload

 

Create / Destroy

 

11. NÃO ALTERAR GAMEPLAY

 

Não modifique:

 

* lógica de combate;

* alcance das habilidades;

* posição dos personagens;

* velocidade;

* ataque;

* movimentação;

* networking;

* sincronização;

* lógica do servidor.

 

A otimização deve ser exclusivamente no cliente/renderização.

 

12. NÃO MASCARAR O PROBLEMA

 

Não faça simplesmente:

 

if (effects.size() > 100)

effects.clear();

 

Isso mascara o bug.

 

Se existir um crescimento incorreto, encontre QUEM adiciona os objetos e QUEM deveria removê-los.

 

Quero corrigir a origem.

 

13. PROCESSO DE ANÁLISE

 

Não altere arquivos imediatamente.

 

Primeiro faça uma busca global no projeto e apresente:

 

A) arquitetura encontrada;

 

B) arquivos envolvidos;

 

C) classes envolvidas;

 

D) caminho completo de criação até renderização;

 

E) caminho completo de destruição;

 

F) possível ponto de acúmulo;

 

G) evidências no código;

 

H) correção proposta;

 

I) riscos da alteração.

 

Depois disso faça as alterações.

 

14. AO MODIFICAR

 

Para cada alteração mostre:

 

Arquivo:

Função:

Problema:

Causa:

Alteração:

Impacto esperado:

 

Mostre o código ANTES e DEPOIS quando possível.

 

Não substitua arquivos inteiros sem necessidade.

 

Faça alterações pequenas e verificáveis.

 

15. OBJETIVO FINAL

 

Quero que uma situação como:

 

100 jogadores

 

* monstros

* centenas de magias

* milhares de partículas

 

possa gerar uma carga alta enquanto estiver acontecendo, mas que depois que os elementos desaparecerem o número de objetos processados e draw calls RETORNE para valores normais.

 

Não pode existir degradação progressiva do FPS simplesmente porque o cliente ficou aberto durante muito tempo ou participou de várias guerras.

 

O comportamento esperado é:

 

Carga sobe durante batalha

→ efeitos expiram

→ objetos são removidos

→ estruturas diminuem

→ draw calls diminuem

→ uso de CPU/GPU volta próximo do normal.

 

IMPORTANTE:

 

Não faça suposições baseadas apenas nos nomes tradicionais de engines modernas.

 

Essa é uma source antiga de MMORPG.

 

Encontre as estruturas REAIS existentes no projeto e adapte a solução à arquitetura encontrada.

 

Comece fazendo uma busca no projeto por termos relacionados a:

 

Render

Draw

Scene

Node

Tree

Effect

Particle

Magic

Aura

Projectile

Arrow

Add

Remove

Delete

Destroy

Release

Update

DrawPrimitive

DrawIndexedPrimitive

VertexBuffer

IndexBuffer

 

Depois me apresente o mapa do pipeline real encontrado antes de propor a correção definitiva."

Editado por azkar
Erros de escrita.
  • Curtir 2
  • Amei 1
Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar Agora
 Compartilhar

×
×
  • Criar Novo...

Informação Importante

Nós fazemos uso de cookies no seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies , caso contrário, vamos supor que você está bem para continuar.