现在的位置: 首页 > 综合 > 正文

3D 贴图算法

2013年08月28日 ⁄ 综合 ⁄ 共 1809字 ⁄ 字号 评论关闭

 

第一个公式:基本空间坐标变换

电脑屏幕是二维的,怎么体现出三维的感觉了。那就只能用改变物体在屏幕上的大小来给人,物体远近的感觉了。这个公式很简单,基于人的视觉感受,东西离自己越远就会越小,表示方法如下:

公式: X1=(d/Z)*X

d 是人眼到屏幕的距离,z 是到人眼的距离,X是某一点在平面的相对位置,X1是该点在屏幕投影的相对位置。图中黑色框框就是电脑屏幕。设一个平面距离屏幕为0时,在屏幕上展现的就是它最大的样子。

看看这个公式:d是固定的,X也有个最大值,那么只要平面离屏幕越远,x就会越小。符合人的视觉感受。

 

第二个公式:贴图坐标变换

 

 因为一张图,投影到屏幕只会比原来小,所以根据屏幕上的位置去原图找相应的点

如图,假设原图的X,Y,0投影到屏幕的 U,V,0

那么U,V,0空间坐标系中任意一的点W对应到X,Y,0坐标系中了?

根据第一个公式可以找到WX,Y,0对应的向量P

P=(Pz/d)W

我们要的是P的坐标(x,y),变形后有:

A=V X O

B=0 X U

C=U X V

x=A.W/C.W

y=B.W/C.W 

注意:“X”是交集,而“.”是点乘

下面是代码实现

    public class Method1 extends ScanRenderer {  //屏幕上的一条扫描线

        public void render(int offset, int left, int right) {  //放入象素的起点,扫描的起点,终点
            for (int x=left; x<=right; x++) {    //每行从左往右扫
                int tx = (int)(a.getDotProduct(viewPos) /       //getDotProduct是点乘//viewPos是屏幕上的一点,我们对它经过变换去图中找相应的象素

                    c.getDotProduct(viewPos));
                int ty = (int)(b.getDotProduct(viewPos) /
                    c.getDotProduct(viewPos));
                doubleBufferData[offset++] =               //从图像中找到相应位置的象素,放入数组
                    currentTexture.getColor(tx, ty);
                viewPos.x++;          //下一个屏幕上的点
            }
        }
    }

下面这个是优化过的代码:

基于这样的公式变形:

u=A.V=Ax.Vx+Ay.Vy

V的同一行中的下一点V'横坐标是 Vx+1

此时u'=A.V'=Ax.Vx+Ay.Vy+Ax

        =u+Ax

//////////////////////////////////////////////////////////////////

    public class Method2 extends ScanRenderer {

        public void render(int offset, int left, int right) {
            float u = a.getDotProduct(viewPos);
            float v = b.getDotProduct(viewPos);
            float z = c.getDotProduct(viewPos);
            float du = a.x;
            float dv = b.x;
            float dz = c.x;
            for (int x=left; x<=right; x++) {
                doubleBufferData[offset++] =
                    currentTexture.getColor(
                    (int)(u/z), (int)(v/z));
                u+=du;
                v+=dv;
                z+=dz;
            }
        }
    }

 

抱歉!评论已关闭.