网页功能: 加入收藏 设为首页 网站搜索  
3D 粒子系统
发表日期:2007-01-16作者:[转贴] 出处:  

通常我们所编程的粒子系统有 2D 的数据结构 , 如

CPaticle
{
    int x,int y;
    int VelocityX,VelocityY;
    int AccelerateX,int AccelerateY;
    ......
};

如果稍稍扩展一下这个数据结构,掺入一点 3D 的思想和一些小技巧 ... 就能作出完全不同的 FX

下面我们先来看一看 3D 编程世界吧 !

我们现在就生活在 3D 的空间里 , 左右手系均可以表示,而我习惯右手系统。

伸右手食指指自己脑门 , 中指,拇指展开 , 对 , 大拇指是 Y, 中指 X, 食指为 Z. 就是这个意思。

 

顶点 :3D 空间里我们可以用 3 个分量定义顶点 , 这 3 个分量表示空间点在 X,Y,Z 上的投影。

矢量 : 而两个顶点相连 , 并表示出一点指向另一点就是矢量。

首先我们需要数据结构表示它们。

3D 应用程序的主要目标就是要变换它们,并把他们投影到屏幕系统。

矩阵

- 矩阵 (Matrix) 无处不在 , 在我们的周围 , 就在这间屋子里。你能在窗户往外看到它 , 在电视里看到它 . 当你上班,去教堂或者缴税你可以感觉到它。你眼前的世界让你看不到真实。 - 呵呵 , 不是这个解释。我们说的线性代数里的那种矩阵 。通常是 3x3 或 4x4 的 2 维数组。 3x3 表平面变换, 4x4 可以表示空间变换。


现在我们唯一需要知道的就是如何使用矩阵执行我们的 3D 操作 , 技巧很简单,我们把我们的视点乘上几个变换的子矩阵就可以了。如下式 :

camera = rotx( anglex ) * roty( angley ) * rotz( anglez )

如果我们需要,我们可以增加平移,缩放 , 取景。要注意的是矩阵乘法是不可逆的,所以乘上矩阵的顺序相当重要 ( 每本书都强调这点 , 还是有人犯错 ) 。矩阵乘法的方法如下 :

// resulting matrix is stored in r

for (int i=0; i<4; i++) // 行循环
    for (int j=0; j<4; j++) // 列循环
    {
        r[i][j] = m[i][0] * b[0][j] + m[i][1] * b[1][j] + m[i][2] * b[2][j] + m[i][3] * b[3][j];
    }

如果我们需要平移我们的矩阵,我们必须按如下法则平移我们的矢量 :

// resulting vector is stored in r

r[0] = v[0] * m[0][0] + v[1] * m[1][0] + v[2] * m[2][0] + m[3][0];

r[1] = v[0] * m[0][1] + v[1] * m[1][1] + v[2] * m[2][1] + m[3][1];

r[2] = v[0] * m[0][2] + v[1] * m[1][2] + v[2] * m[2][2] + m[3][2];

如果还不清楚,最好买本图形学或者 OpenGL 的书,里面有大量空间变换的讲解。

那就是矢量转换的全部,但是要完成该效果还有其他的问题。

  转换 3D-2D :现在我们必须显示 3D 数据到我们的 2D 屏幕 . 这样我们必须把屏幕模型化为 3D 空间的一个平面。那就是投影平面。所以转换 3D 坐标到 2D ,我们只需要在该平面上投影。假想有一束光线通过照相机,射过我们的平面。

zs 是照相机到投影平面的距离。 z 是视点到点 X 的在 Z 轴投影的距离。

给出这些数据,根据泰利斯的理论,我们知道如下公式: ( 相似三角形的原理 )

xs = x * zs / z

ys = y * zs / z

我们还需要增加两个常量和系数以便让我们的坐标系原点在屏幕的中间。

xs = x * XSCALE / z + XCENTRE

ys = y * YSCALE / z + YCENTRE

现在既然知道了点在投影平面的位置 , 现在我们应该在这个位置绘画了。

反走样像素

现在我们需要在屏幕上画出我们的粒子了。我们应该避免简单的绘制像素。因为那样看上去很糟糕 , 那样移动起来很多锯齿 。所以我们需要简单的反走样像素绘制,也许你们知道这个 Wu 像素技术。


这个理论的基本思想是真正理想的点是在几个设备像素的区域内部,这将增加几次乘法, 4 次内存写入,但是为了提高输出质量,这是值得的。如下的代码画出一个反走样点 :

buffer[offs] = (1.0-sx)*(1.0-sy);

buffer[offs+1] = sx*(1.0-sy);

buffer[offs+RESX] = (1.0-sx)*sy;

buffer[offs+RESX+1] = sx*(1.0-sy);

sx,sy 是 0.0 到 1.0 的浮点数 .

( 理论上是这样,但你永远不要真用 Float Point 来生成屏幕像素 ... 回忆微机原理里的定点数运算吧 !)

你能够绘制粒子为闪光,和各类精灵。但是最好的效果就是增加粒子的强度到屏幕上。不要忘记做溢出检查。

图象缩放

这是个简单的技术,但是看上去棒极了。基本的思想是我们使用前一帧图象并且拷贝一小块放大到我们需要的尺寸,再模糊 (Blur, 现在我想全国人民都应该知道 Blur 是如何编程实现了吧 ! 其实可以再施加其他的 Filter, 比如 Edge,Emboss ,又可以做出完全不同的 FX) 它。再把该帧画到上边。这将产生很酷的光的效果,就象闪耀的亮光穿过浓雾一样 ( 丁达耳现象 ?... 让我想起我最喜爱的化学课 ) 。

以下的代码找到每个像素到给定点的距离,再按这个距离放大 ( 工作在 VGA 13H 模式 )

long offs = 0;

for (j=0; j<200; j++)
    for (i=0; i<320; i++)
    {
        ny = sy+(j-sy)*YSCALE;
        nx = sx+(i-sx)*XSCALE;
        dst[offs] = src[ny*320+nx];
    }

这些代码应该被彻底优化。你能加上一些简单的 sin 函数调节,可以产生一些难以预想的效果。

最后要说的是一但你进入 3D 编程,你发现你将很难再回到 2D 的效果。现在需要记住,伟大的视觉效果综合了 2D 和 3D 的技术。
 

 
我来说两句】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 3D 粒子系统
本类热点文章
  Particle Fire [粒子火焰]
  wu反走样(Anti-aliased)直线
  反走样技术之一 —— Wu像素
  粒 子 系 统
  3D 粒子系统
  Real-time Cloth Deformation [实时变形..
  Ripple [水波]
  碰撞检测和粒子的交互作用
  Particle System Overview [粒子系统概..
  wu像素
  图象特效-等离子体(Plasma)
  制作爆炸效果
最新分类信息我要发布 
最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放  
Copyright ©2003-2024 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.00328