WPF实现3D粒子波浪效果

本文实例为大家分享了WPF实现3D粒子波浪效果的具体代码,供大家参考,具体内容如下

实现效果如下:

步骤:

1、3D粒子类Particle.cs

public class Particle

{

public Point3D Position;//位置

public double Size;//尺寸

public int XIndex;//X位置标识

public int YIndex;//Y位置标识

}

2、粒子系统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();

}

以上是 WPF实现3D粒子波浪效果 的全部内容, 来源链接: utcz.com/z/355834.html

回到顶部