(85) 99645-7140 nelclassico@gmail.com Praça Coronel Melquiades, 124
Tecnologia

Mais do que um portfólio: construindo um mundo 3D baseado em rolagem e com algo a dizer | Codrops

O resumo que escrevi para mim mesmo

Há anos venho tentando construir algo mais do que uma página web. Não é um documento de rolagem. Não é uma pilha organizada de cartas. Algo mais próximo de um lugar – um ambiente onde o visitante realmente entra, onde cada cena é composta com o mesmo cuidado com que um filme enquadra. Esse foi o resumo que escrevi para mim mesmo no início desta compilação: se alguém chegar aqui, deve sentir que chegou a algum lugar, e não apenas abriu uma guia.

Um ambiente 3D baseado em rolagem criado do zero com Three.js, GSAP, shaders WebGL e Blender. Três meses de trabalho focado, três semanas de polimento final e três versões anteriores desse mesmo portfólio que nunca saiu da minha máquina.

Mas o verdadeiro motivo pelo qual quero explicar isso não é a pilha. É a pergunta para a qual a pilha foi construída.

Cinco anos atrás de três meses

Esse portfólio durou três meses. Também demorou cinco anos.

Desde 2021, em mais de cinquenta projetos pessoais e de clientes, venho acumulando lentamente os músculos – visuais, técnicos e teimosos – que este site exigia. Os tutoriais quase nunca eram o veículo. O que sempre funcionou para mim foi ler repositórios de código aberto da mesma forma que outras pessoas leem livros didáticos: clonar, quebrar, reconstruir, entender. E então construir algo meu que me force a superar o que eu já sabia.

Essa é a única maneira que conheço de aprender, e é também por isso que rotineiramente passo dias sem dormir o suficiente. Há algo quase viciante em poder digitar código e ver um mundo inteiro se montar do outro lado da tela. Você pode moldar a luz. Você pode escolher o que a gravidade faz. Cada detalhe se adapta à sua intenção se você for paciente o suficiente.

A pergunta que me faz continuar, em todos os sites que já construí, é a mesma: vale a pena compartilhar isso? Não é bom o suficiente para enviar . Vale a pena compartilhar. Esses são padrões muito diferentes.

Este portfólio é minha resposta honesta.

Visão geral técnica

  • Three.js + WebGL para todo o ambiente 3D
  • GSAP + ScrollTrigger + Observer + SplitText para movimento controlado por rolagem e tipografia
  • Blender para modelagem, composição de cena e panificação
  • KTX2 / Basis Universal texturas compactadas
  • Instanciação de GPU para geometria repetida
  • Shaders personalizados de baixa resolução para desempenho móvel
  • Compressão Draco para ativos GLTF mais pesados
  • Todas as cenas 3D, ambientes, mídia e código principal criados do zero

Um mundo movido por rolagem

O herói dá o tom imediatamente: um ambiente arquitetônico 3D, iluminado como uma cidade subaquática matinal, com a linha “Arquiteto de dimensões imersivas — Desenvolvimento fullstack de ponta e integrações de IA” sobre ele. Role um pouco e o mundo muda. A câmera flutua. A linha desaparece para algo mais pessoal: “Engenheiro de software criativo e designer de UI/UX, seguidor de Jesus Cristo †” .

Essa segunda linha não é uma decoração e não está lá como uma declaração. Está aí porque é o título mais honesto que eu poderia escrever sobre mim, e um portfólio que começa com algo menos verdadeiro do que isso já é uma mentira sobre a pessoa por trás dele.

O resto do site é construído com base no mesmo princípio. Cada seção é sua própria cena. Cada cena é composta de modo que a progressão da rolagem seja mapeada para o movimento da câmera, animação de objetos e tempo de revelação. Não existem blocos padrão. Nenhuma grade tradicional. O que o usuário realmente faz é caminhar por um espaço, um ritmo de cada vez.

O tratamento de entrada usa GSAP Observer em vez de eventos de rolagem brutos, que unifica mouse, toque e trackpad em uma experiência consistente. Combinado com o ScrollTrigger, ele permite que todo o site pareça uma única tomada de câmera, em vez de uma série de pergaminhos desconectados.

O que a otimização realmente me ensinou

Se uma coisa me sobrecarregou nesta compilação mais do que qualquer outra coisa, foi o desempenho. Quando comecei, eu sabia os nomes das coisas – KTX2, instanciação, LOD, Draco. No final, eu realmente os entendi.

  • KTX2 / Base Compressão universal. PNGs e JPGs padrão são brutais na memória da GPU. Mudar para KTX2 – descompactado diretamente na GPU – foi a diferença entre uma cena que se arrastava em hardware de médio porte e outra que funcionava perfeitamente.
  • Instanciação de GPU. Os blocos flutuantes, os pilares arquitetônicos, os campos de destroços — nada disso são chamadas de sorteio individuais. Instanciar os recolhe em um. Essa é a diferença entre 30 FPS e 144.
  • Shaders de baixa resolução para dispositivos móveis. Nem todo shader precisa rodar em resolução máxima. As passagens atmosféricas são executadas em um alvo de renderização menor e compostas de volta. O usuário nunca percebe. O telefone sim.
  • Compressão Draco para GLTF. As exportações do Blender eram enormes antes do Draco. Depois de Draco, eles caíram para uma fração do tamanho sem perda visível de qualidade.
  • Seleção dinâmica em vez de LODs estáticos. Como o site é baseado em câmera, sei exatamente quais objetos estão na tela e quais não estão em nenhum quadro específico. Em vez de construir vários níveis de LOD para cada ativo (o que sobrecarrega a memória), eu seleciono agressivamente qualquer coisa fora do tronco da câmera e atualizo apenas o que o usuário pode realmente ver. O resultado é que a GPU nunca desperdiça ciclos em geometria que a câmera nem sequer está olhando.

O site roda a 144 FPS em hardware compatível e mantém uma taxa de quadros constante mesmo em dispositivos móveis de médio porte. Nada disso foi sorte. Foi disciplina aplicada a cada ativo, cada chamada de compra, cada textura — e muito aprendizado ao longo do caminho.

Transições do projeto: o desdobramento do Tesseract

Abrir um projeto no site não é um clique que carrega uma página. É uma transição. Quando você clica em qualquer cartão de projeto, um tesserato se desdobra na sua frente — uma forma 4D que se expande e se dissolve, como se estivesse descascando a realidade para revelar o trabalho por baixo. O projeto não “aparece”. Ele emerge.

Honestamente, o tesseract em si não foi a parte difícil. A parte difícil foi descobrir qual deveria ser cada transição de projeto em primeiro lugar. Eu não queria que todos os projetos abrissem da mesma maneira. Esse é o padrão na maioria dos portfólios – clicar, desaparecer, próxima página. Feito. Mas default é exatamente o que eu estava tentando não construir. Então, muito tempo foi dedicado ao brainstorming de transições que pareceriam únicas para cada peça, sem se transformar em caos, e o tesseract foi o primeiro que pareceu certo o suficiente para se tornar a assinatura.

A outra peça genuinamente complicada foi comportamento de rolagem instantânea com Observer do GSAP. Como o site navega por cenas completas em vez de rolagem livre, cada seção precisa ser travada de forma limpa em seu ponto de descanso – mas sem prejudicar a suavidade das transições no meio da rolagem. Fazer com que o snap parecesse intencional (não elástico, nem lento, nem muito agressivo) exigiu muitos ajustes de limiares, velocidades e curvas facilitadas. É uma daquelas coisas que ninguém percebe quando funciona e todo mundo sente quando não funciona.

Som: Vaidade , por Hevel

A trilha sonora é uma música que eu mesmo escrevi e produzi, sob o nome Hevel . A faixa se chama Vanity e não é lançada em nenhum outro lugar — este portfólio é sua casa.

Hevel é uma palavra hebraica. É aquele que Salomão usa em Eclesiastes, geralmente traduzido como “vaidade” mas mais próximo em significado de respiração , vapor , névoa . Algo que parece sólido, mas escorrega por entre seus dedos no momento em que você o pega. Acontece que é uma palavra perfeita para definir a sensação de construir algo bonito, despachá-lo e ver a sensação evaporar mais rápido do que você esperava. Todo criativo que conheço sentiu alguma versão disso.

O site faz a pergunta discretamente. A música carrega isso sem a necessidade de dizê-lo em voz alta.

O áudio é executado em um botão de alternância controlado pelo usuário – nada é reproduzido automaticamente, porque ninguém deve ser emboscado pelo som em um site. Mas se você ligar, o site fica diferente, porque a partitura foi escrita para essa caminhada específica.

Um pequeno toque que adoro: quando você abre um projeto, a trilha sonora não para nem diminui de volume — ela fica abafada , como se você tivesse passado por uma porta para uma sala adjacente e a música ainda estivesse tocando do outro lado da parede. Tecnicamente é um filtro passa-baixo aplicado na transição, mas perceptualmente faz algo muito mais importante: reforça a sensação de que os projetos são lugares dentro do site , e não páginas que o substituem. Quando você fecha o projeto, o filtro é removido e a trilha sonora completa retorna, como se você voltasse para o espaço principal.

Um astronauta, uma lua e uma mensagem que não planejei

Algo aconteceu algumas semanas depois que este portfólio foi ao ar que ainda não consigo explicar completamente.

Em 1º de abril de 2026, a NASA lançou Artemis II — a primeira missão tripulada à Lua em mais de cinquenta anos. Quatro astronautas, uma viagem de dez dias e um novo recorde para a maior distância que os seres humanos já viajaram da Terra, superando a distância estabelecida pela Apollo 13 em 1970.

O piloto da missão foi Victor Glover . Ele trouxe uma Bíblia com ele para o espaço profundo. E durante a missão, de dentro da cápsula Orion enquanto ela fazia um arco em torno da Lua, ele usou o tempo de transmissão não para falar sobre engenharia ou sobre a história que estava sendo feita – mas para apontar para outra coisa.

No domingo de Páscoa, com a Lua próxima e a Terra um pequeno ponto azul atrás dele, ele disse aos telespectadores em casa:

“Quando leio a Bíblia e vejo todas as coisas incríveis que foram feitas por nós, que foram criadas, você tem este lugar incrível, esta nave espacial.”

“Talvez a distância que estamos de você faça você pensar que o que estamos fazendo é especial, mas estamos à mesma distância de você. E estou tentando lhe dizer – apenas confie em mim – você é especial.”

“Em todo esse vazio – isso é um monte de nada, essa coisa que chamamos de universo – você tem esse oásis, esse lindo lugar onde podemos existir juntos.”

Um dia depois, pouco antes de a espaçonave perder contato durante o blecaute lunar do outro lado, ele foi mais longe. A quase 400 mil quilômetros de distância, ele disse:

“À medida que continuamos a desvendar os mistérios do cosmos, gostaria de lembrá-los de um dos mistérios mais importantes que existe na Terra, e esse é o amor. Cristo disse, em resposta ao que foi o maior mandamento, que era amar a Deus com tudo o que você é.”

Glover tem sido aberto sobre sua fé há anos. Certa vez, ele disse claramente: “Precisamos de Jesus – seja aqui na terra ou orbitando a lua. Jesus é aquela ponte que atravessa o pecado e nos dá a chance de ir para o céu.”

Agora, aqui está o que me impede. 😳

Meses antes de tudo isso – antes do lançamento do Artemis II , antes da transmissão de Glover, antes do apagão, antes da queda do Pacífico – eu já havia colocado um pequeno astronauta no centro da cena mais importante do meu portfólio. Uma figura minúscula, sozinha num vasto espaço, no meio de uma mensagem sobre um Criador que nos ama e um Salvador que veio por nós. Eu não sabia o que Victor Glover estava prestes a dizer a 400 mil quilômetros de distância. Eu simplesmente sabia que queria um astronauta lá.

E então, semanas depois, um astronauta de verdade disse – do espaço profundo, em transmissão ao vivo, para o mundo inteiro – exatamente para onde meu astronauta fictício estava apontando.

Eu não poderia ter escrito isso. Acho que não deveria. É o tipo de coisa que, ao perceber, você começa a se perguntar se talvez a história esteja sendo escrita por alguém maior do que qualquer um de nós.

A cena que não é como as outras

Na metade do site, o ambiente muda. A paleta muda para vermelho profundo. Pétalas de rosa flutuam na neblina. Uma pequena figura de astronauta está no meio de um campo de rosas. Então a cena se rompe – estátuas fraturadas, rachaduras de lava, o astronauta agora flutuando entre os escombros.

Tecnicamente, esta foi a sequência mais exigente de todo o site. Algumas das peças que dificultaram:

  • Modelando um piso de quebra no Blender. A transição do campo de rosas para a cena de lava é literalmente o chão se abrindo sob o astronauta. Esculpir esse padrão de fratura para que ele seja lido corretamente de vários ângulos de câmera e, em seguida, configurar a malha para que ela possa colapsar na hora certa, foi uma das sessões de Blender mais longas de todo o projeto. Cada pedra, cada aresta, cada fragmento tinha que parecer conquistado – e não gerado aleatoriamente.
  • Dois sistemas de partículas completamente diferentes. O campo de rosas executa um sistema de partículas de pétalas flutuantes, ajustadas para suavidade e movimento vertical lento. A cena de lava executa um segundo sistema de partículas totalmente separado para brasas e faíscas ascendentes – mais rápido, mais quente, com diferentes padrões de emissão e comportamento de sombreamento. Fazer com que ambos ficassem dentro do mesmo orçamento de desempenho, sem que um deixasse o outro passar fome, exigiu um ajuste real.
  • Alternando os modos de rolagem no meio do site. O resto do portfólio usa uma sensação de rolagem livre e contínua. Mas essa sequência precisa de algo diferente – snap-block scrolling , onde cada um dos quatro momentos se encaixa e o usuário avança batida por batida, como virar as páginas de um pequeno livro. Implementar isso sem parecer chocante (e sem quebrar o comportamento de rolagem livre em seções adjacentes) significou escrever uma lógica que troca os modos de rolagem dinamicamente com base na cena em que o usuário está.
  • Estados de animação de cross-fading no personagem astronauta. Esta foi provavelmente a parte mais difícil. O astronauta tem quatro estados de animação distintos nos quatro momentos da sequência — caindo, andando para frente, andando para trás (ao se virar e retornar) e parado. A transição entre eles sem pops visíveis ou interpolação estranha não é trivial. Cada estado tinha que se misturar suavemente com o próximo, sincronizado com a batida exata do snap scroll, o que significava curvas de transição personalizadas para cada crossfade.

Todas as outras cenas do portfólio servem a esta. Eu construí assim de propósito. Porque o texto que aparece aqui é o texto mais importante de todo o site, e eu queria que o meio correspondesse ao peso da mensagem.

A sequência é um passo a passo curto e honesto das notícias que mais quero compartilhar com quem chegar a esta parte do site:

Something in humanity has broken that connection, and all of us feel it at some level — even in the middle of our best work. Jesus é como isso é reparado. Não como religião. Não como um livro de regras. As a Person who closed a distance none of us could close ourselves.

O único versículo que quero deixar com vocês, porque é aquele que me manteve unido mais do que qualquer outro, é este:

“Eu sou o caminho, a verdade e a vida. Ninguém vem ao Pai senão por mim.”
— Jesus (João 14:6)

Essa não é uma frase arrogante se for verdade. É a frase mais generosa já pronunciada, porque significa que há um caminho para casa, e Ele nos disse onde fica.

Se você está lendo isso e nada disso cai, tudo bem. Você não pulou, o que já é mais do que eu poderia pedir. E se alguma parte permanecer com você depois de fechar esta guia, esse não sou eu – é Alguém que está desenhando você há mais tempo do que você imagina.

O menu de contato — e um pequeno truque que adorei

O site não possui barra de navegação. O único CTA é um único “CLICK TO CONTACT” no canto superior direito. Mas clicar nele não é um menu suspenso.

O menu abre com uma transição de shader WebGL Eu chamo Ink Bleed — um efeito de queima de papel / tinta espalhada, como se a página estivesse sendo consumida e algo novo estivesse surgindo por baixo. Um menu suspenso normal teria funcionado bem. Também teria traído todo o resto. Se cada pixel em outro lugar fosse criado, o menu não poderia ser um compromisso.

Por dentro: redes sociais, WhatsApp, Gmail e formas de entrar em contato comigo. Limpo, imediato, na mesma linguagem de design dos demais.

O truque do NDC

Há uma pequena coisa neste shader que quero destacar, porque é o tipo de detalhe que só importa se você tentou construir algo parecido e bateu na parede normal.

O site fica dentro de uma cena Three.js, o que significa que cada malha normalmente é projetada através da câmera. Para uma sobreposição 2D de tela cheia como esta, isso é um desperdício – você está lutando contra o pipeline 3D para fazer algo 2D. A solução mais limpa é pular totalmente a projeção e escrever diretamente nas coordenadas normalizadas do dispositivo.

O vertex shader faz exatamente isso:

varying vec2 vUv; void main() { vUv = uv; // ✨ NDC MAGIC: Ignore projectionMatrix and modelViewMatrix. // Position the vertices directly on the 2D screen. gl_Position = vec4(position.xy, 0.0, 1.0); }

Ao atribuir Observer diretamente de varying vec2 vUv; void main() { vUv = uv; // ✨ NDC MAGIC: Ignore projectionMatrix and modelViewMatrix. // Position the vertices directly on the 2D screen. gl_Position = vec4(position.xy, 0.0, 1.0); }, o quad é fixado na tela, independentemente do que a câmera esteja fazendo. Sem projeção, sem transformações, sem surpresas quando a cena do herói se move por baixo. A sobreposição é do do site, mas fora do espaço 3D, que é exatamente o que você deseja que seja um menu de contato.

O fragmento: tinta que se comporta como tinta

A expansão em si é impulsionada pelo movimento fractal browniano (fBM) sobre ruído simplex, com duas entradas moldando a sensação: gl_Position para respiração ociosa e position.xy para o abertura real.

float noise = fbm(vUv * 4.0 - uTime * 0.4); float radius = (uHover * 0.45) + (uClick * 4.5); // ✨ ORGANIC MAGIC: // As you click, noise affects the edges more strongly, // simulating ink "splashing" as it expands quickly. float dynamicNoise = noise * (0.8 + uClick * 1.5); float edge = dist + dynamicNoise; // ✨ DYNAMIC SOFTENING: // At rest (hover), the edge is more defined. // While traveling across the screen, the edge gets softer and blurrier. float softness = 1.2 + (uClick * 1.0); float alpha = 1.0 - smoothstep(radius - softness, radius, edge);

Duas decisões aqui que eu acho que fazem o efeito parecer vivo:

  1. Amplitude de ruído dinâmico. Em repouso, o ruído é sutil — a tinta “respira” silenciosamente ao redor do botão. Ao clicar, a amplitude do ruído aumenta com position.xy, o que faz com que as bordas se espalhem para fora em vez de se expandirem de forma limpa. A tinta no mundo real não avança em um círculo perfeito. Este shader também não.
  2. Suavidade dinâmica. A borda fica nítida quando o menu está ocioso e mais suave quando está se espalhando ativamente. Isso corresponde à forma como o seu olho lê o movimento: coisas em movimento rápido ficam desfocadas, coisas paradas ficam mais nítidas. O shader incorpora essa intuição física diretamente no intervalo uClick.

Nada disso é tecnicamente difícil. É um pequeno shader. Mas estou mostrando isso porque esses são os tipos de detalhes que separam um efeito que parece gerado de um que parece elaborado . Um botão de contato poderia ser um menu suspenso. Em vez disso, tornou-se um dos meus dez segundos favoritos em todo o site.

Considerações finais

Em algum momento entre o primeiro e o terceiro mês desta construção, parei de pensar no site como um portfólio. Tornou-se um pequeno mundo que eu estava cuidando, acrescentando quartos, limpando, andando para ver se ainda parecia honesto. O código era a ferramenta. O mundo era o ponto. E o mundo existia para carregar algo que eu realmente queria doar.

Se você sair deste artigo com uma coisa, espero que seja esta: sua criatividade vem de algum lugar. Na minha vida, acredito que vem de um Criador que tem sido paciente comigo, que tem bons planos para mim mesmo nas épocas em que me afastei Dele, e que sempre esteve presente quando voltei. Qualquer coisa que valha alguma coisa no que você acabou de ler veio dele, não de mim.

Obrigado por ler. Obrigado à Manoela e à equipe Codrops por terem dado lugar para pousar esta obra. E para todos os desenvolvedores e designers que ainda lutam pela arte – continuem. Construa algo que você realmente deseja compartilhar. O trabalho será melhor e você também.

“Eu te louvarei, Senhor, de todo o coração; contarei todas as maravilhas que fizeste.”
— Salmo 9:1

Deixe um comentário

Seu email não será publicado. Campos obrigatórios marcados com *

Este site utiliza o Akismet para reduzir spam. Saiba como seus dados em comentários são processados.