요즘 Konstruktor 렌더링 엔진의 퀄리티를 개선하기 위한 방법을 생각하고 있습니다. 현재 퀄리티에서 가장 문제가 되는 부분은 쉐이딩입니다.

플랫 쉐이딩으로 인해 물체 표면이 각져 보입니다. 현재 LDraw의 스펙에서는 단순히 삼각형, 사각형을 그리기 위한 vertex들의 집합(mesh)만 정의되어 있고, surface normal을 정의하지 않습니다. 그래서 단순히 그 정점의 데이터만 가지고 surface normal을 뽑아내면 저런 식으로 물체가 각져 보이게 되는데, smooth shading을 하기 위해서는 인접한 삼각형과 사각형을 이루는 vertex가 가지는 surface normal 벡터들을 보간해야 합니다. 하지만 가장 큰 문제는 LDraw 파일의 스펙이 strictly declarative하지 않다는 것입니다. 그러다 보니 렌더러에서 정해진 파일 스펙 이상을 표현하기가 어렵게 되다 보니 현재 mesh를 인접한 것들끼리 서로 분류하기 위해서는 전체 파일 트리를 뒤지면서 메쉬를 재구성하는 절차가 필요해지게 되는데, 그 시점에서 고려해야 할 부분이 많은 꽤나 골치아픈 작업이 될 것 같습니다.

그리고 또 다른 문제가 있는데, 이 스크린샷에서는 일부 삼각형의 쉐이딩이 깨집니다. 파트 제작자의 실수인지는 모르겠지만 정점 순서가 잘못되어 surface normal이 인접 삼각형과 반대 방향으로 반전되어 생기는 문제입니다. 근본적으로는 렌더러의 문제가 아니라 파트 자체의 문제이나 메쉬 재구성 과정을 통해서 능동적으로 고칠 여지는 있습니다.
일단 고려해야 할 부분은:
- 메쉬 전체를 그루핑하면 안 됩니다. 원래부터 각진 표면이 있기 때문에 모든 정점에 대해 normal smoothing을 적용하면 안 됩니다. 일단 인접 삼각형, 사각형과의 각도를 재어서 threshold를 적당하게 주면 될 겁니다.
- 메모리 사용량을 최소화해야 합니다. 지금 LDraw 구조를 나이브하게 활용하면 중복되는 정점 데이터가 너무 많이 생깁니다. 메쉬를 재구성하는 김에 triangle, quad strip 등으로 재조립해서 중복되는 정점 데이터를 최소화해야 합니다.
- 그리고 이 모든 과정은 휴리스틱해야 합니다. triangle/quad strip을 만드는 문제도 그렇고 두번째 스크린샷의 normal 반전 오류를 고치는 등의 문제를 해결하기 위해서는 적절한 조건이 있어야 할텐데, 이건 조금 더 생각해봐야 할 문제인 것 같군요.
- 빨라야 합니다. part 데이터는 수시로 메모리에 적재되기 때문에 이 모든 메쉬 재구성 작업에 들어가는 시간은 최대한 적은 것이 좋을 겁니다.
사실 이런 것은 시중에 나와있는 대부분의 3D 소프트웨어가 기본으로 하는 일일텐데 공부하는 셈 치고 독자적으로 구현해 볼 생각입니다. 이 모든 작업을 위해서는 일단 자료구조부터 잘 설계해야 하는데, 조금 더 생각해보고 실제 구현해 본 다음에 이어서 포스팅하겠습니다. 아마 비슷한 걸 다루는 논문이라도 있는지 찾아봐야겠군요.


