Loading repository data…
Loading repository data…
elen-c-sales / repository
Este repositório é um estudo do efeito de fogo estilo Doom usando uma tabela de cores (paleta) e uma simulacao discreta de calor. A implementacao foi feita como exercicio de aprendizagem: primeiro entendendo a "fisica" simplificada do fogo, depois adicionando dissipacao e, por fim, o vento.
Este repositorio é um estudo do efeito de fogo estilo Doom usando uma tabela de cores (paleta) e uma simulacao discreta de calor. A implementacao foi feita como exercicio de aprendizagem: primeiro entendendo a "fisica" simplificada do fogo, depois adicionando dissipacao e, por fim, o vento.
Requisitos:
Execucao:
Versao original:
python fire.py
Versao vetorizada:
python vectorizedvolumetricfire.py
| Arquivo | Funcao |
|---|---|
fire.py | Implementa o grid de calor, paleta e renderizacao |
vectorizedvolumetricfire.py | Versão vetorizada usando broadcasting NumPy avançado |
TECHNICAL_DEEP_DIVE.md | Análise técnica detalhada sobre vetorização e otimização |
O segredo deste algoritmo é que não existe uma simulação física de partículas ou fluidos complexos. O "fogo" é apenas uma visualização gráfica de uma matriz de números inteiros sendo atualizada constantemente.
Imagine o fogo como uma planilha onde cada célula possui um valor entre 0 e 36. Este valor representa a temperatura, que é mapeada para uma cor específica no momento da renderização:
| Índice (Temperatura) | Cor Visual (RGB Aproximado) | Estado Simulado |
|---|---|---|
| 36 | Branco (255, 255, 255) | Fonte de calor infinita (Base) |
| 20 a 35 | Amarelo / Laranja | Combustão ativa (Corpo da chama) |
| 1 a 19 | Vermelho / Marrom | Resfriamento e dissipação |
| 0 | Preto (0, 0, 0) | Frio / Vazio (Topo da tela) |
A cada quadro (frame), o algoritmo percorre a matriz e define o valor de um pixel baseado no pixel diretamente abaixo dele. A lógica de propagação segue a fórmula:
Pixel_Atual = Pixel_Abaixo - Decaimento_Aleatório
Isso garante que o calor suba, mas perca intensidade (esfrie) aleatoriamente conforme ganha altura.
| Posição (Origem) | Valor Original | Fator Aleatório (Decay) | Cálculo | Novo Valor (Destino) |
|---|---|---|---|---|
| Abaixo | 36 (Branco) | 0 | 36 - 0 | 36 (Mantém calor) |
| Abaixo | 36 (Branco) | 2 | 36 - 2 | 34 (Esfria levemente) |
| Abaixo | 20 (Laranja) | 3 | 20 - 3 | 17 (Esfria rápido) |
| Abaixo | 2 (Vermelho) | 2 | 2 - 2 | 0 (Apaga) |
O efeito de vento não é físico, mas uma manipulação de matriz. Após calcular a temperatura, o código desloca horizontalmente os valores da matriz.
np.roll com valor -1).O comportamento visual do fogo é controlado por constantes no código:
| Variável | Efeito ao aumentar | Efeito ao diminuir |
|---|---|---|
| LARGURA_FOGO | Maior resolução horizontal (fogo HD). | Visual mais pixelado ("blocadão"/retrô). |
| ALTURA_FOGO | Permite que a chama suba mais antes de ser cortada. | O fogo é cortado abruptamente no topo. |
| Fator de Decay | O fogo fica baixo e apaga rápido. | O fogo sobe até o topo da tela (efeito pilar). |
| Conceito | Implementacao |
|---|---|
| Grid | Matriz ALTURA_FOGO x LARGURA_FOGO |
| Fonte | Ultima linha recebe o valor maximo da paleta |
| Conceito | Implementacao |
|---|---|
| Decaimento | Valor aleatorio de 0 a 2 por celula |
| Efeito | Reduz o calor enquanto ele sobe |
O decaimento pequeno ja e suficiente para criar movimento, porque o ruido muda a cada frame.
O vento e apenas um deslocamento horizontal do grid. Isso puxa as chamas para um lado e cria uma direcao perceptivel.
| Tipo | Implementacao |
|---|---|
| Vento constante | np.roll(..., -1, axis=1) |
| Turbulencia | Deslocamento aleatorio por linha |
| Passo | O que acontece |
|---|---|
| 1 | Gera decaimento aleatorio |
| 2 | Calcula novo calor a partir da linha de baixo |
| 3 | Aplica vento constante e turbulencia |
| 4 | Converte indices em RGB com a paleta |
| 5 | Escala e desenha na janela |
Após a publicação inicial deste projeto, recebi uma pergunta técnica do engenheiro @victorvalentee durante uma discussão sobre otimização:
"Como simular os 3 segundos de fogo sem usar loops?"
Essa pergunta me levou a um estudo aprofundado sobre broadcasting multidimensional, álgebra vetorial e trade-offs entre paralelização espacial vs. temporal em algoritmos com dependência causal.
Criei uma implementação vetorizada (vectorizedvolumetricfire.py) que:
Para detalhes sobre a implementação, conceitos de broadcasting avançado, benchmarks e discussão sobre limitações teóricas, veja:
Este documento inclui:
Alavancado pela proposta e implementação no PR #1 do engenheiro @victorvalentee, implementamos uma abstração avançada que troca equivalência física por equivalência perceptual, alcançando speedup de 2.5x.
Para detalhes sobre a proposta original, fundamentação teórica e implementação com particle streams (documentos de autoria do @victorvalentee), veja:
** decay_abstraction/DECAY_MATRIX_PROPOSAL.md**
Para executar a comparação de performance e gerar GIF lado-a-lado, use:
uv run decay_abstraction/compare_approaches.py
** decay_abstraction/WHY_USE_UV.md** explica o uso do uv para gerenciamento de dependências.