프롬프트

Prompt

이미지 생성 모델에게 무엇을 그릴지 알려주는 텍스트 설명. 모델은 이 문장을 이미지가 향해야 할 목표로 해석합니다.

다른 이름: Text prompt
···
html
<div class="wrap">
  <div class="promptbar"><span class="dot"></span><span id="ptxt"></span><span class="caret">▍</span></div>
  <canvas id="cv"></canvas>
</div>
css
.wrap{position:relative;width:100%;height:100%}
#cv{position:absolute;inset:0;width:100%;height:100%}
.promptbar{position:absolute;top:10px;left:10px;right:10px;z-index:2;display:flex;align-items:center;gap:7px;
  padding:7px 10px;border-radius:10px;background:rgba(13,13,18,0.55);backdrop-filter:blur(6px);
  border:1px solid rgba(255,255,255,0.15);font-size:11px;color:#f1f0ec;font-family:ui-monospace,monospace}
.dot{width:6px;height:6px;border-radius:50%;background:var(--accent);flex-shrink:0}
.caret{color:var(--accent);animation:blink 1s step-end infinite}
@keyframes blink{50%{opacity:0}}
js
const cv = document.getElementById('cv'), ctx = cv.getContext('2d');
const ptxt = document.getElementById('ptxt');
function fit() { const dpr = Math.min(devicePixelRatio || 1, 2); cv.width = innerWidth * dpr; cv.height = innerHeight * dpr; ctx.setTransform(dpr, 0, 0, dpr, 0, 0); }
addEventListener('resize', fit); fit();

function mulberry32(a) { return function () { a |= 0; a = a + 0x6D2B79F5 | 0; let t = Math.imul(a ^ a >>> 15, 1 | a); t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t; return ((t ^ t >>> 14) >>> 0) / 4294967296; }; }

function paintSunset(w, h) {
  const r = mulberry32(7);
  const g = ctx.createLinearGradient(0, 0, 0, h);
  g.addColorStop(0, 'hsl(28 80% 62%)'); g.addColorStop(0.55, 'hsl(345 70% 48%)'); g.addColorStop(1, 'hsl(255 45% 18%)');
  ctx.fillStyle = g; ctx.fillRect(0, 0, w, h);
  ctx.beginPath(); ctx.arc(w * 0.5, h * 0.42, Math.min(w, h) * 0.09, 0, Math.PI * 2); ctx.fillStyle = 'hsl(45 95% 78%)'; ctx.fill();
  for (let l = 0; l < 3; l++) {
    ctx.beginPath(); ctx.moveTo(0, h);
    for (let i = 0; i <= 6; i++) { const x = w * i / 6; const y = h * (0.58 + l * 0.09) - r() * h * 0.08 - Math.sin(i + l) * h * 0.02; ctx.lineTo(x, y); }
    ctx.lineTo(w, h); ctx.closePath();
    ctx.fillStyle = 'hsl(' + (280 + l * 10) + ' 30% ' + (14 + l * 7) + '%)'; ctx.fill();
  }
}
function paintAurora(w, h) {
  const r = mulberry32(7);
  ctx.fillStyle = 'hsl(250 45% 8%)'; ctx.fillRect(0, 0, w, h);
  for (let i = 0; i < 50; i++) { ctx.fillStyle = 'rgba(255,255,255,' + (0.2 + r() * 0.6) + ')'; ctx.beginPath(); ctx.arc(r() * w, r() * h * 0.7, r() * 1.4 + 0.3, 0, Math.PI * 2); ctx.fill(); }
  for (let b = 0; b < 3; b++) {
    ctx.beginPath();
    for (let i = 0; i <= 20; i++) { const x = w * i / 20; const y = h * (0.25 + b * 0.08) + Math.sin(i * 0.5 + b) * h * 0.05; i === 0 ? ctx.moveTo(x, y) : ctx.lineTo(x, y); }
    ctx.strokeStyle = 'hsla(' + (150 + b * 30) + ' 80% 60% / 0.5)'; ctx.lineWidth = h * 0.05; ctx.stroke();
  }
  ctx.beginPath(); ctx.moveTo(0, h);
  for (let i = 0; i <= 6; i++) { const x = w * i / 6; const y = h * 0.9 - r() * h * 0.06; ctx.lineTo(x, y); }
  ctx.lineTo(w, h); ctx.closePath(); ctx.fillStyle = 'hsl(250 30% 6%)'; ctx.fill();
}

const prompts = ['노을 지는 산과 호수', '별이 가득한 밤하늘과 오로라'];
let pi = 0, ci = 0;
function typeAndRender() {
  const full = prompts[pi]; ci = 0; ptxt.textContent = '';
  (function step() { ptxt.textContent = full.slice(0, ci); ci++; if (ci <= full.length) setTimeout(step, 55); else setTimeout(render, 300); })();
}
function render() {
  const w = innerWidth, h = innerHeight;
  if (pi === 0) paintSunset(w, h); else paintAurora(w, h);
  setTimeout(() => { pi = (pi + 1) % prompts.length; typeAndRender(); }, 2400);
}
typeAndRender();

프롬프트는 사람이 읽는 문장이지만 모델 안에서는 토큰으로 쪼개져 임베딩 벡터로 바뀌고, 그 벡터가 노이즈를 이미지로 바꾸는 전체 과정에서 "이 방향으로 가라"는 조건으로 계속 참조됩니다. 같은 모델이라도 프롬프트 문구가 바뀌면 조건 벡터가 달라지므로 결과도 달라집니다.

단어 순서와 구체성이 결과에 영향을 줍니다. 매체("수채화", "3D 렌더"), 구도("클로즈업", "부감"), 조명("역광", "네온") 같은 속성을 구체적으로 적을수록 결과가 더 예측 가능한 방향으로 좁혀집니다. 반대로 짧고 추상적인 프롬프트는 모델이 채워 넣을 여지가 커서 같은 문장이라도 시드에 따라 결과 폭이 넓어집니다.

프롬프트가 길다고 전부 반영되는 것은 아니고, 단어 하나의 유무가 이미지 전체 구도를 바꾸기도 합니다. 모델마다 학습 데이터와 토크나이저가 달라서 같은 문장을 다른 모델에 넣으면 결과가 상당히 달라질 수 있습니다.

아래 데모는 실제 언어 이해 대신, 문구 안의 몇 가지 키워드를 미리 정해둔 시각 요소(하늘 색, 산·오로라 유무 등)에 그대로 매핑하는 단순화한 시뮬레이션입니다 — 실제 모델의 의미 해석과는 다릅니다.

언제 쓰나

모든 텍스트-투-이미지 작업의 출발점입니다. 결과가 기대와 다르면 프롬프트를 고치기 전에 먼저 시드·CFG 스케일 같은 다른 파라미터를 고정하고 한 가지씩 바꿔보는 편이 원인을 찾기 쉽습니다.