2012-12-13 2 views
13

3D 섬을 렌더링하는 OpenGL ES 2.0 앱을 작성 중입니다. 이미 섬 주변에 하늘 돔을 생성하는 코드가 있습니다. 이것은 삼각형으로 구성된 반구로 z 점을 위로하여 섬을 눕습니다.설득력있는 스카이 돔을 어떻게 렌더링합니까?

돔에는 퍼블 노이즈 텍스처를 사용하여 다른 속도로 움직이는 매우 기본적인 움직이는 구름이 있습니다.

  • (하늘을 가로 질러 추적) 일 문 (밤) (포함 상)
  • 별 정적 텍스처
  • 먼 땅을 :

    는하지만 궁극적으로 나는 또한 렌더링하는 돔이 필요합니다

  • 다른 색은 O가 끝날 때부터 매우 효율적으로이 작업을 수행 할 필요가

밤, 새벽, 황혼, 하루 시뮬레이션 n 안드로이드는 테스트 하니스에서 실행되는 순간입니다. 예를 들어 태양, 달, 별은 텍스처가 합당한 정확도로 그려지기는하지만 텍스쳐가됩니다.

이미 돔을 생성하고 날짜와 시간에 대해 태양을 그릴 코드가 있습니다. 그래서 대부분 내가 필요한 쉐이더와 함께 제공되는 쉐이더입니다.

이러한 것을 보여주는 예가 있습니까? 나는 기본적인 큐브 맵이나 제한된 것들을하는 많은 것을 발견했지만, 내가 필요로하는 정교함의 수준까지는 아무것도 찾지 못했다. 이것은 OpenGL ES 2.0이기 때문에 셰이더에서 수행되어야합니다.

내 스카이 돔을위한 쉐이더는 구름을 시뮬레이트하기 위해 2 층의 펄린 노이즈를 렌더링합니다. 텍스처가 연속적으로 감싸서 돔의 정점을 xy 평면으로 (x와 y를 atan에 공급 함) 각도와 돔의 정점 z를 사용하는 v 오프셋을 기반으로 u 오프셋을 계산할 수 있습니다.

버텍스 쉐이더

내가 그것을 할 방법을 보여줍니다 : 나는 또한 구름이 이동하므로 약간에게 U 각 프레임을 상쇄하기 위해 시간을 사용

#ifdef GL_ES 
precision mediump float; 
precision mediump int; 
#endif 

attribute vec4 aVertex; 

uniform mat4 uPMVMatrix; 
uniform float uTime; 
uniform float uSkyDomeRadius; 

const float PI = 3.1415926535897932384626433832795; 

varying vec2 texCoord0, texCoord1; 

void main() 
{ 
    vec2 centre = vec2(600., 600.); 

    gl_Position = uPMVMatrix * aVertex; 

    float slow_time = uTime/100.; 

    vec2 dome_point = aVertex.xy - centre; 
    float tex_u = atan(dome_point.x, dome_point.y);///(.25 * PI); 
    float tex_v = aVertex.z/(uSkyDomeRadius * .5); 

    texCoord0 = vec2(tex_u/2.0 + slow_time, tex_v/2.0); 
    texCoord1 = vec2(tex_u + slow_time/2.0, tex_v); 
} 

. 이것은 Atan이 -PI에서 PI로 바뀌는 것을 제외하고는 훌륭하게 작동합니다. 갑자기 texCoord0과 texCoord1 값은 조각 쉐이더 보간이 보간을 수행하는 큰 거리로 분리됩니다.

가장 좋은 방법은 내베이스에 16 개의 삼각형이 있고 0/16에서 1/16까지의 보간, 1/16에서 2/16까지의 보간법 등입니다. 그러나 15/16에서 0/16으로 갈 때 인터폴 레이터는 뒤로 가고 큰 변화는 frag 쉐이더로 하여금 작은 공간에서 텍스처를 계속해서 반복하여 그림과 같이 줄무늬를 만듭니다.

Interpolation goes haywire as angle goes into reverse

나는 내가이 문제를 해결하겠습니다 유일한 방법은 솔기가 카메라 뒤에 항상 내가 전체 돔을 회전하면 생각 원활한 360도 전망을 가질 수있는 방법을 볼 수 없습니다하지만 여전히 수도 카메라가 돔의 꼭대기를 똑바로 가리키는 지 보여줍니다.

소스를 사용한 작업 예제는 특히 이러한 문제를 해결할 경우 매우 유용합니다.

+0

바보 같은 질문이지만 tex_x 수> PI 또는 <-PI – BevynQ

+0

atex는 그 값을 반환하기 때문에 tex_x는 항상 PI와 -PI 사이에 있습니다. 저는 각 삼각형베이스가 2PI/16 또는 PI/8의 호를 규정하도록 돔 바닥에 16 개의 삼각형을 가지고 있습니다. 그래서 v0는 3/16 주위에 있고 v1은 4/16 번째이므로 tex_x는 적절히 보간합니다. v0가 15/16이고 v1이 0/16이고 보간이 완전히 망쳐 있다면 문제가 발생합니다. 이 문제를 올바르게 해결할 방법이 없다고 생각합니다. 따라서 돔을 회전시켜 솔기가 항상 카메라 뒤쪽에 있어야하고 동등한 양만큼 렌더링을 오프셋해야합니다. – locka

+0

이것을 명확히하기 위해 질문을 업데이트하고 tex_x 및 tex_y를 tex_u 및 tex_v로 변경했습니다. – locka

답변

3

문제는 동일한 꼭지점을 0 °와 360 ° 각도로 사용한다는 것입니다. 그래서 이제 첫 번째 정점이 텍스처 좌표가 15/16, 0이고 두 번째 정점이 1,0 대신 0, 0 인 삼각형이 생깁니다.이 문제를 해결하려면 구를 열어야 만 동일한 공간 위치에 한 쌍의 꼭지점이 있습니다. 하나는 0 °에 하나는 360 °에 있습니다. 그런 식으로 두 정점은 서로 다른 텍스처 좌표를 가질 수 있으며 교란 된 텍스처는 없습니다.

회전시키기 위해서는 래핑 모드를 사용해야하며, 텍스처 랩핑이 반복되도록 설정되어 있는지 확인하십시오. 변경하지 않은 경우 제대로 설정해야하지만 기능이 glTexParameter으로 설정 될 수 있으며 매개 변수는 GL_TEXTURE_WRAP_SGL_TEXTURE_WRAP_T이며 값은 GL_REPEAT이어야합니다. 그런 다음 텍스처 값이 1보다 크면 줄 바꿈하지 않고 텍스처를 반복합니다. 이제 구의 시작점 (0도에서 정점의 경우)과 끝점 (360 도의 정점의 경우)에서 정점을 말할 수 있어야만 tex_u을 수정할 수 있으므로 추가 속성이 필요할 수 있습니다 .

+0

감사합니다. 저는이 문제가 각도가 효과적으로 0으로 돌아가는 것을 알고 있습니다 만, 당신이 제안한 것과 같은 것을 보상하는 방법으로 스카이 돔을 생성 할 수 있는지를 알 수 있습니다. – locka

관련 문제