https://www.quora.com/What-is-a-vertex-shader-and-what-is-a-fragment-shader
http://www.haroldserrano.com/blog/what-is-the-opengl-rendering-pipeline
OpenGL ES에서 모든 오브젝트들은 일련의 코너점들에 의해서 정의된다. 삼각형은 3개의 코너점을 가지고 있으며, 오각형은 5개의 코너점을 가지고 있다. 이 코너점을 vertex라고 부른다.
삼각형을 화면에 올바르게 보여주기 위해 필요한 정보는 3개의 vertex와 3D공간에서 삼각형의 방향(보여지고 있는시점?)이다.
OpenGL에서 삼각형을 정의하기 위해 vertex 리스트를 작성할때 반시계방향 순으로 vertex를 저장해야 한다.
1 2 3 4 5 6 | static float triangleCoords[] = { //넣는 순서는 반시계 방향입니다. 0.0f, 0.622008459f, 0.0f, // 상단 vertex -0.5f, -0.311004243f, 0.0f, // 왼쪽 아래 vertex 0.5f, -0.311004243f, 0.0f // 오른쪽 아래 vertex }; | cs |
vertex 리스트에 있는 vertex들이 primitive의 외곽선을 정의한다. 예를 들어 primitive인 삼각형을 구성하는 3개의 꼭지점이 vertex이며 vertex를 연결하면 삼각형의 외곽선을 정의하게 된다.
삼각형 같은 vertex들의 집합으로 오브젝트를 생성할 수 있는데 이 오브젝트를 mesh라고 부르기도 한다. 삼각형들을 서로 연결하여 오브젝트를 만들어 낼 수 있다.
primitive는 삼각형, 사각형, 원, 선 같은 간단한 shape이다. 복잡한 도형들은 삼각형을 이용하여 만들 수 있다. 예를 들어 사각형은 2개의 삼각형이 하나의 선을 공유하도록 붙여서 만들어 낸다.
오브젝트를 렌더링하기 위해 OpenGL Rendering Pipeline은 다음 순서대로 진행된다.
1.Per-Vertex Operation
vertex shader는 vertex들을 처리하기 위한 범용 프로그래밍 메소드를 제공한다. vertex shader의 입력은 다음 3가지이다.
Attributes - vertex array를 사용하여 제공되는 vertx data.
Uniforms -vertex shader에서 사용되는 상수 데이터
Shader program - vertex가 처리되는 Vertex shader program source code
1 2 3 4 5 6 7 8 9 10 11 | private final String vertexShaderCode = // This matrix member variable provides a hook to manipulate // the coordinates of the objects that use this vertex shader "uniform mat4 uMVPMatrix;" + "attribute vec4 vPosition;" + "void main() {" + // the matrix must be included as a modifier of gl_Position // Note that the uMVPMatrix factor *must be first* in order // for the matrix multiplication product to be correct. " gl_Position = uMVPMatrix * vPosition;" + }"; | cs |
각각의 vertex들은 transformation matrix와 곱해진다. 많이 사용한는 것이 perspective projection transformation matrix이다. 3차원 공간 상의 오브젝트를 구성하는 vertex들의 위치 정보들에 transformation matrix 을 곱하여 2차원 이미지상의 오브젝트를 구성하기 위한 위치로 변환된다.
2.Primitive Assembly
vertex들의 위치정보를 이용하여 삼각형 같은 primitive를 만들어 낸다. vertex들을 서로 연결할때 일정한 순서에 따라 연결이 된다.
3.Primitive Processing
앞에서 생성한 primitive가 View Volume 내부에 포함되는지 태스트한다. 이 태스트를 통과하지 못한 primitive는 이후 단계에서 무시된다. 이 태스트를 Clipping이라고 부른다. 쉽게 얘기해서 3차원 공간상의 물체를 카메라로 찍었을때 보이지 않는 부분들을 제외시키는 것이다.
4.Rasterization 래스터화
Primitive를 화면에 보여주기 위해서는 Primitive의 형태를 화면의 출력 기본단위인 pixel로 근사화해야 한다. primitive가 나누진 각각의 작은 유닛을 fragment라고 부른다.
5.Fragment Processing
Fragment Shader가 fragment에 색 또는 텍스처를 적용한다.
1 2 3 4 5 6 | private final String fragmentShaderCode = "precision mediump float;" + "uniform vec4 vColor;" + "void main() {" + " gl_FragColor = vColor;" + "}"; | cs |
6.Per-Fragment Operation
fragment들을 화면에 보여주기 전에 다음 테스트들을 진행한다.
Pixel Ownership test
Scissor test
Alpha test
Stencil test
Depth test
렌더링을 위해 사용되어지는 모든 데이터들은 위에서 소개한 6단계를 통과해야만 한다. 그리고 나서 화면에 보여지게 된다.
shader
shader는 graphics hardware GPU에서 실행되는 작은 프로그램으로 OpenGL Shading Language(GLSL)라 불리는 그래픽 언어로 작성된다. OpenGL를 사용하여 화면에 오브젝트를 렌더링하기 위해서는 최소한 하나의 vertex shader와 fragment shader를 작성해야 한다. 그렇지 않으면 제대로 동작하지 않는다.
OpenGL Rendering Pipeline에서 shader와 관련있는 단계가 Per-Vertex와 Per-Fragment 이다.
Per-Vertex 단계와 관련 있는 shader를 vertex shader라고 부르고 Per-Fragment 단계와 관련 있는 shader를 fragment shader라고 부른다.
'OpenGL' 카테고리의 다른 글
OpenGL 강좌 - 삼각형이 회전하는 애니메이션 구현 (0) | 2016.12.20 |
---|---|
OpenGL 강좌 - 정사각형 그리기 (7) | 2016.12.20 |
Intel HD 4600에서 벌칸(Vulkan) API 사용해보기 (4) | 2016.11.15 |
Ubuntu 16.04에서 OpenGL( freeGLUT ) 프로그래밍 (2) | 2016.11.10 |
OpenGL( freeGLUT ) 을 Visual Studio 2015에 연동하기 (2) | 2016.09.09 |
시간날때마다 틈틈이 이것저것 해보며 블로그에 글을 남깁니다.
블로그의 문서는 종종 최신 버전으로 업데이트됩니다.
여유 시간이 날때 진행하는 거라 언제 진행될지는 알 수 없습니다.
영화,책, 생각등을 올리는 블로그도 운영하고 있습니다.
https://freewriting2024.tistory.com
제가 쓴 책도 한번 검토해보세요 ^^
그렇게 천천히 걸으면서도 그렇게 빨리 앞으로 나갈 수 있다는 건.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!