Céu e Fundo de Janela
Fonte: room-at-dawn (MIT), de src/scene/sky.js, src/scene/parts/exterior.js.
Ideia central: o céu é descrito apenas uma vez.
- O baker usa um céu analítico: um gradiente do horizonte ao zênite, com um halo na direção do sol.
- A esfera celeste visível adiciona nuvens sobre o mesmo gradiente, mas a luminância média deve permanecer próxima à do gradiente: o céu limpo entre nuvens é mais escuro que a média, as bordas das nuvens são mais claras, e o centro das nuvens é aproximadamente igual.
- Assim, o céu visto pela janela corresponde à luz que ilumina o interior.
measureDomeé usado para verificar isso.
Arquivos
| Caminho | Conteúdo |
|---|---|
scripts/sky.js | SKIES (amanhecer, dia, nublado, entardecer), skyRadiance (mesma fórmula do worker do threejs-baked-gi), bakeCfg, skyDome, SKY_U (uTime), skyLights, skyEnvironment, measureDome |
scripts/backdrop.js | windowVisibility (visibilidade da abertura da janela e LOD), hazePatch (névoa atmosférica, preserva patches originais do shader), grassTexture, roofTexture, windowTexture, crownTexture, Soup, houses, lawn, gravelPath, hedge, crownWall |
example/ | Quarto no segundo andar (piso 5.5 m acima do jardim) com vista para: gramado, caminho, sebes, três casas, árvores, parede de árvores ao fundo |
example/preview*.jpg | Quatro tipos de céu vistos de dentro; da janela, olhando para cima; vista externa |
references/sky.md | Cada camada do shader do céu, parâmetros padrão, como ajustar, como conectar com o baker |
references/backdrop.md | Lógica de visibilidade, névoa, cada elemento do fundo, dados de desempenho, problemas encontrados, portabilidade para outros engines |
As árvores do exemplo usam threejs-procedural-vegetation (caminho relativo ../../threejs-procedural-vegetation/).
Executar o Exemplo
cd <pasta do skill>/.. && python3 -m http.server 5426 --bind 127.0.0.1
# http://127.0.0.1:5426/threejs-sky-backdrop/example/
(<pasta do skill> é o diretório base exibido ao carregar este skill; quando instalado como plugin, fica em ~/.claude/plugins/cache/)
?sky=dawn|day|overcast|golden: Preset do céu.?cam=window|wide|up|out: Do quarto olhando para fora / da janela / olhando para cima / vista externa.?cull=0: Desativa corte de visibilidade (para comparação).?t=5: Tempo fixo, nuvens não se movem.
window.__sky contém tempo de processamento, número de triângulos, número de folhas e a razão da esfera celeste com o céu analítico.
Uso
import { SKIES, skyDome, bakeCfg, skyLights, skyEnvironment, measureDome, SKY_U } from './scripts/sky.js';
const S = SKIES.dawn;
scene.add(skyDome(S)); // Com baker: display 0.3 (padrão); externo: skyDome(S, { display: 1 })
const cfg = { ...bakeCfg(S), portal, room }; // Passar para runBake do threejs-baked-gi
// Cena sem baker:
const { sun, hemi } = skyLights(S); scene.add(hemi); if (sun) scene.add(sun, sun.target);
scene.environment = skyEnvironment(renderer, S);
console.log(measureDome(renderer, S)); // ratio 0.85–1.15
renderer.setAnimationLoop((ms) => { SKY_U.uTime.value = ms / 1000; ... });
Regras Obrigatórias
- O céu é descrito apenas uma vez: baker, esfera celeste e luzes são gerados a partir do mesmo preset. Se alterar a cor do céu, precisa re-hornear.
- Após ajustar nuvens, execute
measureDome. Ela renderiza a esfera celeste em um float cube map, calcula a média ponderada por cosseno do hemisfério superior e compara com o céu analítico.- A razão deve estar entre 0.85 e 1.15; caso contrário, o céu visto não corresponderá à luz que ilumina o interior.
- Com
{ pure: true }, desenha apenas o gradiente; o resultado deve ser exatamente 1.000, confirmando que a medição está correta.
- A cor das nuvens é luminância absoluta, na mesma unidade do céu, não um multiplicador. Testei escalonar com o gradiente, e a razão do amanhecer caiu para 0.73; por isso voltei à implementação original.
- Em interiores horneados, a esfera celeste deve ser desenhada mais escura (
display~0.3). A exposição é ajustada para o interior; desenhar o céu com brilho real resultaria em área branca e sem cor – isso não afeta a luminância usada para iluminação. - Construa apenas o que é visível.
windowVisibilityusa múltiplas posições de olho dentro do quarto, projetando através da abertura da janela com espessura.- Folhas não visíveis: retorna 0 no
lodAtdo skill de vegetação, mantendo apenas alguns cartões grandes para que a sombra ainda exista no baker. - Folhas visíveis apenas obliquamente: retorna 1, tornando-se mais esparsas.
- Folhas não visíveis: retorna 0 no
- Adicione
hazePatchao fundo. Para distâncias acima de 10 m, desbota em direção à cor do horizonte; caso contrário, casas e árvores distantes parecerão tão escuras e saturadas quanto as próximas, como adesivos.
Benchmark (RTX 4090, Chrome headless, 1280×800)
| Item | Valor |
|---|---|
| Esfera celeste ÷ Céu analítico | amanhecer 0.934, dia 1.080, nublado 1.034, entardecer 1.034; modo pure 1.000 |
| Fundo (grama, caminho, sebes, casas, parede de árvores) | 31–34 ms |
| Árvores (4 principais, 8 de médio alcance, 26 distantes) | geração 0.14–0.16 s, malha 0.31 s |
| Corte de visibilidade | Folhas 117.808 → 97.589 (−17%), triângulos 425k → 383k. A economia principal vem de duas árvores rentes à parede externa, ao lado da janela |
| Mapa de ambiente do céu + duas medições | ~0.09 s |