Camera In JSR184

转自lyo的blog,原文地址:http://lyo.blogsome.com/2007/01/31/camera-in-jsr184/

1. Camera类
                  — Lyo Wu

写完模拟器的M3G部分,早就想写点总结,不写怕要忘了。
那就从最简单的Camera类开始。

Camera类封装了3种投影变换:Generic、Parallel、Perspective。
1) Generic
public void setGeneric(Transform transform)
直接指定一个变换矩阵(Transform类其实就是一个矩阵的封装),可以根据需求任意设置投影矩阵。

2) Parallel
public void setParallel(float fovy, float aspectRatio, float near, float far)
 平行投影(正射投影,Orthographic Projection),忽略z轴作用,投影后的物体大小尺寸不变。M3G Specification中已经给出了对应的矩阵(NDC坐标系):
   | 2/w      0          0           0  |
   | 0       2/h         0           0  |
   | 0        0        -2/d   -(near+far)/d |
   | 0        0          0           1  |
其中,fovy - height of the view volume in camera coordinates。
h = height (= fovy)
w = aspectRatio * h
d = far - near

公式推导:

设(x, y, z, w)为视点坐标,(x’, y’, z’, w’)为投影坐标,(Px, Py, Pz, Pw)为NDC。
近平面距离为n,远平面距离为f,视口宽为w,高为h。
 x’ = x 
y’ = y
映射到NDC ([-1, 1]),
 Px = 2 * x’/ w = 2 * x / w
 Py = 2 * y’ / h = 2 * y / h
由于z坐标投影后不参与绘图,用于可见性判断,只要保证Pz与z呈线性关系,即Pz=a*z+b
将(-n,-1), (-f, 1) 代入得
 a = -2 / (f - n)
b = -(n + f) / (f - n)
Pz = -2/ (f - n)*z - (n + f) / (f - n)
即等价于
 | x |       | 2/ w   0          0                      0           |
 | y |       |  0    2 / h       0                       0           |
 | z |   *  |  0      0     -2/ (f – n)   -( n + f) / (f - n) |
 | 1 |      |  0       0         0                      1            |

3) Perspective
public void setPerspective(float fovy, float aspectRatio, float near, float far)
 透视投影,即离视点近的物体大,离视点远的物体小,符合人们心理习惯。
M3G Specification中已经给出了对应的矩阵(NDC坐标系):
   | 1/w      0          0           0       |
   | 0       1/h         0            0      |
   | 0        0     -(near+far)/d   -2*near*far/d |
   | 0        0          -1           0      |
其中,fovy - field of view in the vertical direction, in degrees。
h = tan ( fovy/2 )
w = aspectRatio * h
d = far - near

公式推导:

设(x, y, z, w)为视点坐标,(x’, y’, z’, w’)为投影坐标,(Px, Py, Pz, Pw)为NDC。
近平面距离为n,远平面距离为f,近平面宽为W,高为H。
由相识三角形可以得到
x’ = -n * x / z
y’ = -n * y / z
映射到NDC ([-1, 1]),可得
 Px = x’/ (W/2) = -2*n*x / z * W
 Py = y’/ (H/2) = -2*n*y / z * H
由于x’, y’与1/ z有线性关系,只要保证Pz与1/z呈线性关系,即Pz=a/z+b
将(-n,-1), (-f, 1) 代入得
 a = 2*n*f / f - n
b = f + n / f – n
Pz = 2*n*f / (f - n)*z + (f+n) / (f - n)
由于最后会除以w分量,所以可以把共同项写入w分量:
 -zPx = 2*n*x / W
 -zPy = 2*n*y / H
 -zPz = -2*n*f / (f – n) - (f+n) / (f - n) * z
  w = -z
即等价于
 | x |       | 2*n / W   0                 0                      0            |
 | y |       |  0       2*n / H             0                     0            |
 | z |   *  |  0           0        - (f+n) / (f - n)   -2*n*f / (f – n) |
 | 1 |      |  0           0                 -1                     0             |

引入视角fovy,即:
 h = tan ( fovy/2 ) = (H/2) / n = H / 2*n
 w = aspectRatio * h = W / 2*n
d = f - n

=============

不知道有没有下文。。。。

 

你可能感兴趣的:(Blog,float,parallel)