WPF實現(xiàn)3D粒子波浪效果
更新時間:2020年09月04日 08:14:25 作者:RunnerDNA
這篇文章主要為大家詳細(xì)介紹了WPF實現(xiàn)3D粒子波浪效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
本文實例為大家分享了WPF實現(xiàn)3D粒子波浪效果的具體代碼,供大家參考,具體內(nèi)容如下
實現(xiàn)效果如下:

步驟:
1、3D粒子類Particle.cs
public class Particle
{
public Point3D Position;//位置
public double Size;//尺寸
public int XIndex;//X位置標(biāo)識
public int YIndex;//Y位置標(biāo)識
}
2、粒子系統(tǒng)ParticleSystem類
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()
{
// 計算粒子位置及大小
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();
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C#中IEnumerator<T>和IEnumerable的區(qū)別
在C#中,IEnumerator<T>和IEnumerable是用于實現(xiàn)迭代的接口,本文主要介紹了C#中IEnumerator<T>和IEnumerable的區(qū)別,具有一定的參考價值,感興趣的可以了解一下2024-01-01
在C#中如何使用正式表達式獲取匹配所需數(shù)據(jù)
本文給大家分享C#中如何使用正式表達式獲取匹配所需數(shù)據(jù) ,非常實用,對正則表達式獲取匹配相關(guān)知識感興趣的朋友一起學(xué)習(xí)吧2016-03-03
C#實現(xiàn)訪問Web API Url提交數(shù)據(jù)并獲取處理結(jié)果
Web API 是 Web 服務(wù)器和 Web 瀏覽器之間的應(yīng)用程序處理接口,我們常見的模式是訪問 Web API Url 地址,并獲取 Json 、XML或其它指定格式的處理結(jié)果, 本文我們介紹了使用C#實現(xiàn)訪問Web API Url提交數(shù)據(jù)并獲取處理結(jié)果,需要的朋友可以參考下2024-05-05
C#窗口實現(xiàn)定時關(guān)機系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C#窗口實現(xiàn)定時關(guān)機系統(tǒng),具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-07-07

