原文 /
很多年前(80年代中期),我在一家拥有Silicon Graphics工作站的公司工作。在旨在展示SGI机器高端图形的少数演示中,有一个模拟了一个小线框网格中的波传播。通过更改网格中的点的高度然后让模拟运行来玩游戏非常有趣。并且SGI机器足够快,结果动画只是令人着迷。
在WPF中重新创建这个水模拟似乎是一个很好的方式来学习WPF中的3D图形。(最终结果在这里)。
第一步是找到一种模拟水中波传播的算法。事实证明,有一种非常简单的算法可以简单地通过获取相邻点的平均高度来实现期望的效果。在2D Water上的文章中详细描述了基本算法。“ 水效应解释”中也描述了相同的算法。
下一步是设置3D视口及其组成元素。我使用了两种不同的定向灯,在水面上创造了更多的对比度,同时为水面定义了漫反射和镜面反射材料特性。
这是相关的XAML。请注意,meshMain是包含水面的网格。
1 2 3 4 五 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 三十 31 32 33 34 35 36 37 38 39 40 41 | < Viewport3D Name = "viewport3D1" Margin = "0,8.181,0,0" Grid.Row = "1" > < Viewport3D.Camera > < PerspectiveCamera x:Name = "camMain" Position = "48 7.8 41" LookDirection = "-48 -7.8 -41" FarPlaneDistance = "100" UpDirection = "0,1,0" NearPlaneDistance = "1" FieldOfView = "70" > </ PerspectiveCamera > </ Viewport3D.Camera > < ModelVisual3D x:Name = "vis3DLighting" > < ModelVisual3D.Content > < DirectionalLight x:Name = "dirLightMain" Direction = "2, -2, 0" /> </ ModelVisual3D.Content > </ ModelVisual3D > < ModelVisual3D > < ModelVisual3D.Content > < DirectionalLight Direction = "0, -2, 2" /> </ ModelVisual3D.Content > </ ModelVisual3D > < ModelVisual3D > < ModelVisual3D.Content > < GeometryModel3D x:Name = "gmodMain" > < GeometryModel3D.Geometry > < MeshGeometry3D x:Name = "meshMain" > </ MeshGeometry3D > </ GeometryModel3D.Geometry > < GeometryModel3D.Material > < MaterialGroup > < DiffuseMaterial x:Name = "matDiffuseMain" > < DiffuseMaterial.Brush > < SolidColorBrush Color = "DarkBlue" /> </ DiffuseMaterial.Brush > </ DiffuseMaterial > < SpecularMaterial SpecularPower = "24" > < SpecularMaterial.Brush > < SolidColorBrush Color = "LightBlue" /> </ SpecularMaterial.Brush > </ SpecularMaterial > </ MaterialGroup > </ GeometryModel3D.Material > </ GeometryModel3D > </ ModelVisual3D.Content > </ ModelVisual3D > </ Viewport3D > |
接下来,我们创建一个WaveGrid类,实现上述基本算法。基本思想是我们维护两个独立的网格数据缓冲区 - 一个表示水的当前状态,一个表示先前状态。 WaveGrid将此数据存储在两个Point3DCollection对象中。在我们运行模拟时,我们交替使用哪个缓冲区并将我们的MeshGeometry3D.Positions属性附加到最新的缓冲区。请注意,我们只是改变点的垂直高度 - 即Y值。
WaveGrid还建立了对网格的三角形索引,在Int32Collection这也将可以连接到我们的MeshGeometry3D。
所有有趣的东西都发生在ProcessWater中。这是我们实现文章中描述的平滑算法的地方。由于我想要对网格中的每个点进行完全动画处理,因此我不仅处理了具有四个相邻点的内部点,而且还处理了网格边缘上的点。当我们添加相邻点的高度值时,我们会跟踪我们找到的邻居数量,以便我们可以正确地进行平均。
每个点的最终值是平滑(邻居的平均高度)和“速度”的函数,它基本上是 - 在最后一次迭代期间距离均衡的距离是多少?然后我们还应用阻尼因子,因为波将逐渐失去其幅度。
这是WaveGrid类的完整代码:
1 2 3 4 五 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 三十 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 |
本文发布于:2024-02-02 19:11:31,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170687228945855.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |