本文实例为大家分享了WPF实现3D粒子波浪效果的具体代码,供大家参考,具体内容如下
实现效果如下:
步骤:
1、3D粒子类Particle.cs
1
2
3
4
5
6
7
|
public class Particle { public Point3D Position; //位置 public double Size; //尺寸 public int XIndex; //X位置标识 public int YIndex; //Y位置标识 } |
2、粒子系统ParticleSystem类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
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布局
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
< 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、交互逻辑
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
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(); } |
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/dnazhd/article/details/107314906