오다기리 박의 알고리즘 노트

[OpenGL로 배우는 컴퓨터 그래픽스] Chapter 07. 투상변환과 뷰포트변환 본문

컴퓨터 그래픽스/OpenGL

[OpenGL로 배우는 컴퓨터 그래픽스] Chapter 07. 투상변환과 뷰포트변환

오다기리 박 2019. 2. 14. 21:11

OpenGL로 배우는 3차원 컴퓨터 그래픽스



Chapter 07. 투상변환과 뷰포트변환

Section 01. 투상 (Projection)

투상(Projection), 가시변환(Viewing Transformation) : 모델좌표계-전역좌표계-시점좌표계를 순차적으로 거친 다각형 정점 좌표를 2차원 투상면(View Plane, Projection Plane)으로 사상시키는 과정.

  • 정사투상(Orthographic Projection)

  • 원근투상 (Perspective Projection)


Section 02. GL의 투상변환 (Projection Transformation)

void glGetFloatv(GLenum pname, GLfloat *params); -> 현 투상행렬 값을 검색하여 params 배열로 저장

  • GL 파이프라인

    • 설계된 물체 또는 그래픽 라이브러리에서 가져온 물체를 장면에 맞도록 기하변환시키는 것을 모델변환(Modeling Transformation)이라고 한다.

    • 변환된 물체를 관찰하기 위해 카메라 위치와 방향을 설정하는 것을 시점변환, 뷰변환(Viewpoint Transformation, View Transformation)이라고 한다.

    • 카메라의 렌즈를 선택하고 촬영하여 물체의 2차원 영상을 필름에 맺히게 하는 것이 투상변환(Projection Transformation)

  • GL의 직교투영

    • 기본적인 직교투영


      <math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>P</mi><mn>0</mn></msub><mo>=</mo><mfenced><mtable><mtr><mtd><mn>1</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>1</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>1</mn></mtd></mtr></mtable></mfenced></math>

      • <math xmlns="http://www.w3.org/1998/Math/MathML"><mfenced open="|" close="|"><msub><mi>P</mi><mn>0</mn></msub></mfenced><mo>=</mo><mn>0</mn></math> : 비가역적 = 3차원에서 2차원으로 축소된 것을 다시 복원할 수 없다.

    • 일반적인 직교투영 (정규화 변환 : Normalization Transformation)

      • void glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far); -> 시야 영역 설정 (near, far는 양수로 표시)


<math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>P</mi><mn>0</mn></msub><mo>=</mo><msub><mi>R</mi><mi>z</mi></msub><mi>S</mi><mfenced><mi>s</mi></mfenced><mi>T</mi><mfenced><mi>t</mi></mfenced><mo>=</mo><mfenced><mtable><mtr><mtd><mn>1</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>1</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mo>-</mo><mn>1</mn></mtd><mtd><mn>0</mn></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>1</mn></mtd></mtr></mtable></mfenced><mfenced><mtable><mtr><mtd><mfrac><mn>2</mn><mrow><mi>r</mi><mo>-</mo><mi>l</mi></mrow></mfrac></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mfrac><mn>2</mn><mrow><mi>t</mi><mo>-</mo><mi>b</mi></mrow></mfrac></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mfrac><mn>2</mn><mrow><mi>f</mi><mo>-</mo><mi>n</mi></mrow></mfrac></mtd><mtd><mn>0</mn></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>1</mn></mtd></mtr></mtable></mfenced><mfenced><mtable><mtr><mtd><mn>1</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mo>-</mo><mfrac><mrow><mi>l</mi><mo>+</mo><mi>r</mi></mrow><mn>2</mn></mfrac></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>1</mn></mtd><mtd><mn>0</mn></mtd><mtd><mo>-</mo><mfrac><mrow><mi>t</mi><mo>+</mo><mi>b</mi></mrow><mn>2</mn></mfrac></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>1</mn></mtd><mtd><mfrac><mrow><mi>f</mi><mo>+</mo><mi>n</mi></mrow><mn>2</mn></mfrac></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>1</mn></mtd></mtr></mtable></mfenced><mspace linebreak="newline"/><mo>=</mo><mfenced><mtable><mtr><mtd><mfrac><mn>2</mn><mrow><mi>r</mi><mo>-</mo><mi>l</mi></mrow></mfrac></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mo>-</mo><mfrac><mrow><mi>l</mi><mo>+</mo><mi>r</mi></mrow><mrow><mi>r</mi><mo>-</mo><mi>l</mi></mrow></mfrac></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mfrac><mn>2</mn><mrow><mi>t</mi><mo>-</mo><mi>b</mi></mrow></mfrac></mtd><mtd><mn>0</mn></mtd><mtd><mo>-</mo><mfrac><mrow><mi>t</mi><mo>+</mo><mi>b</mi></mrow><mrow><mi>t</mi><mo>-</mo><mi>b</mi></mrow></mfrac></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mfrac><mn>2</mn><mrow><mi>f</mi><mo>-</mo><mi>n</mi></mrow></mfrac></mtd><mtd><mo>-</mo><mfrac><mrow><mi>f</mi><mo>+</mo><mi>n</mi></mrow><mrow><mi>f</mi><mo>-</mo><mi>n</mi></mrow></mfrac></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>1</mn></mtd></mtr></mtable></mfenced></math>
glOrtho에 의해 <math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>P</mi><mn>0</mn></msub></math>행렬이 물체 정점에 곱해진다.

      • 절단 작업 진행

      • 정규 시야영역 내의 물체만을 대상으로 2차원으로 투상작업 진행

  • GL의 원근투영

    • 기본적인 원근투영

      <math xmlns="http://www.w3.org/1998/Math/MathML"><mi mathvariant="bold-italic">q</mi><mo>=</mo><mfenced><mrow><msub><mi>q</mi><mi>x</mi></msub><mo>,</mo><mo>&#xA0;</mo><msub><mi>q</mi><mi>y</mi></msub><mo>,</mo><mo>&#xA0;</mo><mo>-</mo><mi>d</mi></mrow></mfenced><mo>=</mo><mfenced><mrow><mo>-</mo><mi>d</mi><mfrac><msub><mi>p</mi><mi>x</mi></msub><msub><mi>p</mi><mi>z</mi></msub></mfrac><mo>,</mo><mo>&#xA0;</mo><mo>-</mo><mi>d</mi><mfrac><msub><mi>p</mi><mi>y</mi></msub><msub><mi>p</mi><mi>z</mi></msub></mfrac><mo>,</mo><mo>&#xA0;</mo><mo>-</mo><mi>d</mi></mrow></mfenced></math>
      <math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>P</mi><mi>p</mi></msub><mo>=</mo><mfenced><mtable><mtr><mtd><mn>1</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>1</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>1</mn></mtd><mtd><mn>0</mn></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mo>-</mo><mfrac><mn>1</mn><mi>d</mi></mfrac></mtd><mtd><mn>0</mn></mtd></mtr></mtable></mfenced><mspace linebreak="newline"/><mi>q</mi><mo>=</mo><msub><mi>P</mi><mi>p</mi></msub><mi>p</mi><mo>=</mo><mfenced><mtable><mtr><mtd><mn>1</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>1</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>1</mn></mtd><mtd><mn>0</mn></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mo>-</mo><mfrac><mn>1</mn><mi>d</mi></mfrac></mtd><mtd><mn>0</mn></mtd></mtr></mtable></mfenced><mfenced><mtable><mtr><mtd><msub><mi>p</mi><mi>x</mi></msub></mtd></mtr><mtr><mtd><msub><mi>p</mi><mi>y</mi></msub></mtd></mtr><mtr><mtd><msub><mi>p</mi><mi>z</mi></msub></mtd></mtr><mtr><mtd><mn>1</mn></mtd></mtr></mtable></mfenced><mo>=</mo><mfenced><mtable><mtr><mtd><msub><mi>p</mi><mi>x</mi></msub></mtd></mtr><mtr><mtd><msub><mi>p</mi><mi>y</mi></msub></mtd></mtr><mtr><mtd><msub><mi>p</mi><mi>z</mi></msub></mtd></mtr><mtr><mtd><mo>-</mo><mfrac><msub><mi>p</mi><mi>z</mi></msub><mi>d</mi></mfrac></mtd></mtr></mtable></mfenced><mover><mo>&#x21D2;</mo><mrow><mo>&#xD7;</mo><mfenced><mrow><mo>-</mo><mfrac><mi>d</mi><msub><mi>p</mi><mi>z</mi></msub></mfrac></mrow></mfenced></mrow></mover><mfenced><mtable><mtr><mtd><mo>-</mo><mfrac><mrow><mi>d</mi><msub><mi>p</mi><mi>x</mi></msub></mrow><msub><mi>p</mi><mi>z</mi></msub></mfrac></mtd></mtr><mtr><mtd><mo>-</mo><mfrac><mrow><mi>d</mi><msub><mi>p</mi><mi>y</mi></msub></mrow><msub><mi>p</mi><mi>z</mi></msub></mfrac></mtd></mtr><mtr><mtd><mo>-</mo><mi>d</mi></mtd></mtr><mtr><mtd><mn>1</mn></mtd></mtr></mtable></mfenced></math>

    • 일반적인 원근투영 (정규화 변환 : Normalization Transformation)

      • void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);

      • void glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far);


        <math xmlns="http://www.w3.org/1998/Math/MathML"><msub><mi>P</mi><mi>p</mi></msub><mo>=</mo><mi>T</mi><mo>&#xB7;</mo><mi>S</mi><mo>&#xB7;</mo><mi>S</mi><mi>h</mi><mo>=</mo><mfenced><mtable><mtr><mtd><mn>1</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>1</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mo>-</mo><mfrac><mrow><mi>f</mi><mo>+</mo><mi>n</mi></mrow><mrow><mi>f</mi><mo>-</mo><mi>n</mi></mrow></mfrac></mtd><mtd><mo>-</mo><mfrac><mrow><mn>2</mn><mi>f</mi><mi>n</mi></mrow><mrow><mi>f</mi><mo>-</mo><mi>n</mi></mrow></mfrac></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mo>-</mo><mn>1</mn></mtd><mtd><mn>0</mn></mtd></mtr></mtable></mfenced><mfenced><mtable><mtr><mtd><mfrac><mrow><mn>2</mn><mi>n</mi></mrow><mrow><mi>r</mi><mo>-</mo><mi>l</mi></mrow></mfrac></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mfrac><mrow><mn>2</mn><mi>n</mi></mrow><mrow><mi>t</mi><mo>-</mo><mi>b</mi></mrow></mfrac></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>1</mn></mtd><mtd><mn>0</mn></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>1</mn></mtd></mtr></mtable></mfenced><mfenced><mtable><mtr><mtd><mn>1</mn></mtd><mtd><mn>0</mn></mtd><mtd><mfrac><mrow><mi>r</mi><mo>+</mo><mi>l</mi></mrow><mrow><mn>2</mn><mi>n</mi></mrow></mfrac></mtd><mtd><mn>0</mn></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>1</mn></mtd><mtd><mfrac><mrow><mi>t</mi><mo>+</mo><mi>b</mi></mrow><mrow><mn>2</mn><mi>n</mi></mrow></mfrac></mtd><mtd><mn>0</mn></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>1</mn></mtd><mtd><mn>0</mn></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>1</mn></mtd></mtr></mtable></mfenced><mspace linebreak="newline"/><mo>=</mo><mfenced><mtable><mtr><mtd><mfrac><mrow><mn>2</mn><mi>n</mi></mrow><mrow><mi>r</mi><mo>-</mo><mi>l</mi></mrow></mfrac></mtd><mtd><mn>0</mn></mtd><mtd><mfrac><mrow><mi>r</mi><mo>+</mo><mi>l</mi></mrow><mrow><mi>r</mi><mo>-</mo><mi>l</mi></mrow></mfrac></mtd><mtd><mn>0</mn></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mfrac><mrow><mn>2</mn><mi>n</mi></mrow><mrow><mi>t</mi><mo>-</mo><mi>b</mi></mrow></mfrac></mtd><mtd><mfrac><mrow><mi>t</mi><mo>+</mo><mi>b</mi></mrow><mrow><mi>t</mi><mo>-</mo><mi>b</mi></mrow></mfrac></mtd><mtd><mn>0</mn></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mo>-</mo><mfrac><mrow><mi>f</mi><mo>+</mo><mi>n</mi></mrow><mrow><mi>f</mi><mo>-</mo><mi>n</mi></mrow></mfrac></mtd><mtd><mo>-</mo><mfrac><mrow><mn>2</mn><mi>f</mi><mi>n</mi></mrow><mrow><mi>f</mi><mo>-</mo><mi>n</mi></mrow></mfrac></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mo>-</mo><mn>1</mn></mtd><mtd><mn>0</mn></mtd></mtr></mtable></mfenced></math>


Section 03. GL의 뷰포트변환 (Viewport Transformation)

  • GL 파이프라인


    • 원근 분할된 정규 시야 영역에 있는 물체가 2차원 화면으로 매핑하는 과정

    • Screen Coordinate System = Viewport Coordinate System = Window Coordinate System

  • 뷰포트 설정

    • void glViewport(GLint left, GLint bottom, GLsizei width, GLsizei height);

      <math xmlns="http://www.w3.org/1998/Math/MathML"><mi>P</mi><mo>'</mo><mo>=</mo><mfenced><mtable><mtr><mtd><mi>x</mi><mo>'</mo></mtd></mtr><mtr><mtd><mi>y</mi><mo>'</mo></mtd></mtr><mtr><mtd><mi>z</mi><mo>'</mo></mtd></mtr><mtr><mtd><mn>1</mn></mtd></mtr></mtable></mfenced><mo>=</mo><mfenced><mtable><mtr><mtd><mfrac><mrow><mi>w</mi><mi>i</mi><mi>d</mi><mi>t</mi><mi>h</mi></mrow><mn>2</mn></mfrac></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mi>l</mi><mi>e</mi><mi>f</mi><mi>t</mi><mo>+</mo><mfrac><mrow><mi>w</mi><mi>i</mi><mi>d</mi><mi>t</mi><mi>h</mi></mrow><mn>2</mn></mfrac></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mfrac><mrow><mi>h</mi><mi>e</mi><mi>i</mi><mi>g</mi><mi>h</mi><mi>t</mi></mrow><mn>2</mn></mfrac></mtd><mtd><mn>0</mn></mtd><mtd><mi>b</mi><mi>o</mi><mi>t</mi><mi>t</mi><mi>o</mi><mi>m</mi><mo>+</mo><mfrac><mrow><mi>h</mi><mi>e</mi><mi>i</mi><mi>g</mi><mi>h</mi><mi>t</mi></mrow><mn>2</mn></mfrac></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>1</mn></mtd><mtd><mn>0</mn></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>1</mn></mtd></mtr></mtable></mfenced><mfenced><mtable><mtr><mtd><mi>x</mi></mtd></mtr><mtr><mtd><mi>y</mi></mtd></mtr><mtr><mtd><mi>z</mi></mtd></mtr><mtr><mtd><mn>1</mn></mtd></mtr></mtable></mfenced></math>

    • 재정규화 : z값 범위를 [-1, +1]에서 [0, 1] 로 사상

      <math xmlns="http://www.w3.org/1998/Math/MathML"><mi>P</mi><mo>'</mo><mo>=</mo><mfenced><mtable><mtr><mtd><mi>x</mi><mo>'</mo></mtd></mtr><mtr><mtd><mi>y</mi><mo>'</mo></mtd></mtr><mtr><mtd><mi>z</mi><mo>'</mo></mtd></mtr><mtr><mtd><mn>1</mn></mtd></mtr></mtable></mfenced><mo>=</mo><mfenced><mtable><mtr><mtd><mfrac><mrow><mi>w</mi><mi>i</mi><mi>d</mi><mi>t</mi><mi>h</mi></mrow><mn>2</mn></mfrac></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mi>l</mi><mi>e</mi><mi>f</mi><mi>t</mi><mo>+</mo><mfrac><mrow><mi>w</mi><mi>i</mi><mi>d</mi><mi>t</mi><mi>h</mi></mrow><mn>2</mn></mfrac></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mfrac><mrow><mi>h</mi><mi>e</mi><mi>i</mi><mi>g</mi><mi>h</mi><mi>t</mi></mrow><mn>2</mn></mfrac></mtd><mtd><mn>0</mn></mtd><mtd><mi>b</mi><mi>o</mi><mi>t</mi><mi>t</mi><mi>o</mi><mi>m</mi><mo>+</mo><mfrac><mrow><mi>h</mi><mi>e</mi><mi>i</mi><mi>g</mi><mi>h</mi><mi>t</mi></mrow><mn>2</mn></mfrac></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mfrac mathcolor="#FF0000"><mn>1</mn><mn>2</mn></mfrac></mtd><mtd><mfrac mathcolor="#FF0000"><mn>1</mn><mn>2</mn></mfrac></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>1</mn></mtd></mtr></mtable></mfenced><mfenced><mtable><mtr><mtd><mi>x</mi></mtd></mtr><mtr><mtd><mi>y</mi></mtd></mtr><mtr><mtd><mi>z</mi></mtd></mtr><mtr><mtd><mn>1</mn></mtd></mtr></mtable></mfenced></math>

  • 시야 영역과 뷰포트

    • 시야 영역 (View Volume)과 뷰포트의 종횡비가 일치해야한다.