OpenGL에서 객체를 어떻게 구부릴 수 있습니까?


11

OpenGL을 사용하여 실린더 또는 평면과 같은 객체를 구부릴 수있는 방법이 있습니까?

저는 OpenGL 초보자입니다 (OpenGL ES 2.0을 사용하고 있습니다. 문제가 중요하다면,이 경우 수학이 가장 중요하므로 어떤 식 으로든 독립적입니다). 번역, 회전, 행렬 변환 등의 기본 사항을 이해합니다. 객체의 지오메트리를 실제로 변경할 수있는 기술이 있는지 궁금합니다 (이 경우 구부림).

모든 링크, 튜토리얼 또는 다른 참조를 환영합니다!

답변:


11

객체를 "구부리기"위해해야 할 일은 변환 / 회전 / 확장의 적절한 조합을 해당 객체 정점의 일부 하위 집합에만 적용하는 것입니다.

이 방법을 사용하면 유쾌한 모양으로 원래 메쉬를 설명하는 데 꼭 필요한 것보다 더 많은 정점을 사용해야합니다. 예를 들어 간단한 원통에는 양쪽 끝에 정점이있을 수 있지만 그 원통이 가운데에서 구부리려면 정점도 필요합니다.

관심있는 모든 것이 매우 간단한 모양 (앞서 언급 한 평면과 같은)의 일회성 변형 인 경우 수동으로 수행 할 수 있습니다. 예를 들어, 평면의 "굽힘 축"을 결정하고 각 평면 정점 행에 대한 적절한 변형을 계산하여 해당 굽힘 축에 대한 거리를 그 거리에 따라 적절하게 회전시킨 다음 지오메트리에 적용합니다. CPU는 적어도 처음에는 가장 간단합니다). 그러나 이러한 기술은 확장 성이 떨어지고 매우 지루할 것입니다.

원하는 변형 (특히보다 실용적이고 복잡한 객체의 경우)을 달성하기 위해 세트에서 각 개별 정점에 변형을 가중하는 방법을 정확하게 계산하는 것은 너무 번거로울 수 있기 때문에 많은 게임은 골격 애니메이션 이라는 기술을 사용합니다 . 높은 수준에서 이것은 별도의 지오메트리 세트 ( "골격")를 메시와 연관시키는 것을 포함합니다. 이 지오메트리는 객체의 뼈를 나타내며 실제 모델의 꼭지점과 골격의 뼈 사이의 매핑을 정의합니다 (종종 모델링 도구에서)-각 꼭지점과 관련된 뼈 및 해당 뼈가 변형에 미치는 영향 그 정점의. 그런 다음 골격이 직접 애니메이션되고 뼈와 정점 간의 관계를 통해 애니메이션이 실제 모델로 전송됩니다.

일반적으로이 기법에서 스켈레톤과 실제 메시 간의 매핑은 자산 생산시 정의됩니다. 그런 다음 애니메이션을 제작하거나 런타임에 절차 적으로 제작할 수도 있습니다. 애니메이션 변환을 실제 메쉬에 적용하는 것은 런타임에 발생합니다. 일반적으로 런타임에 새로운 정점이 생성되지 않습니다. 즉, 잘 보이는 변형 범위가 처음 생성 될 때 메시에 암시 적으로 고정됩니다.

이론적으로는 애니메이션의 변형 분석을 기반으로 런타임에 테셀레이션 및 세분화를 메시에 적용 할 수 있으므로 반드시 계획되지 않은 애니메이션을 만들기 위해 적절한 정점을 생성 할 수 있습니다. 나는이 주제에 관한 어떤 종이도 모릅니다.

또한보십시오:


9

실제 비틀림 계산을 위해 이것은 매우 복잡해질 수 있습니다. 여기서 시작 하지 않겠 습니까? .

이제 변형을 어떻게 줄 일지에 대한 수학이 이미 있다고 가정하고 이것을 적용하는 방법에 대해 이야기하겠습니다.

두 가지 방법 :

1) 모든 프레임, 실린더 모델의 모든 정점을 방문하여 어떤 식 으로든 오프셋합니다.

2) 렌더링 할 때 정점 셰이더 에서 정점을 오프셋합니다 . OpenGL ES 2.0은 꼭짓점 셰이더를 지원합니다. 그래서 당신은 운이 좋았습니다.

화면에 나타나는 것처럼 오브젝트 만 워프하겠습니까 , 아니면 게임 내의 모든 오브젝트가 변형되었음을 알 수 있도록 오브젝트를 워프 하시겠습니까?

정점 셰이더에서 오브젝트를 뒤 틀면 표시 / 래스터 화 직전에 발생 하므로 게임 오브젝트 중 어느 것도 변형에 대해 알 수 없습니다 . 단순히 화면 보호기를 만들거나 변형이 너무 작아서 물체의 충돌 가능한 모양에 영향을 미치지 않는 경우에 좋습니다.

정점 셰이더 에서 지오메트리를 왜곡하면 모델의 원래 정점이 실제로 이동 하지 않습니다 ( 이동나타남 ).

버텍스 쉐이더의 변형

변형되지 않은 :

변형되지 않은

변형

변형

이것은 cg tutorial 6 장 (프로그램 # 14)에 있습니다.

이 변형을 생성하는 셰이더 코드는

// choose a displacement amount
float displacement = scaleFactor * 0.5 * sin(position.y * frequency * time) + 1 ;

// displace it in the direction of the normal
float4 displacementDirection = float4(normal.x, normal.y, normal.z, 0) ;

// move the vertex
float4 newPosition = position + displacement * displacementDirection ;

// transform (as normal)
oPosition = mul(modelViewProj, newPosition) ;

보시다시피, 이것은 디스플레이 바로 전에 발생합니다 (버텍스 쉐이더는 GPU에서 발생합니다) .CPU 코드는 변환 된 정점 위치에 실제로 액세스 할 수있는 방법이 없습니다 (주로 텍스처를 통해 GPU에서 CPU로 데이터를 보내는 방법이 있습니다) 거기에 가지 않을 것입니다).


8

달성하려는 것은 기본적으로 메쉬 변형 주제의 하위 집합입니다. 그러나 당신이 구걸 자이기 때문에, 나는 이런 유형의 정보가 지금은 너무 이상하다고 생각합니다. 그래도 기본적인 개념을 설명하려고 노력할 것입니다.

이렇게하려면 두 가지가 필요합니다.

  1. 메시에는 변형하기에 충분한 정점이 있어야합니다. 예를 들어 평면 인 경우 변형 할 수있는 정점이 많은 그리드로 실제로 만들어 졌는지 확인해야합니다. 실린더도 마찬가지입니다. 테셀레이션을 사용하여 런타임에 이것을 달성 할 수는 있지만 주제에 대해 많이 알지 못합니다.
  2. 꼭짓점을 변형하려면 꼭짓점 셰이더를 사용해야합니다. 기본적으로 정점 셰이더는 각 정점의 최종 변환 위치를 계산하므로 변형을 적용 할 수 있습니다.

그것이 얼마나 도움이 될지 확신하지 못하지만이 OpenGL 리소스를 살펴보십시오. 필요한 종류의 것 같습니다.

http://www.ozone3d.net/tutorials/mesh_deformer_p3.php#part_3

해당 링크의 스크린 샷 :

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

편집하다

방금 Josh의 대답을 보았을 때 골격 애니메이션은 특히이 문제를 캡슐화하는 매우 우아한 방법입니다. 특히 변형이 수학적으로 표현하기가 더 복잡하고 어려워지기 시작할 때 특히 그렇습니다.

그러나 위의 두 점 모두 여전히 적용됩니다. 꼭짓점 만 변형 할 수 있으므로, 반드시 처음에 존재해야하므로 메시에 알맞은 양의 꼭짓점 밀도가 있어야합니다. 그리고 일반적으로 골격 애니메이션을 구동하고 정점 블렌딩 등을 수행하는 정점 셰이더입니다.

그런데 CPU 에서도이 작업을 수행 할 수 있지만 요즘에는 GPU에서 수행하는 것이 더 나은 옵션이므로 정점 셰이더에 중점을 두어야합니다. 어쨌든 CPU에서 프로그램하는 것보다 프로그래밍 방식이 그렇게 어려운 것은 아닙니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.