line/outline renderer
편집기에는 fill rectangle만 있지 않습니다. 선택 outline, hover outline, ruler tick, guide line, frame edge 같은 선이 계속 등장합니다.
그래서 별도의 line/outline renderer가 필요합니다.
overlay rectangle outline을 만드는 코드
WebGL의 기본 line은 플랫폼마다 두께 제어가 제한적입니다. 그래서 selection outline도 얇은 rectangle 네 개로 만들어 triangle로 그리는 방식이 실무적으로 단순합니다.
function pushOutline(vertices, bounds, thickness) {
const { x, y, width, height } = bounds;
pushRect(vertices, x, y, width, thickness); // top
pushRect(vertices, x, y + height - thickness, width, thickness); // bottom
pushRect(vertices, x, y, thickness, height); // left
pushRect(vertices, x + width - thickness, y, thickness, height); // right
}
const overlayVertices = [];
pushOutline(overlayVertices, selectionBounds, 2 / camera.zoom);
gl.bindBuffer(gl.ARRAY_BUFFER, overlayBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(overlayVertices), gl.DYNAMIC_DRAW);
gl.uniform4f(colorLocation, 0.05, 0.58, 0.53, 1);
gl.drawArrays(gl.TRIANGLES, 0, overlayVertices.length / 2);
2 / camera.zoom처럼 두께를 보정하면 zoom이 바뀌어도 화면에서는 비슷한 두께로 보입니다. content renderer와 overlay renderer를 분리하면 이런 정책을 도형 fill과 독립적으로 다룰 수 있습니다.
WebGL line은 기대와 다를 수 있다
WebGL에는 line primitive가 있지만, 브라우저와 GPU에 따라 두꺼운 line 지원이 제한적입니다. 편집기에서 필요한 1px, 2px, dashed, zoom-independent outline을 모두 맡기기에는 부족할 수 있습니다.
그래서 실무에서는 선도 rectangle이나 triangle strip으로 직접 만드는 경우가 많습니다.
line segment -> thin rectangle -> two triangles
outline은 screen pixel 기준이 많다
선택 outline은 도형과 같이 확대되는 것이 아니라 화면에서 일정한 두께를 유지하는 편이 자연스럽습니다.
node world bounds
-> camera로 screen bounds 계산
-> screen에서 1px outline 그리기
이것은 content renderer와 overlay renderer를 분리해야 하는 이유이기도 합니다.
handles와 guides도 같은 계열이다
resize handle, rotation handle, smart guide는 모두 overlay에 가깝습니다. world 정보를 기반으로 위치를 계산하지만, 실제 크기와 두께는 screen pixel 정책을 따릅니다.
world anchor -> screen position
handle size = 8px
guide width = 1px
오늘의 핵심
line/outline renderer는 편집기의 사용감을 좌우합니다. 도형 자체보다 사용자가 조작하는 피드백을 그리는 역할이 큽니다.
content renderer: 문서 도형
outline renderer: 선택과 조작 피드백
이 구분이 잡히면 다음 Part의 editor tool math가 renderer 위에 자연스럽게 올라갑니다.