개발 / / 2024. 4. 28. 09:46

webgpu object loading - face triangle count 계산하기 quad vertex indices mesh rendering

반응형

face triangle count 계산하기

일단 obj 파일을 수정하자.

 

o Grid
v -0.500000 0.750000 -0.000000
v -0.450000 0.750000 -0.000000
v -0.400000 0.750000 -0.000000
v -0.500000 0.700000 -0.000000
v -0.450000 0.700000 -0.000000
v -0.400000 0.700000 -0.000000
vt 0.000000 0.000000
vt 0.050000 0.000000
vt 0.050000 0.033333
vt 0.000000 0.000000
vt 0.050000 0.000000
vt 0.050000 0.033333
vn 0.0000 -0.0000 1.0000
usemtl None
s off
f 1/1/1 2/2/1 5/3/1 4/4/1
f 2/1/1 3/2/1 6/1/1 5/1/1

이 qaud face들을 올바르게 triangle로 나누기 위해 다음 로직을 만들었다.

 

        // calculate triangle count in faces
        const triangleCount = faces.length - 2;
        for(var j = 0; j < triangleCount; j++) {
          const triangleFace : string[] = [faces[0]];
          triangleFace.push(faces[1 + j]);
          triangleFace.push(faces[2 + j]);
          console.log(triangleFace)
        }

출력해보니 face가 (1,2,5) (1,5,4) (2,3,6) (2,6,5)로 잘 구분된다. 

오른쪽 그림을 참고해보면 올바른 삼각형들로 나눠졌음을 알 수 있다.

이제 이 triangleFace를 값으로 finalPosition, Uvs, Normal, Indices를 잘 구분된 triangle 들로 값을 넣어주면 될 것이다.

 

수정중...

 

    {
      const cache: Record<string, number> = {};
      let i = 0;
      for (const faces of cachedFaces) {
        // calculate triangle count in faces
        const triangleCount = faces.length - 2;
        for(var j = 0; j < triangleCount; j++) {
          const triangleFace : string[] = [faces[0]];
          triangleFace.push(faces[1 + j]);
          triangleFace.push(faces[2 + j]);

          for (const faceString of triangleFace) {
            // If we already saw this, add to indices list.
            if (cache[faceString] !== undefined) {
              finalIndices.push(cache[faceString]);
              continue;
            }
  
            cache[faceString] = i;
            finalIndices.push(i);
  
            // Need to convert strings to integers, and subtract by 1 to get to zero index.
            const [vI, uvI, nI] = faceString
              .split("/")
              .map((s: string) => Number(s) - 1);
  
            vI > -1 && finalPosition.push(...cachedVertices[vI]);
            uvI > -1 && finalUvs.push(...cachedUvs[uvI]);
            nI > -1 && finalNormals.push(...cachedNormals[nI]);
  
            i += 1;
          }
        }
      }
    }

이렇게 수정된 코드를 넣고 실행해보면

 

짠. 이렇게 모든 triangle들이 잘 넣어져서 모든 vertex quad들이 빠지지않고 렌더링 되었다.

 

이대로 확장해서 원래 cloth.obj에 넣어보자.

 

cloth.obj 넣기
before & after

 

와 성공이다. 이전에 깨져 보였던 것과는 달리 깨지지 않고 잘 나오는 것을 볼 수 있다.

 

stanford_bunny.obj 토끼 오브젝트 loading

quad 문제를 해결했으니 토끼 오브젝트를 로딩해보자.

 

... quad가 문제가 아니었다.

심지어 토끼 obj file은 vertex indices가 quad로 이루어져있지도 않다.

이쯤 되면 carmen씨의 obj loader 코드가 잘못된 로직으로 짜여있다고 생각된다. 

 

 

carmen씨의 github 코드 보러가기

 

 

model이 너무 커서 그런가 싶어 저해상도의 토끼 모델을 가져왔다.

신기하게 이건 잘 로딩되네.

고해상도 모델이 값이 너무 세밀해서 단위상 오차가 생겨서 그런건가 싶기도 하다.

 

 

webgpu obj load 엔진을 처음부터 만들어야하나?

 

 

webgpu beginner 강의 보러가기

 

이걸로 engine을 다시 만들어보자.

 

 

반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유