색상, alpha, blending
CSS에서는 색상과 투명도를 자연스럽게 씁니다.
background: rgba(13, 148, 136, 0.5);
WebGL에서는 fragment shader가 색을 내보내고, blending 설정이 뒤의 픽셀과 어떻게 섞을지 결정합니다.
alpha blending을 켜는 실제 코드
fragment shader가 alpha 값을 내보내도 WebGL blending 상태를 켜지 않으면 원하는 합성이 나오지 않습니다.
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
gl.useProgram(program);
gl.uniform4f(colorLocation, 0.05, 0.58, 0.53, 0.55);
gl.drawArrays(gl.TRIANGLES, 0, 6);
투명 도형은 draw order도 중요합니다. 일반적인 2D editor에서는 뒤 레이어부터 앞 레이어 순서로 그립니다.
for (const node of scene.nodes) {
gl.uniform4fv(colorLocation, node.fill);
drawNode(node);
}
색은 보통 0..1 범위다
CSS의 rgb(13 148 136)은 0..255 범위입니다. shader에서는 보통 0..1 float로 씁니다.
13 / 255 = 0.051
148 / 255 = 0.580
136 / 255 = 0.533
vec4 color = vec4(0.051, 0.580, 0.533, 0.5);
처음에는 scene model의 색을 renderer에서 0..1 배열로 정규화해 넘기면 됩니다.
alpha만으로는 투명해지지 않는다
fragment shader가 alpha 0.5를 반환해도 blending이 꺼져 있으면 기대한 투명 합성이 나오지 않을 수 있습니다.
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
이 설정은 가장 익숙한 CSS식 alpha 합성에 가깝습니다.
그리는 순서가 중요하다
투명한 도형은 순서에 민감합니다. 뒤에 있는 것을 먼저 그리고 앞에 있는 것을 나중에 그려야 자연스럽습니다.
background
opaque nodes
transparent nodes in layer order
overlay
2D editor에서는 scene layer order가 곧 draw order가 되는 경우가 많습니다.
오늘의 핵심
색상은 shader가 정하지만, 투명 합성은 WebGL 상태와 draw order가 함께 결정합니다.
fill color -> fragment shader
alpha -> blending
layer order -> visual stacking
CSS에서 자연스럽던 투명도를 GPU renderer에서는 명시적인 정책으로 만들어야 합니다.