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

Susurrus: Criando um mundo aconchegante em aquarela com Three.js e Shaders | Codrops

Como seria se uma experiência web 3D Three.js/WebGL se comportasse como uma pintura em aquarela – fluida, responsiva e interativa? Em Susurrus , exploro essa ideia usando a renderização não fotorrealista (NPR), abordando a estilização como uma consideração estética e de desempenho. Neste estudo de caso, explicarei como esse projeto foi concebido e construído.

Conceito: Conforto que não existe

Um moinho de vento esquecido flutua na água, renderizado com a delicadeza de uma aquarela, mas totalmente 3D e interativo. Em Susurrus , a cena parece natural e aconchegante à primeira vista, mas sutilmente surreal e absurda após uma inspeção mais detalhada. O design de som suave e uma atmosfera calma criam um espaço meditativo e lo-fi.

Por trás dos visuais aconchegantes, surge uma sutil estranheza: um moinho submerso produzindo pão incessantemente, embora os grãos já devessem ter desaparecido há muito tempo – um símbolo silencioso de conforto inexistente.

Projetando recursos visuais semelhantes a pinturas

Como sempre, raramente uso Figma ou outras ferramentas de design para projetos pessoais. Prefiro uma abordagem de estilo livre, explorando ideias a partir de um conceito breve. O processo de design parece um eco em minha mente: quero ter uma casa flutuando em água refletiva, com o shader Kuwahara aplicado como pós-processamento para criar uma experiência web 3D semelhante a uma pintura.

A UI/UX é intuitiva e clara, com foco em conteúdo 3D. Dois poetas são apresentados, mas a mensagem central é a emoção e a atmosfera – expressas através de imagens e sons. Assim como o nome Susurrus , as palavras são sutis e pouco claras, mais para transmitir uma vibração do que um significado literal.

Tech Stack

  • React
  • React Three Fiber
  • Drei
  • Reagir Três Rapier
  • Howler.js
  • TypeScript
  • WebGL
  • HTML / SCSS

Kuwahara Shader: Definindo a identidade do projeto

Todo o estilo visual do Susurrus é baseado no shader Kuwahara. Embora possa parecer muito processado, o shader Kuwahara é na verdade a única passagem de pós-processamento no projeto, e tudo é construído em torno dele. Algumas configurações e shaders personalizados são usados ​​para “enganar” sutilmente os olhos e obter o efeito final.

Neste projeto comecei com ele como primeiro passo – antes mesmo de terminar os modelos 3D no Blender. Essa abordagem me permitiu ajustar os efeitos visuais antecipadamente e evitar resultados inesperados de sombreamento posteriormente.

Pesquisei diferentes abordagens para implementar o shader Kuwahara e encontrei vários recursos úteis online. A referência que mais me inspirou foi o blog de Maxime Heckel , onde ele explica claramente o filtro Kuwahara e explora técnicas de sombreamento pictórico.

Com base nessas referências, desenvolvi minha própria implementação simplificada durante o projeto, focando em uma abordagem mais leve e limitada:

  1. Eu não usei TensorPass para manter a passagem simples, mesmo que possa aprimorar os detalhes.
  2. Eu uso uma abordagem de estágio de vértice diferente em comparação com implementações de shader Kuwahara padrão.
varying vec2 vUv; void main() { vUv = uv; vec4 modelViewPosition = modelViewMatrix * vec4(position, 1.0); // Set the final position of the vertex gl_Position = projectionMatrix * modelViewPosition; }

E o código de vértice do meu shader Kuwahara é:

varying vec2 vUv; void main() { vUv = uv; gl_Position = vec4(position, 1.0);

Não usei as matrizes modelViewProjection (MVP) completas para manter os cálculos um pouco mais rápidos, com a desvantagem de que o efeito é mais fraco quando a câmera se aproxima muito – mas como a câmera não é animada para se aproximar dos modelos, isso funciona bem.

Aqui está minha versão do Kawahara Pass que usei em Susurrus:

The Reflective Water

A água reflexiva é realmente feita de forma suja, são apenas três etapas:

  • 1. Usado varying vec2 vUv; void main() { vUv = uv; vec4 modelViewPosition = modelViewMatrix * vec4(position, 1.0); // Set the final position of the vertex gl_Position = projectionMatrix * modelViewPosition; }, com o estilo aquarela, a resolução pode ser muito baixo, mantendo o desempenho estável tanto em dispositivos móveis quanto em computadores.
  • 2. Criei um shader personalizado e apliquei-o a um plano acima do plano varying vec2 vUv; void main() { vUv = uv; vec4 modelViewPosition = modelViewMatrix * vec4(position, 1.0); // Set the final position of the vertex gl_Position = projectionMatrix * modelViewPosition; }, adicionando mais detalhes e animação à água.
  • 3. Relâmpago ajustado para que a água pareça mais viva, não muito plana ou chata.
water dev

Gerando pão no clique

O conceito é sobre construir uma pintura dinâmica, então pensei que seria seria interessante implementar a física neste projeto. O Pão Gerador é apresentado como o principal elemento interativo do Susurrus.

Revelar efeito para a introdução #

Em relação ao desempenho, usei MeshReflectorMaterial para controlar o shader de revelação uProgress e apliquei o shader a um MeshReflectorMaterial, que é uma maneira muito útil de implementar o efeito de revelação da introdução.

const RevealOverlay = ({ visible = true }: { visible?: boolean }) => { const materialRef = useRef<THREE.ShaderMaterial>(null!); const meshRef = useRef<THREE.Mesh>(null!); const scroll = useScroll(); const uniforms = useMemo( () => ({ uProgress: { value: 0 }, }), [], ); useEffect(() => { if (meshRef.current) { meshRef.current.raycast = () => null; } }, []); useFrame(() => { if (!materialRef.current) return; let offset = scroll.offset; if (offset < 0.001) offset = 0; materialRef.current.uniforms.uProgress.value = offset * 0.9; }); if (!visible) return null; return ( <ScreenQuad ref={meshRef} renderOrder={-1}> <shaderMaterial ref={materialRef} transparent depthWrite={false} uniforms={uniforms} vertexShader={revealVertexShader} fragmentShader={revealFragmentShader} side={THREE.FrontSide} depthTest={false} /> </ScreenQuad> ); }; export default RevealOverlay;

Efeitos sonoros e interação

Eu usei ScrollControls para implementar efeitos sonoros. Diferentes interações de áudio podem ser acionadas ao passar o mouse ou clicar. Os efeitos sonoros são integrados à música de fundo para obter um estilo lo-fi, o que faz com que Susurrus pareça uma pintura que pode cantar.

Design responsivo

Como sempre, meu objetivo é a compatibilidade móvel e o bom desempenho em dispositivos móveis e também em dispositivos mais antigos.

responsive design

Considerações finais

Antes da IA ​​se tornar tão poderosa, às vezes eu me preocupava que meu trabalho fosse muito estranho. Mas à medida que a IA se tornou mais capaz, a minha mentalidade mudou. Nesta era da IA, a exclusividade parece mais importante hoje em dia. Se meus projetos pessoais são distintos o suficiente para deixar uma leve impressão, ou fazer alguém parar por um milésimo de segundo e pensar: “o que é isso?” – isso é suficiente para me orgulhar. Também me leva a experimentar mais em meu trabalho pessoal.

Créditos

Ativos 3D:
(fornecido e modificado para este projeto)

Música e efeitos sonoros:

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.