본문 바로가기
C++ 200제/코딩 IT 정보

[OpenGL ES] 7. 쉐이더와 Per-Fragment 이해하기

by vicddory 2017. 10. 25.

[OpenGL ES] 7. 쉐이더와 Per-Fragment 이해하기


Per-Fragment Operations

이제 OpenGL ES, Fragment Shader 작업 이후에 어떤 일이 일어나는지 기술한다. (왼쪽 말고 오른쪽을 기술한다, FULL PIPELINE)


OpenGL ES, rasterize_pipepline_example[[OpenGL ES] 7. 쉐이더와 Per-Fragment 이해하기]


그림에선 OpenGL ES, Fragment Shader와 Scissor Test 사이에 생략된 단계가 하나 있다.

"Pixel Ownership Test"라 부르는 내부 단계이지만, 개발자가 내부 단계를 안다 해도 사용할 수 없다. 그러니, 이 단계는 완전히 무시해도 된다.


몰라도 된다.


그림에 보이듯이 접근할 수도, 원하는 대로 설정할 수도 없는 유일한 단계가 Logicop이다(녹색). 우리는 보라색 단계에 집중한다. 어차피 못 건드릴 거 무시하자.


보라색 단계는 기본적으로 비활성화되어 있으며, 활성화하려면 OpenGL ES, glEnable 함수를 쓴다.


OpenGL ES, glEnable의 파라미터는 다음과 같다.


Scissor Test : GL_SCISSOR_TEST - This can crop the image, so every fragment outside the scissor area will be ignored.


Stencil Test : GL_STENCIL_TEST - Works like a mask, the mask is defined by a black-white image where the white pixels represent the visible area. So every fragment placed on the black area will be ignored. This requires a stencil render buffer to works.


Depth Test : GL_DEPTH_TEST - This test compares the Z depth of the current 3D object against the others Z depths previously rendered. The fragment with a depth higher than another will be ignored (that means, more distant from the viewer). This will be done using a grey scale image. This requires a depth render buffer to works.


Blend : GL_BLEND - This step can blend the new fragment with the existing fragment into the color buffer.


Dither : GL_DITHER - This is a little OpenGL's trick. In the systems wich color available to the frame buffer is limited, this step can optimize the color usage to appears to have more colors than has in real. The Dither has no configuration, you just choose to use it or not.


각각의 과정에서 OpenGL ES는 glScissor, glBlendColor, glStencilFunc 등의 설정 함수를 제공한다.


OpenGL ES 쉐이더[[OpenGL ES] 7. 쉐이더와 Per-Fragment 이해하기]


10개 이상의 함수가 존재하지만 여기선 언급하지 않는다. 중요한 건 프로세스를 이해하는 것이다. programmable pipeline을 보면 3차원 객체를 그릴 때마다, 파이프라인 전체가 glDraw*로 부터 호출된다.


Shaders

Shader는 GLSL이나 GLSL ES라는 간략화된 버전을 사용한다. Shader는 Vertex shader와 fragment shader 양쪽에서 동작한다.


Shader는 glDrawArray, glDrawElements 두 종류이며 render 할 때마다 실행된다. Vertex Shader는 모든 꼭지점마다 실행된다(8개의 꼭짓점을 가진 물체라면 8번). Vertex Shader는 꼭지점의 최종 위치를 결정하는 책임도 진다.


Fragment shader는 물체의 보이는 모든 픽셀에 대응해 실행되고, 그래픽 파이프라인에서 fragment operations 전에 실행된다는 것을 기억해라. 그래서 OpenGL ES는 어떤 물체가 다른 물체보다 앞에 있는지 아직 모른다.


fsh는 픽셀의 최종 색을 결정하는데 책임을 진다. vsh, fsh는 각각 따로 컴파일되지만, program object에서 연결된다. 컴파일된 쉐이더는 여러 program object에서 재사용할 수 있지만 program object 는 vsh 하나, fsh 하나만 연결할 수 있다.


OpenGL ES Per Fragment[[OpenGL ES] 7. 쉐이더와 Per-Fragment 이해하기]


Shader and Program Creation

먼저 Shader object의 생성 과정에 대해 알아보고, 소스 코드를 넣고 컴파일해보자. 다른 opengl es 객체들처럼, id를 생성하고 속성들을 설정할 거다. 다른 opengl es 객체와 차이점은 추가된 컴파일 과정이 있다는 것이다.


Shader는 GPU에 의해서 실행된다는 것과 opengl es가 당신의 코드를 바이너리 포맷으로 컴파일해서 최적화 한다는 것을 기억하자.


당신이 미리 컴파일된 shader 바이너리 파일을 가지고 있다면, 이것을 바로 로드 할 수도 있다. 하지만 지금은 컴파일 과정에 집중하자. 다음은 shader 생성에 필요한 함수들이다.


[OpenGL ES] 7. 쉐이더와 Per-Fragment 이해하기[[OpenGL ES] 7. 쉐이더와 Per-Fragment 이해하기]


Shader Object Creation


GLuint glCreateShader(GLenum type)


type : Indicates what kind of shader will be created. This parameter can be:

GL_VERTEX_SHADER: To create a Vertex Shader.

GL_FRAGMENT_SHADER: To create a Fragment Shader.


GL_FRAGMENT_SHADER: To create a Fragment Shader.GLvoid glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)


shader: The shader name/id generated by the glCreateShader function.

count: Indicates how many sources you are passing at once. If you are uploading only one shader source, this parameter must be 1.


string: The source of your shader(s). This parameter is a double pointer because you can pass an array of C strings, where each element represent a source. The pointed array should has the same length as the count parameter above.


length: A pointer to an array which each element represent the number of chars into each C string of the above parameter. This array must has the same number of elements as specified in the count parameter above. This parameter can also be NULL. In this case, each element in the string parameter above must be null-terminated.


위에 보이듯 간단한 단계다.


출처 : All About OpenGL ES 2.X 번역

[OpenGL ES] 7. 쉐이더와 Per-Fragment 이해하기

댓글