Learn OpenGL
Vertex Input
- y축이 위쪽을 향함
- 그래픽스에서는 전통적으로 화면 왼쪽 위 모서리가 (0,0)
- x축은 오른쪽으로 증가, y축은 아래쪽으로 증가
- CRT 모니터 시대의 전자총 방향에서 유래됨
- windows api, 웹 브라우저 등 대부분의 UI 시스템이 이 방식 사용
Vertex Buffer Object(VBO)
- vertex data를 GPU 메모리에 저장하는 OpenGL 객체
- CPU에서 전송한 데이터를 GPU에서 가지고 있기 위해 필요, 없으면 매 프레임마다 CPU에 요청해야함
- VBO는 GPU 메모리에 있는 버퍼 데이터를 가리키는 id
- OpenGL에서 객체는 GPU 자원에 대한 ID를 의미함
- 생성 과정: VBO 생성 -> VBO 바인딩 -> 데이터 복사
- OpenGL의 상태를 슬롯 같은 것임, 이 슬롯에 바인딩하는 과정 필요함
- 바인딩은 데이터 없이 연결만함
- 데이터 복사해서 실제 데이터를 CPU 메모리에서 GPU 메모리로 복사
- 사용 패턴
- GL_STATIC_DRAW: 한 번 설정, 많이 사용 (삼각형 같은 고정 데이터)
- GL_DYNAMIC_DRAW: 자주 변경, 많이 사용 (애니메이션 데이터)
- GL_STREAM_DRAW: 한 번 설정, 몇 번만 사용
Vertex Shader
- 각 vertex 마다 한번씩 실행됨
- 다음 단계로 데이터 전달
Compiling a shader
- 작성한 shader 코드를 실제로 사용하기 위해 컴파일
- shader 소스코드를 문자열로 저장
- shader 객체 생성
- 소스코드 연결 및 컴파일
- 컴파일 성공 여부 확인
- 확인할 에러: GLSL 문법 오류, 타이핑 실수, 버전 호환상 문제 등등
Fragment Shader
- Red, Green, Blue, Alpha 성분을 0.0과 1.0 사이의 값으로 표현
Shader Program
- 여러 셰이더들을 연결한 최종 버전
- vertex shader의 출력이 fragment shader의 입력과 매칭됨
- 생성 과정
- 프로그램 객체 생성
- shader들을 프로그램에 attach
- shader들을 프로그램에 link
- linking 성공 여부 확인
- 프로그램 사용
Linking Vertex Attributes
- 여기까지 상황: VBO에서 정점 데이터 저장, shader program 준비됨, OpenGL은 아직 데이터 형식 모름
- glVertexAttributePointer로 설정
- glEnableVertexAttribArray으로 location 정점 속성 활성화 -> 이 호출이 있어야 데이터가 shader로 전달됨
Vertex Array Object (VAO)
- 매번 정점 속성을 설정하는 것이 번거로우니, 이 설정을 저장하는 객체
- 정점 속성 설정의 스냅샷을 저장함
Skia vs OpenGL
브라우저가 Skia를 사용하는 이유
- 텍스트 렌더링 품질
- 벡터 그래픽 지원
- 크로스플랫폼 일관성 -> 가장 큰 이유
브라우저가 OpenGL을 쓰지 않는 이유
- 호환성 문제
- OpenGL을 지원하지 않는 오래된 사용자 환경
- 정밀도 문제
- CSS는 정수 픽셀 단위 요구
- 서브 픽셀 텍스트 렌더링 어려움
- 복잡한 상태 관리
실제 Chromium 아키텍처
HTML/CSS → Layout Engine → Compositor → GPU Process
↓
Skia (CPU/GPU)
Skia GPU 선택
- 적응적으로 CPU/GPU 선택, 자동으로 전환
- 명시적으로 GPU 사용 요청 가능
/* CSS로 GPU 레이어 유도 */
.element {
transform: translateZ(0); /* GPU 레이어 생성 */
will-change: transform; /* 브라우저에게 미리 알림 */
}
Element Buffer Objects(EBO)
- 정점을 재사용해서 메모리를 절약하는 방법
- 생성 과정
- EBO 생성
- EBO 바인딩 및 데이터 복사
- 그리기 함수 변경
- 3D 도구에서 작업시 indices를 만들어 줌. 라이브러리도 있음
- 대부분 자동으로 해줌