PS:自己翻译的,转载请著明出处
简单的图象模板
Jesse Chounard
前言
这是一个非常简单的方法去创建一个模板从一个纹理中,你可以使用粒子效果。我使用这个效果在我的xbox在线游戏社区的主要屏幕中。一个类似的效果可以看到在Braid的开始,这里游戏的标题被显示。
Getting Started-Brute Force
让我们开始这个brute forch方法。我们想要从我们图象的某处象素没有完全透明(意思是alpha值不是0)的随机的X和Y值。
步骤:
1.从图象中得到象素数据。
2.产生随机的X和Y值
3.测试alpha值在这个位置上,如果是0,返回到步骤2并且在试一次。
1 Vector2 BruteForceRandomPosition(Texture2D texture)
2 {
3 Color[] colorData = new Color[texture.Width * texture.Height];
4 texture.GetData<Color>(colorData);
5 do
6 {
7 int x = random.Next(texture.Width);
8 int y = random.Next(texture.Height);
9 if (colorData[y * texture.Width + x].A != 0)
10 {
11 return new Vector2(x, y);
12 }
13 } while (true);
14 }
2 {
3 Color[] colorData = new Color[texture.Width * texture.Height];
4 texture.GetData<Color>(colorData);
5 do
6 {
7 int x = random.Next(texture.Width);
8 int y = random.Next(texture.Height);
9 if (colorData[y * texture.Width + x].A != 0)
10 {
11 return new Vector2(x, y);
12 }
13 } while (true);
14 }
Optimization(最优化)
虽然它工作了,但是这里有些严重的问题。
1.每一次我们从图象中读出颜色数据,我们需要一个随机的位置。不仅是缓慢的,而且我们不断的分配并且释放我们不需要的内存块。
2.由于我们的图象大部分是透明的部分,,我们可以用相当长的时间循环直到我们找一个有效的象素。
幸运的是,这是一个非常简单的事情,用一个预处理步骤处理。事实上,我建议你使用这个Content Pipeline去实现这个,并且移动所有正在绘制的粒子到GPU中,但是这是超出了本文的范围位。
步骤:
1.从图象中得到象素数据。
2.通过查看整个图像,逐个逐个象素的看。如果alpha是非零的,添加位置到象素位子列表中。
3.产生一个随机数在0到表单的长度之间。使用它作为表单的偏移量,并且我们有一个有效的象素位置。
1 List<Vector2> GenerateTemplate(Texture2D texture)
2 {
3 List<Vector2> templateData = new List<Vector2>();
4 Color[] colorData = new Color[texture.Width * texture.Height];
5 texture.GetData<Color>(colorData);
6 for (int y = 0; y < texture.Height; y++)
7 {
8 for (int x = 0; x < texture.Width; x++)
9 {
10 if (colorData[y * texture.Width + x].A != 0)
11 {
12 templateData.Add(new Vector2(x, y));
13 }
14 }
15 }
16 return templateData;
17 }
18 Vector2 RandomFromTemplate(List<Vector2> templateData)
19 {
20 return templateData[random.Next(templateData.Count)];
21 }
2 {
3 List<Vector2> templateData = new List<Vector2>();
4 Color[] colorData = new Color[texture.Width * texture.Height];
5 texture.GetData<Color>(colorData);
6 for (int y = 0; y < texture.Height; y++)
7 {
8 for (int x = 0; x < texture.Width; x++)
9 {
10 if (colorData[y * texture.Width + x].A != 0)
11 {
12 templateData.Add(new Vector2(x, y));
13 }
14 }
15 }
16 return templateData;
17 }
18 Vector2 RandomFromTemplate(List<Vector2> templateData)
19 {
20 return templateData[random.Next(templateData.Count)];
21 }
Conclusion(结论)
在示例代码中,我们包含一个非常简单的粒子系统,所以你可以看见在活动。粒子超出了这篇文章的范围,并且这里有很多的文章关于高性能的粒子系统,所以我提醒你去查找他们。
源代码:http://www.ziggyware.com/readarticle.php?article_id=218
(完)