스프라이트 시트 텍스처가 인접한 텍스처의 가장자리를 잡습니다.


10

간단한 스프라이트 시트를 사용하는 사용자 정의 스프라이트 루틴 (openGL 2.0)이 있습니다 (텍스처가 서로 수평으로 정렬되어 있음).

예를 들어 다음은 간단한 2 개의 텍스처가있는 테스트 스프라이트 시트입니다.

여기에 이미지 설명을 입력하십시오

이제 openGL 스프라이트 객체를 만들 때 수행 할 작업은 아틀라스의 총 프레임 수를 지정하고 그릴 때 그릴 프레임을 지정하는 것입니다.

그런 다음 다음을 통해 텍스처를 가져올 위치를 결정합니다.

필요한 프레임 수를 총 프레임 수로 나누기 (왼쪽 좌표를 얻기 위해)

그런 다음 총 프레임 수로 1을 다이빙하고 결과를 위에서 계산 한 왼쪽 좌표에 추가합니다.

이것은 작동하는 것처럼 보이지만 때로는 문제가 발생합니다. 예를 들어, 아래에 X를 그리고 싶습니다 ...........

여기에 이미지 설명을 입력하십시오

각 텍스처 사이에 1px의 '패딩'을 넣는 것에 대해 들었지만 누군가 어떻게 작동하는지 정확하게 설명 할 수 있습니까? 내가 이것을하면 텍스처를 얻는 것에 대한 계산을 확실히 버릴 것입니다.

텍스처를 채운 채 패딩을 포함 시키면 (스프라이트가 빈 테두리로 그려 짐) 충돌 감지에 문제가 발생합니까? (예 : 투명 부품이 충돌 할 때 경계 상자를 사용할 때 스프라이트가 충돌하는 것처럼 보일 수 있습니다).

누군가 설명 할 수 있다면 감사하겠습니다.


텍스처 를 사용 GL_NEAREST하거나 GL_LINEAR렌더링하고 있습니까?
MichaelHouse

답변:


15

텍스처 아틀라스와 인접한 텍셀 누출을 사용하는 문제는 선형 텍스처 필터링이 작동하는 방식과 관련이 있습니다.

텍스처의 텍셀 중심에서 정확히 샘플링되지 않은 점의 경우 선형 샘플링은 인접한 텍셀 4 개를 샘플링하고 4 개의 가중치 (샘플 포인트로부터의 거리를 기준으로)로 요청한 위치의 값을 계산합니다. 견본.

다음은 문제에 대한 멋진 시각화입니다.

  

GL_CLAMP_TO_EDGE텍스처 아틀라스 와 같은 것을 사용할 수 없으므로 각 텍스처의 가장자리 주위에 테두리 텍셀을 만들어야합니다. 이러한 경계 텍셀은 아틀라스의 완전히 다른 텍스처에서 인접한 샘플이 위에서 설명한 가중치 보간을 통해 이미지를 변경하지 못하게합니다.

이방성 필터링을 사용하는 경우 테두리 너비를 늘려야 할 수도 있습니다. 이방성 필터링은 극단적 인 각도에서 샘플 주변의 크기를 증가시키기 때문입니다.


각 텍스처의 가장자리 주위에 테두리를 사용하여 의미하는 바를 설명하기 위해 OpenGL에서 사용할 수있는 다양한 랩 모드를 고려하십시오. 에 특별한주의를 기울이십시오 CLAMP TO EDGE.

  http://lucera-project.com/blog/wp-content/uploads/2010/06/wrap.png

"Clamp to Border"라는 모드가 있지만 실제로는 관심이 없습니다.이 모드를 사용하면 정규화를 벗어난 텍스처 좌표에 대해 텍스처 주위의 테두리로 사용할 단일 색상을 정의 할 수 있습니다 [0.0 -1.0] 범위.

원하는 것은 CLAMP_TO_EDGE(하위) 텍스처의 적절한 범위를 벗어난 텍스처 좌표가 경계를 벗어난 방향으로 마지막 텍셀 중심의 값을받는 동작을 복제하는 것입니다. 아틀라스 시스템의 텍스처 좌표, (효과적인) 텍스처 좌표가 텍스처 외부의 위치를 ​​참조 할 수있는 유일한 시나리오는 가중 평균 텍스처 필터링 단계 동안입니다.

우리는 알고 GL_LINEAR그래서 우리는 단지 1 텍셀 국경을 필요로 위의 그림에서 볼 수 있듯이 4 개 가까운 이웃을 샘플링합니다. 이방성 필터링을 사용하는 경우 특정 조건에서 샘플 인접 크기가 증가하기 때문에 더 넓은 텍셀 경계가 필요할 수 있습니다.

다음은 테두리를보다 명확하게 보여주는 텍스처의 예입니다. 목적에 따라 테두리를 1 텍셀 또는 2 텍셀로 만들 수 있습니다.

  

(참고 : 내가 참조하는 테두리는 이미지의 네 가장자리 모두에서 검은 색이 아니라 바둑판 패턴이 규칙적으로 반복되는 영역이 아닙니다)

궁금한 점이 있으시면 이방성 필터링을 계속 사용하는 이유는 다음과 같습니다. 각도를 기준으로 샘플 이웃의 모양을 변경하고 필터링에 4 개 이상의 텍셀을 사용할 수 있습니다.

  http://www.arcsynthesis.org/gltut/Texturing/ParallelogramDiag.svg

사용하는 이방성 정도가 클수록 4 개 이상의 텍셀을 포함하는 샘플 주변을 처리해야 할 가능성이 높습니다. 2 개의 텍셀 경계는 대부분의 이방성 필터링 상황에 적합해야합니다.


마지막 GL_CLAMP_TO_EDGE으로, GL_LINEAR텍스처 필터 가있는 상태에서 동작을 복제하는 패킹 된 텍스처 아틀라스를 만드는 방법은 다음과 같습니다.

( 검은 색 좌표에서 X와 Y에서 1을 빼고 게시하기 전에 이미지를 읽은 것을 증명하지 않았습니다. )   

테두리 저장으로 인해이 아틀라스에 4 개의 256x256 텍스처를 저장하려면 크기가 516x516 인 텍스처가 필요합니다. 테두리는 아틀라스 생성 중에 텍셀 데이터로 채우는 방법에 따라 색상으로 구분됩니다.

  • 빨간색 = 바로 아래 텍셀로 교체
  • 노란색 = 바로 위의 텍셀로 교체
  • 녹색 = 왼쪽으로 직접 텍셀로 교체
  • 파란색 = 오른쪽으로 직접 텍셀로 교체

이 예제에서 효과적으로 아틀라스의 각 텍스처는 아틀라스의 258x258 영역을 사용하지만 보이는 256x256 영역에 매핑되는 텍스처 좌표를 생성합니다. 경계 텍셀은 아틀라스의 텍스처 가장자리에서 텍스처 필터링이 수행되고 디자인 방식이 GL_CLAMP_TO_EDGE동작을 모방 한 경우에만 사용됩니다 .

궁금한 점이 있다면 비슷한 접근법을 사용하여 다른 유형의 랩 모드를 GL_REPEAT구현할 수 있습니다. 쉐이더. 조금 더 복잡하므로 지금은 걱정하지 마십시오. 스프라이트 시트 만 다루고 있기 때문에 자신을 제한합니다 GL_CLAMP_TO_EDGE:)


@AndonMColeman에게 감사합니다. 다이어그램의 테두리를 보여줄 수 있습니까? 여전히 이것이 어떻게 작동하는지 이해하지 못합니다. 텍스처가 내 개체에 적용될 때 테두리가 포함된다는 것을 의미합니까? 실제 텍스처를 쿼드의 가장자리로 바로 가져 가고 싶습니다. 올바르게 이해하지 못하면 죄송합니다. 자세한 내용은 감사하겠습니다. 감사합니다
BungleBonce

확실히이 테두리가 작동하는 방식은 텍스처의 가장자리에 텍셀을 복제하는 것입니다.
Andon M. Coleman

@ user22241 : 아니요. 정상적인 상황에서는이 경계선이 보이지 않습니다. 패킹 된 텍스처는 텍스처 좌표 계산에 대해 동일한 치수를 가진 것으로 취급되며, 경계를 건너 뛰기 위해 오프셋을 적용하기 만하면됩니다. 테두리의 요점은 선형 텍스처 샘플링이 스프라이트 시트에서 별도의 이미지에 속하는 텍셀을 초과하여 샘플링하지 못하도록하는 것입니다. 가장 가까운 이웃 샘플링을 사용하면이 중 어느 것도 필요하지 않지만 불쾌한 앨리어스 스프라이트를 얻습니다.
Andon M. Coleman

훌륭하게 자세한 답변-감사합니다! 내가 할 수 있다면 마지막 한 가지. 텍스처 좌표에 추가하기 위해 '오프셋'을 어떻게 해결합니까? 단순히 1 / widthOfTexture라고 말하는 것이 맞습니까?
BungleBonce

@ user22241 : 예, 텍스처 이미지의 시작은 X 방향으로 + 1 / widthOfTexture이고 Y 방향으로 + 1 / heightOfTexture입니다. 각 텍스처를 둘러싼 테두리가 있습니다. 세 번째 수평 텍스처의 텍스처 좌표를 계산할 때까지이 텍스처의 압축 위치는 실제로 +5 텍셀 (첫 번째 텍스처의 경계에 +2 텍셀, 두 번째 텍스처의 경계에 +2, 시작에 +1)입니다. 다른 2 개의 텍스처의 너비와 더불어 그냥 쓰는 것만으로도 복잡한 것 같습니다. 필요한 경우 다이어그램을 그릴 수 있습니다 :)
Andon M. Coleman
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.