2011-08-25 3 views
1

Valve 's Hammer Editor와 같은 3D 맵 편집기에서 브러시를 만들면 기본적으로 객체의 텍스처가 반복되어 세계 좌표로 정렬됩니다.OpenGL에서 월드 좌표 정렬 반복 텍스처 매핑을 구현하는 방법은 무엇입니까?

어떻게 OpenGL을 사용하여이 기능을 구현할 수 있습니까?

이것을 달성하기 위해 glTexGen을 사용할 수 있습니까?

어쨌든 텍스처 매트릭스를 사용해야합니까? 내가 3 × 3 상자를 만들 경우

, 그것은 쉽게 : 설정 GL_TEXTURE_WRAP_T가 가장자리에서 3,3에 설정 texturecoords을 GL_REPEAT 할 수 있습니다.

하지만 개체가 축 정렬 된 볼록한 껍질이 아닌 경우 조금 복잡합니다.

기본적으로 내가 밸브 해머에서 얼굴 편집 시트의 기능을 만들려면 :

Valve Hammer Face Edit tool

답변

2

기술적으로는 질감이에 대한 좌표 생성 할 수 있습니다. 그러나 변환 된 정점 좌표에서 텍스처 좌표를 생성하는 정점 셰이더를 사용하는 것이 좋습니다. 좀 더 구체적으로 (나는 해머를 잘 모른다).


동영상을 본 후 혼란을 이해합니다. Hammer/Source는 아마도 드로잉 API가 텍스처 좌표를 생성하지는 않지만 내부적으로 생성한다는 것을 알아야한다고 생각합니다.

그래서 얼굴이 가리키는 주요 방향에 따라 X, Y 또는 Z 평면에 투영되는 텍스처가 있습니다. 그런 다음 로컬 정점 좌표를 텍스처 좌표로 사용합니다.

모델을 Vertex Buffer Object (계산이 한 번만 수행되기 때문에보다 효율적 임) 또는 GLSL 정점 셰이더로로드하는 코드에서이를 구현할 수 있습니다. 내가 당신에게 의사주지 :

cross(v1, v2): 
    return { x = v1.y * v2.z - v1.z * v2.y, 
      y = v2.x * v1.z - v2.z * v1.x, // <- "swapped" order! 
      z = v1.x * v2.y - v1.y * v2.x } 

normal(face): 
    return cross(face.position[1] - face.position[0], face.position[2] - face.position[0]) 

foreach face in geometry: 
    n = normal(face) // you'd normally precompute the normals and store them 
    if abs(n.x) > max(abs(n.y), abs(n.z)): // X major axis, project to YZ plane 
     foreach (i, pos) in enumerate(face.position): 
      face.texcoord[i] = { s = pos.y, t = pos.z } 

    if abs(n.y) > max(abs(n.x), abs(n.z)): // Y major axis, project to XZ plane 
     foreach (i, pos) in enumerate(face.position): 
      face.texcoord[i] = { s = pos.x, t = pos.z } 

    if abs(n.z) > max(abs(n.y), abs(n.x)): // Z major axis, project to XY plane 
     foreach (i, pos) in enumerate(face.position): 
      face.texcoord[i] = { s = pos.x, t = pos.y } 

이 glTexGen 질감이 작품은 세대를 좌표 만들려면을, 각 주축의 부분으로 모델을 분할해야 할 것이다. glTexGen이하는 일은 매핑 단계 face.texcoord[i] = { s = pos.<>, t = pos.<> }입니다. 버텍스 쉐이더에서는 분기를 직접 수행 할 수 있습니다.

+0

질문 : OpenGL에서 world-coordinate-aligned 반복 텍스처 매핑을 구현하는 방법은 무엇입니까? 밸브 해머는 단지 예일뿐입니다 (http://www.youtube.com/watch?v=8R4aWvRQP-E 참조). – JBeurer

+0

이것은 작동 할 수 있습니다. 나는 얼굴의 평면에 대한 직각 기저 벡터를 찾고 얼굴 정점을 투영 해 보았습니다. s = Vector.Dot (basis1, vertex); t = Vector.Dot (basis2, vertex); 이 접근법의 문제점은 평면이 평면 수직 주위로 회전 된 여러 직교 기저 벡터를 가질 수 있다는 것입니다. 그리고 저는 비행기 기저 벡터를 얻는 방법을 원점과 어떻게 든 일치시키는 방법을 모릅니다. – JBeurer