WPF實(shí)現(xiàn)3D粒子波浪效果
本文實(shí)例為大家分享了WPF實(shí)現(xiàn)3D粒子波浪效果的具體代碼,供大家參考,具體內(nèi)容如下
實(shí)現(xiàn)效果如下:

步驟:
1、3D粒子類(lèi)Particle.cs
public class Particle
{
public Point3D Position;//位置
public double Size;//尺寸
public int XIndex;//X位置標(biāo)識(shí)
public int YIndex;//Y位置標(biāo)識(shí)
}
2、粒子系統(tǒng)ParticleSystem類(lèi)
public class ParticleSystem
{
private readonly List<Particle> _particleList;
private readonly GeometryModel3D _particleModel;
private readonly int SEPARATION = 100;
public ParticleSystem(int amountX, int amountY, Color color, int Size)
{
XParticleCount = amountX;
YParticleCount = amountY;
_particleList = new List<Particle>();
_particleModel = new GeometryModel3D { Geometry = new MeshGeometry3D() };
var e = new Ellipse
{
Width = Size,
Height = Size
};
var b = new RadialGradientBrush();
b.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, color.R, color.G, color.B), 0.25));
b.GradientStops.Add(new GradientStop(Color.FromArgb(0x00, color.R, color.G, color.B), 1.0));
e.Fill = b;
e.Measure(new Size(Size, Size));
e.Arrange(new Rect(0, 0, Size, Size));
Brush brush = null;
var renderTarget = new RenderTargetBitmap(Size, Size, 96, 96, PixelFormats.Pbgra32);
renderTarget.Render(e);
renderTarget.Freeze();
brush = new ImageBrush(renderTarget);
var material = new DiffuseMaterial(brush);
_particleModel.Material = material;
}
public int XParticleCount { get; set; }
public int YParticleCount { get; set; }
public Model3D ParticleModel => _particleModel;
private double _count = 0;
public void Update()
{
// 計(jì)算粒子位置及大小
for (int ix = 0; ix < XParticleCount; ix++)
{
for (int iy = 0; iy < YParticleCount; iy++)
{
foreach (var p in _particleList)
{
if(p.XIndex == ix && p.YIndex == iy)
{
p.Position.Z = (Math.Sin((ix + _count) * 0.3) * 100) + (Math.Sin((iy + _count) * 0.5) * 100);
p.Size = (Math.Sin((ix + _count) * 0.3) + 1) * 8 + (Math.Sin((iy + _count) * 0.5) + 1) * 8;
}
}
}
}
_count += 0.1;
UpdateGeometry();
}
private void UpdateGeometry()
{
var positions = new Point3DCollection();
var indices = new Int32Collection();
var texcoords = new PointCollection();
for (var i = 0; i < _particleList.Count; ++i)
{
var positionIndex = i * 4;
var indexIndex = i * 6;
var p = _particleList[i];
var p1 = new Point3D(p.Position.X, p.Position.Y, p.Position.Z);
var p2 = new Point3D(p.Position.X, p.Position.Y + p.Size, p.Position.Z);
var p3 = new Point3D(p.Position.X + p.Size, p.Position.Y + p.Size, p.Position.Z);
var p4 = new Point3D(p.Position.X + p.Size, p.Position.Y, p.Position.Z);
positions.Add(p1);
positions.Add(p2);
positions.Add(p3);
positions.Add(p4);
var t1 = new Point(0.0, 0.0);
var t2 = new Point(0.0, 1.0);
var t3 = new Point(1.0, 1.0);
var t4 = new Point(1.0, 0.0);
texcoords.Add(t1);
texcoords.Add(t2);
texcoords.Add(t3);
texcoords.Add(t4);
indices.Add(positionIndex);
indices.Add(positionIndex + 2);
indices.Add(positionIndex + 1);
indices.Add(positionIndex);
indices.Add(positionIndex + 3);
indices.Add(positionIndex + 2);
}
((MeshGeometry3D)_particleModel.Geometry).Positions = positions;
((MeshGeometry3D)_particleModel.Geometry).TriangleIndices = indices;
((MeshGeometry3D)_particleModel.Geometry).TextureCoordinates = texcoords;
}
public void SpawnParticle(double size)
{
// 初始化粒子位置和大小
for (int ix = 0; ix < XParticleCount; ix++)
{
for (int iy = 0; iy < YParticleCount; iy++)
{
var p = new Particle
{
Position = new Point3D(ix * SEPARATION - ((XParticleCount * SEPARATION) / 2), iy * SEPARATION - ((YParticleCount * SEPARATION) / 2), 0),
Size = size,
XIndex = ix,
YIndex = iy,
};
_particleList.Add(p);
}
}
}
}
3、Viewport布局
<Viewport3D Name="World">
<Viewport3D.Camera>
<PerspectiveCamera Position="0,50,1000" LookDirection="0,2,-1" UpDirection="0,-1,-1" FieldOfView="10000" NearPlaneDistance="10" FarPlaneDistance="8000"/>
</Viewport3D.Camera>
<Viewport3D.Children>
<ModelVisual3D>
<ModelVisual3D.Content>
<Model3DGroup x:Name="WorldModels">
<AmbientLight Color="#FFFFFFFF" />
</Model3DGroup>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D.Children>
</Viewport3D>
4、交互邏輯
private readonly ParticleSystem _ps;
private DispatcherTimer _frameTimer;
public MainWindow()
{
InitializeComponent();
_frameTimer = new DispatcherTimer();
_frameTimer.Tick += OnFrame;
_frameTimer.Interval = TimeSpan.FromSeconds(1.0 / 60.0);
_frameTimer.Start();
_ps = new ParticleSystem(50, 50, Colors.White, 30);
WorldModels.Children.Add(_ps.ParticleModel);
_ps.SpawnParticle(30);
KeyDown += Window_KeyDown;
Cursor = Cursors.None;
}
private void Window_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Escape)
Close();
}
private void OnFrame(object sender, EventArgs e)
{
_ps.Update();
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- WPF實(shí)現(xiàn)3D翻牌式倒計(jì)時(shí)特效
- WPF實(shí)現(xiàn)時(shí)鐘特效
- WPF實(shí)現(xiàn)文本描邊+外發(fā)光效果的示例代碼
- WPF實(shí)現(xiàn)動(dòng)畫(huà)效果
- WPF實(shí)現(xiàn)平面三角形3D運(yùn)動(dòng)效果
- WPF實(shí)現(xiàn)文字粒子閃爍動(dòng)畫(huà)效果
- WPF實(shí)現(xiàn)3D立方體波浪墻效果
- WPF實(shí)現(xiàn)進(jìn)度條實(shí)時(shí)更新效果
- WPF實(shí)現(xiàn)轉(zhuǎn)圈進(jìn)度條效果
- WPF實(shí)現(xiàn)流光動(dòng)畫(huà)特效
相關(guān)文章
C#使用Socket快速判斷數(shù)據(jù)庫(kù)連接是否正常的方法
這篇文章主要介紹了C#使用Socket快速判斷數(shù)據(jù)庫(kù)連接是否正常的方法,涉及C#中socket操作的相關(guān)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04
C#微信公眾號(hào)開(kāi)發(fā)之使用MessageHandler簡(jiǎn)化消息處理流程
這篇文章介紹了C#微信公眾號(hào)開(kāi)發(fā)之使用MessageHandler簡(jiǎn)化消息處理流程,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06
C#實(shí)現(xiàn)向指定文本文件添加內(nèi)容的方法
這篇文章主要介紹了C#實(shí)現(xiàn)向指定文本文件添加內(nèi)容的方法,涉及C#操作文本文件的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-04-04
c# 在windows中操作IIS設(shè)置FTP服務(wù)器的示例
這篇文章主要介紹了c# 在windows中操作IIS設(shè)置FTP服務(wù)器的示例,幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下2021-03-03

