프로토타입 충실도

Prototype fidelity

컨셉 검증용 대충 만든 목업(로우파이)부터 실제 제품처럼 마감된 목업(하이파이)까지, 검증하려는 질문에 맞춰 충실도를 조절하는 것.

다른 이름: Low-fi vs. high-fi prototype목업 단계
···
html
<div class="pf-cap"></div>
css
.pf-cap{position:absolute;left:0;right:0;bottom:6%;text-align:center;font-size:clamp(9px,2.4vmin,13px);color:#f1f0eccc}
js
import * as THREE from 'three';
import { RoundedBoxGeometry } from 'three/addons/geometries/RoundedBoxGeometry.js';
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(Math.min(devicePixelRatio, 2));
document.body.appendChild(renderer.domElement);
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x0d0d12);
const camera = new THREE.PerspectiveCamera(40, 1, 0.1, 100);
camera.position.set(0, 0.4, 5.6);
const canvas = document.createElement('canvas');
canvas.width = 128; canvas.height = 128;
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#8a8a8a'; ctx.fillRect(0, 0, 128, 128);
ctx.strokeStyle = '#6f6f6f'; ctx.lineWidth = 2;
for (let y = 4; y < 128; y += 8) { ctx.beginPath(); ctx.moveTo(0, y); ctx.lineTo(128, y); ctx.stroke(); }
const layerTex = new THREE.CanvasTexture(canvas);
const geo = new RoundedBoxGeometry(1.3, 2, 0.6, 3, 0.1);
const stages = [
  { mat: new THREE.MeshStandardMaterial({ color: 0x9a9a94, roughness: 1, metalness: 0 }), label: 'stage 1 — foam block' },
  { mat: new THREE.MeshStandardMaterial({ map: layerTex, roughness: 0.85, metalness: 0 }), label: 'stage 2 — 3D print' },
  { mat: new THREE.MeshPhysicalMaterial({ color: 0x5b5bf7, roughness: 0.15, metalness: 0.1, clearcoat: 1 }), label: 'stage 3 — production finish' },
];
const mesh = new THREE.Mesh(geo, stages[0].mat);
scene.add(mesh);
const key = new THREE.DirectionalLight(0xffffff, 2.1); key.position.set(3, 4, 5); scene.add(key);
scene.add(new THREE.AmbientLight(0xffffff, 0.5));
const cap = document.querySelector('.pf-cap');
function resize() { renderer.setSize(innerWidth, innerHeight); camera.aspect = innerWidth / innerHeight; camera.updateProjectionMatrix(); }
addEventListener('resize', resize); resize();
let idx = 0;
cap.textContent = stages[0].label;
setInterval(() => {
  idx = (idx + 1) % stages.length;
  mesh.material = stages[idx].mat;
  cap.textContent = stages[idx].label;
}, 1600);
renderer.setAnimationLoop((t) => {
  mesh.rotation.y = t * 0.00045;
  camera.lookAt(0, 0, 0);
  renderer.render(scene, camera);
});

프로토타입을 무조건 정교하게 만드는 건 낭비이자 함정입니다. 폼(foam) 블록을 손으로 깎아낸 로우파이 프로토타입은 색도 마감도 없지만, "이 크기가 손에 맞는가", "이 비율이 맞는가" 같은 형태 질문에 답하는 데는 하루면 충분합니다. 만약 여기에 색과 마감까지 완벽하게 입히려 든다면, 정작 형태 자체가 틀렸을 때 그 정교한 마감 작업이 전부 버려집니다.

3D 프린트 프로토타입은 그 다음 단계입니다 — 실제 치수와 조립 관계(부품이 서로 맞는지, 버튼이 눌리는지)까지 검증할 수 있지만 색은 대개 한 가지(프린터 소재 그대로)이고 표면에 적층 무늬(레이어 라인)가 남습니다. 이 단계에서 "인터랙션이 작동하는가"를 확인하고, 색과 마감은 다음 단계로 미룹니다. 마지막 하이파이 프로토타입은 실제 양산과 같은 CMF(색·소재·마감)로 도장·후가공까지 마쳐서, 임원 보고나 사용자 리서치에서 "이게 진짜 제품처럼 보이는가"를 검증하는 데 씁니다.

이 세 단계는 디지털 제품의 와이어프레임 → 클릭 가능한 프로토타입 → 픽셀 퍼펙트 UI 진행과 정확히 같은 논리입니다 — 각 단계는 그 단계에서 검증해야 할 질문에 필요한 만큼만 충실도를 올리고, 그 이상의 디테일에 시간을 쓰지 않습니다. 로우파이 단계에서 픽셀을 다듬는 것과 폼 블록을 사포질하는 것은 같은 실수입니다.

언제 쓰나

어떤 질문(형태? 인터랙션? 최종 인상?)을 검증하려는지 먼저 정하고, 그 질문에 필요한 만큼만 충실도를 올릴 때.