colorverse

컬러버스

  • CLIENT

    COLORVERSE

  • RELEASE DATE

  • TYPE

    creative dev

컬러버스는 자신만의 색깔을 담은 세계를 만들고 공유하는 오픈 메타버스 플랫폼입니다. 컬러버스만의
창의력과 무한한 가능성, 다채로운 컬러를 사이트에 담는 것을 목표로 하였으며, 더불어 자신만의 공간을 만들고
그들이 모여 커뮤니티와 타운, 그리고 월드 까지 확장됨을 느낄 수 있도록 파티클을 이용해 표현하였습니다.
컬러버스가 정식 오픈되기 전 티저 사이트 방문하시는 분들에게는 즐거운 기다림을, 오픈 후 컬러버스를
플레이하시는 분들에게는 자신만의 색으로 세상을 만들어가는 신선한 경험이 되시길 바랍니다.

사이트 바로가기

Front-end dev case study

컬러버스 프로젝트의 핵심목표는 다양한 오브젝트가 자연스럽게 변형될 수 있는 파티클 시스템을 구현하는 것이며, 각 오브젝트는 Colorverse 서비스의 주요 포인트를 나타냅니다.

Keep it simple

원 페이지의 웹사이트로 Javascript UI framework, CMS 또는 별도의 빌드 툴이 없는 간단한 개발 stack으로 구축하였습니다. 프로젝트에서 사용한 라이브러리 정보는 다음과 같습니다.

Particles shader

3D 파티클은 Three.js로 개발했으며, 요구사항을 맞추기 위해 고객 맞춤 GLSL을 추가로 개발했습니다. 하지만 안타깝게도 테스트 버전에서는 3D 모델의 깊이(Depth)에 대한 표현이 미흡했습니다.

Hum🤔 Need to do better!

Houdini to the rescue

깊이 표현 문제를 해결하기 위해 컬러버스 3D 아티스트 담당팀으로부터 Houdini(3D 시각 효과 소프트웨어)로 깊이 표현이 추가 된 오브젝트를 제공받았습니다. 이것을 참고하여 다양한 테스트를 진행하였으며, 여러번의 시행착오끝에 컬러버스만의 파티클 셰이더를 자체적으로 구축하는데 성공하였습니다. 이 셰이더를 활용해 Houdini 오브젝트 버전과 매우 유사한 WebGL을 제작할 수 있었습니다.

고객 Houdini 버전

Studio-JT Webgl 버전

그림자를 시뮬레이션하는 과정에서 그림자에 해당하는 파티클 크기를 원본 보다 작게 적용하는 것은 특히 어려웠으며, 이 문제는 3D 오브젝트의 ‘Normals’ 정보를 셰이더에 전달하는 방법으로 해결하였습니다. 더불어 다양한 문제를 해결과정을 겪으며 Three.js의 소스 코드를 깊게 파고 들고, Three.js의 기본 파티클 셰이더가 어떻게 동작하는지에 대한 원리를 정확히 이해할 수 있었습니다.

Particles depth in GLSL

아래는 파티클 오브젝트 내부의 그림자를 표현하도록 하는 코드의 일부입니다.

vec4 viewPosition = modelViewMatrix * vec4(position, 1.0);
vec4 viewSunPos   = viewMatrix * vec4(sunPosition, 1.0);
              
v_normal      = normalMatrix * norm;
v_vertToLight = normalize(viewSunPos.xyz - viewPosition.xyz);
          
float kd = max(u_minSize, dot(v_vertToLight, v_Normal));

gl_PointSize = (u_size / -viewPosition.z) * kd;

Build a test page

파티클 셰이더에 옵션 패널을 만들어 활용 가능한 매개변수를 최대한으로 추가했으며, 이를 통해 프로젝트에 필요한 완벽한 설정을 찾을 수 있었습니다.

Let's play!


Clean up! 3D 오브젝트 최적화

오브젝트를 파티클화 했을 때 꼭짓점이 많아 원하는 느낌이 나지 않고 용량이 과하게 커지는 경우가 종종 있었습니다. 이는 Blender를 활용해 꼭짓점 개수를 줄여 원하는 느낌을 냄과 동시에 용량을 최적화하는 것으로 해결할 수 있었습니다.

꼭짓점의 수는 ‘decimate modifier’를 사용하여 줄일 수 있었으며, 때로는 복잡한 오브젝트를 단순화 하기위해 일일이 수작업을 하기도 했습니다. 추가로 .glb 포맷으로 저장하여 매우 작은 용량의 3D 오브젝트를 만들었습니다. (오브젝트는 복잡도에 따라 최대 10kb에서 400kb까지 다양한 크기를 가집니다.)

Gradients

컬러버스의 로고 색상을 그라디언트로 사용하여 브랜드 아이덴티티를 한층 더 부각시켰습니다.

여러번의 테스트를 거쳐 섹션별로 그라디언트 추가하고 완벽한 그림자 방향을 설정할 수 있었습니다.

Particle morphing on scroll

또 다른 도전은 여러 오브젝트의 파티클이 페이지의 스크롤에 맞춰 자연스럽게 모핑이 되도록 만드는 것이었습니다. Threejs morph target속성과 GSAP ScrollTrigger를 사용하여 모핑을 구현했습니다.

GSAP ScrollTrigger를 사용한 스크롤의 파티클 애니메이션은 AfterEffect 타임라인에서 작업하는 것과 같은 수작업이었습니다. 원하는 결과를 얻기 위해 타임라인을 조정하고 완화하는 것에 많은 시간을 사용했습니다.

Post processing

Post processing 필터로 3D 경험에 임팩트를 추가했습니다. BloomPass FilmPass를 사용하여 부드러운 빈티지 TV 스타일 렌더링을 만들었습니다.

const  composer = new THREE.EffectComposer( renderer );
composer.addPass( new THREE.RenderPass( scene, camera ) );

// BloomPass (glow effect)
const screenDimension = new THREE.Vector2( window.innerWidth, window.innerHeight );
const bloomPass = new THREE.UnrealBloomPass( 
    screenDimension, 
    1.1, // strength
    0.3, // radius 
    0.0  // threshold
);
composer.addPass( bloomPass);

// FilmPass (Old tv effect)
const filmPass = new THREE.FilmPass(
    0.35,  // noise intensity
    0.6,   // scanline intensity
    2048,  // scanline count
    false, // grayscale
);
filmPass.renderToScreen = true;
composer.addPass( filmPass);  

배포

컬러버스 프로젝트는 별도의 빌드 툴을 사용하지 않았기 때문에 배포 전에 스크립트를 수동으로 압축(minify)해야 했습니다. 이를 위해 Uglify 커맨드 라인 툴을 사용했습니다.

Wrapping up

3D 파티클을 자유자재로 다루긴 쉽지 않지만, 기본 셰이더와 GLSL 언어를 이해하면 정말 인상적인 경험을 만들 수 있습니다. 우리는 WebGL에 대한 경험이 있는 모든 개발자에게 커스텀 셰이더의 아름다운 세계에 대해 깊이 파고들 것을 강력히 추천합니다.

컬러버스 담당자분들은 최종 결과에 정말 만족했으며, 여러분들이 이 프로젝트 결과를 마음껏 즐겨주셨으면 좋겠습니다. 앞으로도 더 창의적이고 무한한 가능성이 담긴 사이트들을 보여드릴 수 있도록 노력하겠습니다.

감사합니다.

만든사람들

개발
  • 쇼베 니콜라

  • 김채희

기획
  • 정동영

디자인
  • 정다운

  • 이용규