Posts Computer Graphic Screen
Post
Cancel

Computer Graphic Screen

资料来源:https://sites.cs.ucsb.edu/~lingqi/teaching/games101.html


What’s after MVP?

Model transformation (placing objects)

View transformation (placing camera)

View transformation (placing camera)

Projection transformation

  • Orthographic projection (cuboid to “canonical” cube [-1, 1]3)

  • Perspective projection (frustum to “canonical” cube)

Canonical cube to Screen

将物体画在屏幕上,屏幕是由像素组成的,一个像素颜色由RGB三种颜色混合构成

屏幕覆盖范围(0,0)至(width,height)

像素索引从(0, 0) to (width - 1, height - 1)

像素坐标中心是(x + 0.5,y + 0.5)

无Z方向

变换到XY平面,[-1, 1]2 to [0, width] x [0, height]

Viewport transform matrix: \(\left [ \begin{matrix} width/2 & 0 & 0 & width/2\\ 0 & height/2 & 0 & height/2 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{matrix} \right ]\)


绘制屏幕上的画面,就是绘制空间中的物体,在获得屏幕空间坐标信息后,绘制物体,物体在屏幕上是由一个个点连成线,再由线绘成三角形,三角形组成物体。

在屏幕坐标中,有哪些像素是近似可以连起来成一个三角形的?

1

一个简单的方法,可以进行采样(采样一般指取样。取样是指从总体中抽取个体或样品的过程,也即对总体进行试验或观测的过程。分随机抽样和非随机抽样两种类型)

Sampling is a core idea in graphics.

We sample time (1D), area (2D), direction (2D), volume (3D) …

Sample If Each Pixel Center Is Inside Triangle

2

1
2
3
4
5
for (int x = 0; x < xmax; ++x)
    for (int y = 0; y < ymax; ++y)
      image[x][y] = inside(tri,
                           x + 0.5,
                           y + 0.5);

Inside? Recall: Three Cross Products!

3

只检查在三角形内的像素,不遍历全屏幕,减少采样数量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
const Triangle& t

auto v = t.toVector4();

auto ext_pt_x = std::minmax_element(v.begin(), v.end(),
                                    [](const Eigen::Vector4f& lhs, const Eigen::Vector4f & rhs){
                                         return lhs.x() < rhs.x();
                                    });
 auto ext_pt_y = std::minmax_element(v.begin(), v.end(),
                                    [](const Eigen::Vector4f& lhs, const Eigen::Vector4f & rhs){
                                         return lhs.y() < rhs.y();
                                    });
 xMinBox = floor(ext_pt_x.first->x());
 xMaxBox = floor(ext_pt_x.second->x());
 yMinBox = floor(ext_pt_y.first->y());
 yMaxBox = floor(ext_pt_y.second->y());

for (int x = xMinBox; x <= xMaxBox; ++x){
  for (int y = yMinBox; y <= yMaxBox; ++y){   
      if(insideTriangle(x,y,v3f)){
          Eigen::Vector3f point(x,y,1.0f);
          set_pixel(point,t.getColor());
      };
  }
}

static bool insideTriangle(int x, int y, const Vector3f* _v)
{   
    Eigen::Vector3f pt;
    pt << (float)x, (float)y, 0.0f;
    bool isInside = isSameSide(pt, _v[0], _v[1], _v[2]) && isSameSide(pt, _v[1], _v[0], _v[2])
      && isSameSide(pt, _v[2], _v[0], _v[1]);
    return isInside;

}

This post is licensed under CC BY 4.0 by the author.