编译环境:XXXXXT 2005代码语言:XXXXXT当初准备用于显示3D电子地图用,后来项目取消,权当练了练手。
速度呢——在有光照强度无纹理渲染2000个三角面的情况下可以达到10以上的帧率,普通3D地图处理足够用了。
核心算法:
1、快速开平方算法:
使用的是Quake里面的快速开平方根算法。
这是C++的托管算法:
float CWOOD::Math::Sqrt( float x ) {
long i;
float y, r;
y = x * 0.5f;
i=*(long*)&x;
i = 0x5f3759df - ( i >> 1 );
r=*(float*)&i;
r = r * ( 1.5f - r * r * y );
return x*r;
}
这是C++的非托管算法:
static float ReciprocalSqrt( float x ) {
long i;
float y, r;
y = x * 0.5f;
i=*(long*)&x;
i = 0x5f3759df - ( i >> 1 );
r=*(float*)&i;
r = r * ( 1.5f - r * r * y );
return r;
}
static float Sqrt( float x ) {
long i;
float y, r;
y = x * 0.5f;
i=*(long*)&x;
i = 0x5f3759df - ( i >> 1 );
r=*(float*)&i;
r = r * ( 1.5f - r * r * y );
return x*r;
}
float QuickSqrt( float x ) {
float d;
_asm
{
mov eax,x;
sub eax,0x3f800000;
sar eax,1;
add eax,0x3f800000;
mov d,eax;
}
return d;
}
2、三角函数的SIN和COS用的是查表法,虽然精度低,但效率是自带算法的好几倍。
3、3D投影到2D算法:
实际上非常简单:
假设3D坐标平面中Z轴指向观察者。
假设2D坐标为标准的笛卡尔坐标系,坐标中心位于观察窗平面中心呢,观察窗平面尺寸为(sw,sh)。
设f为相机与视平面的距离。
设d为3D空间中的一个点(x,y,z)则
根据透视原理,设s为放大率,则点d在2D屏幕上的投影的放大率为:s=fl/(fl-z)注意z>=fl则不绘制。
则点d在2D平面上的投影D为:
Dx=dx * scale + sw/2
Dy=dy * scale + sh/2
这样就构建好一个3D投影系统。
4、矩阵及其他数学算法:
代码太多,包括在附件中,有兴趣的可以下载玩玩。
上图:
投影测试1:
投影测试2(后面的小圆圈是2D坐标):
圆球做的光照测试模型:
曲面做的光照测试模型:
下载地址:
3DTest New.rar
679.41KB
RAR
24次下载
200字以内,仅用于支线交流,主线讨论请采用回复功能。