2012-05-07 5 views
13

구형을 그려야합니다. glBegin() & glEnd()와 같은 호출을 사용하여 OpenGL에서 수행하는 방법을 알고 있습니다.OpenGL ES에서 구형 그리기

하지만 ES에는 아무 것도 없습니다.

제안/개인지도 링크?

+0

이 질문을 확인하십시오 - http://stackoverflow.com/questions/6072308/problem-drawing-a-sphere-in-opengl-es – alegen

+0

URL에 이미 나와 있듯이 http://www.learnopengles.com/ android-lesson-one-getting-started/ –

답변

41

OpenGL ES 2.0에서 태그를 지정 했으므로 부드러운 구체를 만드는 다른 방법을 제안하겠습니다.이 방법은 광선 추적 사기꾼으로 그릴 수 있습니다. 매끄러운 구체를 복제해야하는 많은 정점을 계산하는 대신 어떤 구체에서 구가 거의 동일하게 보임을 활용할 수 있습니다.

은이 작업을 수행하려면 다음과 같은 방법을 사용 :

Sphere impostor generation

당신은 항상 직면 사각형을 만들도록 변위 버텍스 쉐이더에 두 개의 삼각형을 나타내는 네 개의 정점을 보내 사용자. 이 사각형 내에서 조각 쉐이더를 사용하여 각 픽셀을 래스터 화하고이 사각형 창을 통해 볼 때 구가 그 지점에 가질 색을 제공합니다.

이 방법의 장점은 구체가 디스플레이의 해상도만큼 매끄 럽기 때문에 구체를 다시 계산하지 않아도 작은 크기에서 큰 크기로 쉽게 확장 될 수 있다는 것입니다. 버텍스 프로세서에서 프래그먼트 프로세서로의 렌더링에 대한 부담이 줄어들지 만, 필자가 함께 작업 한 OpenGL ES 2.0 장치에 별다른 문제가되지 않는 단일 영역에 대해서도 마찬가지입니다.

this iOS application에서이 기술을 사용합니다.이 기술은 해당 페이지에서 소스 코드를 사용할 수 있으며 조금 더 here에 대해 이야기합니다. ,

precision mediump float; 

uniform vec3 lightPosition; 
uniform vec3 sphereColor; 
uniform mediump float sphereRadius; 

uniform sampler2D depthTexture; 

varying mediump vec2 impostorSpaceCoordinate; 
varying mediump vec3 normalizedViewCoordinate; 

const mediump vec3 oneVector = vec3(1.0, 1.0, 1.0); 

void main() 
{ 
    float distanceFromCenter = length(impostorSpaceCoordinate); 

    // Establish the visual bounds of the sphere 
    if (distanceFromCenter > 1.0) 
    { 
     discard; 
    } 

    float normalizedDepth = sqrt(1.0 - distanceFromCenter * distanceFromCenter); 

    // Current depth 
    float depthOfFragment = sphereRadius * 0.5 * normalizedDepth; 
    //  float currentDepthValue = normalizedViewCoordinate.z - depthOfFragment - 0.0025; 
    float currentDepthValue = (normalizedViewCoordinate.z - depthOfFragment - 0.0025); 

    // Calculate the lighting normal for the sphere 
    vec3 normal = vec3(impostorSpaceCoordinate, normalizedDepth); 

    vec3 finalSphereColor = sphereColor; 

    // ambient 
    float lightingIntensity = 0.3 + 0.7 * clamp(dot(lightPosition, normal), 0.0, 1.0); 
    finalSphereColor *= lightingIntensity; 

    // Per fragment specular lighting 
    lightingIntensity = clamp(dot(lightPosition, normal), 0.0, 1.0); 
    lightingIntensity = pow(lightingIntensity, 60.0); 
    finalSphereColor += vec3(0.4, 0.4, 0.4) * lightingIntensity; 

    gl_FragColor = vec4(finalSphereColor, 1.0); 
} 

이 쉐이더의 현재 최적화 된 버전

이 따라하기 좀 어렵습니다 : 내가 사용하는 버텍스 쉐이더의 단순화 된 버전은 다음과 같이 보입니다 :

attribute vec4 position; 
attribute vec4 inputImpostorSpaceCoordinate; 

varying mediump vec2 impostorSpaceCoordinate; 
varying mediump vec3 normalizedViewCoordinate; 

uniform mat4 modelViewProjMatrix; 
uniform mediump mat4 orthographicMatrix; 
uniform mediump float sphereRadius; 

void main() 
{ 
    vec4 transformedPosition; 
    transformedPosition = modelViewProjMatrix * position; 
    impostorSpaceCoordinate = inputImpostorSpaceCoordinate.xy; 

    transformedPosition.xy = transformedPosition.xy + inputImpostorSpaceCoordinate.xy * vec2(sphereRadius); 
    transformedPosition = transformedPosition * orthographicMatrix; 

    normalizedViewCoordinate = (transformedPosition.xyz + 1.0)/2.0; 
    gl_Position = transformedPosition; 
} 

및 단순화 된 단편 쉐이더이있다 그리고 나는 이것들과 함께 존재하지 않는 앰비언트 오 클루 전 라이팅 (ambient occlusion lighting)을 사용합니다. 또한이 구체의 텍스처링은 구체 표면 좌표와 직사각형 텍스처 사이를 변환하는 적절한 매핑 기능으로 수행 할 수 있습니다. 이것은 내가 구의 표면에 미리 계산 된 앰비언트 오 클루 젼 값을 제공하는 방법입니다.

+0

빌보드도 사용했습니다. http://williamedwardscoder.tumblr.com/post/13270747573/when-playing-with-game-engine-ideas-i-struggled; 내 핵심 입력은 최상의 결과를 얻으려면 두 번째 패스에서 가장자리를 그려야한다는 것입니다.더 이상 조각 당 깊이를 설정할 수 없으므로 OpenGLES 2/webGL로 이동할 때 기술을 포기했습니다. ( – Will

+0

코드에서 'orthographicMatrix'란 무엇입니까? 사각형이 항상 사용자를 향하게하는 매트릭스입니까? –

+0

@ SzałPał - 렌더링보기의 정사각형이 아닌 모양을 수정하려고합니다 –

0

위의 스레드를 방문하는 사람들은 OpenGLES2.0의 "Sphere"를 포함한 다양한 종류의 모양을 만들 수있는 링크를 볼 수 있습니다.

https://github.com/regar007/ShapesInOpenGLES2.0

모양의 클래스 구현은 코드와 통합하기가 매우 쉽습니다.

개체를 인스턴스화하고 렌더링 함수를 사용하여 개체를 그립니다.

관련 문제