

科学可视化经常需要同一数据的两种视图:显示地形的3D曲面和显示精确值分布的2D等高线热力图。大多数图表库将这些视为完全独立的图表类型,具有独立的数据存储、独立的渲染管线和独立的内存分配。ProEssentials做了根本不同的事情——它从同一个GPU Compute Shader管线渲染两个视图,读取同一个数据指针,使用零额外内存。
本页比较所有五个WPF库的3D和2D科学图表功能,通过材料表面扫描应用的真实生产代码演示共享内存架构,并详细介绍只有ProEssentials提供的图表类型——包括4D按值着色曲面、从点云的内置Delaunay三角剖分,以及用于任意3D几何体的自定义多边形数据。
See first hand the benefit of zero-copy shared-memory: clone, build, run the 3d plus 2d material surface scan demo on GitHub.下表比较了五个WPF库的每种科学图表类型。SciChart和LightningChart提供强大的3D覆盖,各支持13种类型中的12种,但都不提供点云Delaunay三角剖分。Syncfusion通过其SfSurfaceChart和SfChart3D控件覆盖7种类型。DevExpress通过其Chart3DControl覆盖5种。ProEssentials是唯一覆盖下面列出的所有十三种图表类型的库——也是唯一在曲面、等高线、热力图和实时3D上提供GPU Compute Shader渲染的库。
| Chart Type | ProEssentials | SciChart | LightningChart | Syncfusion | DevExpress |
|---|---|---|---|---|---|
| 3-D Surface (shaded) | ✅ GPU compute shader | ✅ | ✅ | ✅ | ✅ |
| 3-D Wireframe | ✅ GPU compute shader | ✅ | ✅ | ✅ | ❌ |
| 3-D Surface + Contour overlay | ✅ GPU compute shader | ✅ | ✅ | ✅ | ✅ |
| 3-D Scatter | ✅ | ✅ | ✅ | ✅ | ✅ |
| 3-D Bar | ✅ | ✅ | ✅ | ✅ | ✅ |
| 3-D Waterfall | ✅ | ✅ | ✅ | ❌ | ❌ |
| 2-D Contour / Heatmap (GPU) | ✅ GPU compute shader | ✅ Heatmap | ✅ | ✅ | ✅ |
| 2-D Contour Lines | ✅ | ✅ | ✅ | ✅ | ❌ |
| 4-D (XYZ + W-data / color) | ✅ GPU compute shader | ✅ | ✅ | ❌ | ❌ |
| Delaunay triangulation | ✅ Built-in from point cloud | ❌ | ❌ | ❌ | ❌ |
| Custom polygon data (3-D geometry) | ✅ Raw vertices + color | ✅ | ✅ | ❌ | ❌ |
| Real-time 3-D | ✅ GPU compute shader | ✅ | ✅ | ❌ | ❌ |
| 3-D annotations (XYZ positioned) | ✅ Text, symbol, polygon | ✅ | ✅ | ❌ | ❌ |
ProEssentials支持本比较中的全部13种科学图表类型。SciChart和LightningChart各覆盖12种,Syncfusion覆盖7种,DevExpress覆盖5种。虽然五个库都提供一定程度的3D曲面图表,但只有ProEssentials提供点云内置Delaunay三角剖分,也只有ProEssentials通过零拷贝共享内存的统一GPU Compute Shader管线渲染曲面、等高线、热力图和实时3D。
以下代码摘录来自GigaPrime3D材料表面扫描演示——一个生产级WPF应用程序,将高分辨率表面扫描数据(最大6000 × 6000网格,3600万数据点)同时渲染为3D阴影曲面和2D等高线热力图。这不是简化的教程示例。这是在工业计量、半导体晶圆检测和地形分析应用中使用的代码模式。下面三个代码片段演示了共享内存声明、使用GPU Compute Shader的双重零拷贝数据加载,以及2D和3D视图之间的联动缩放同步。
应用程序分配一个足以容纳3600万高程值的单一静态float数组(sMyYData)——表面扫描的Y(高度)数据。X和Z数组分别保存列和行的网格坐标。这三个数组是整个应用程序中唯一的数据存储。没有任何图表控件会分配自己的副本。
// 36M points × 4 bytes = ~150 MB
// Passing shared app memory to both Pe3do and Pesgo saves ~150 MB
// Always best to save memory where we can
private static float[] sMyXData = new float[6000]; // cols max
private static float[] sMyZData = new float[6000]; // rows max
private static float[] sMyYData = new float[36000000]; // rows × cols max
// Pin smaller arrays (< 85 KB) so GC won't relocate them
private GCHandle _pinXHandle;
private GCHandle _pinZHandle;
public MainWindow()
{
_pinXHandle = GCHandle.Alloc(sMyXData, GCHandleType.Pinned);
_pinZHandle = GCHandle.Alloc(sMyZData, GCHandleType.Pinned);
// ...
}较小的X和Z数组(各<85KB)使用GCHandle固定以防止垃圾回收器移动它们。大的Y数组(最大144MB)位于大对象堆上,GC无论如何都不会移动它——不需要固定。这是在实际生产代码中重要的细节:在零拷贝图表所需的层面上理解.NET内存管理。
当用户加载新的表面扫描文件时,RefreshUi方法填充共享数组,然后将相同的指针传递给两个图表控件。关键行是UseDataAtLocation()——存储指针而不是复制——和ComputeShader = true——激活GPU端场景构建。注意Pesgo 2D等高线图表使用与Pe3do 3D曲面相同的ComputeShader属性和相同的UseDataAtLocation调用模式:
// ─── 3-D Surface (Pe3do) ─── GPU compute shader + zero-copy ───
Chart3DSurface.PeData.Subsets = _rows;
Chart3DSurface.PeData.Points = _cols;
Chart3DSurface.PeData.DuplicateDataX = DuplicateData.PointIncrement;
Chart3DSurface.PeData.DuplicateDataZ = DuplicateData.SubsetIncrement;
Chart3DSurface.PeData.ComputeShader = true; // GPU-side scene construction
// No data transfer — chart reads your array via pointer
Chart3DSurface.PeData.X.UseDataAtLocation(sMyXData, _cols);
Chart3DSurface.PeData.Y.UseDataAtLocation(sMyYData, size);
Chart3DSurface.PeData.Z.UseDataAtLocation(sMyZData, _rows);
// ─── 2-D Contour (Pesgo) ─── same GPU pipeline, same pointer ───
Chart2DContour.PeData.Subsets = _rows;
Chart2DContour.PeData.Points = _cols;
Chart2DContour.PeData.DuplicateDataX = DuplicateData.PointIncrement;
Chart2DContour.PeData.DuplicateDataY = DuplicateData.SubsetIncrement;
Chart2DContour.PeData.ComputeShader = true; // same GPU path as 3-D
// Same shared memory — no copy, no duplication
Chart2DContour.PeData.X.UseDataAtLocation(sMyXData, _cols);
Chart2DContour.PeData.Z.UseDataAtLocation(sMyYData, size);
Chart2DContour.PeData.Y.UseDataAtLocation(sMyZData, _rows);
Chart2DContour.PePlot.Method = SGraphPlottingMethod.ContourColors;两个图表现在都从sMyXData、sMyYData和sMyZData读取——相同的静态数组。3D曲面和2D等高线是相同数据的两个GPU渲染视图。更改源数组并在两个控件上调用ReinitializeResetImage()可立即更新两个视图。注意轴映射差异:Pe3do使用Y作为高程、Z作为深度,而Pesgo使用Z作为等高线值、Y作为空间轴。UseDataAtLocation在两种情况下都处理指针间接引用。
GigaPrime3D演示将两个视图链接,使2D等高线的缩放自动将3D曲面缩放到相同区域。当用户在等高线图表上拖拽缩放矩形时,PeZoomIn事件触发,代码读取等高线的缩放范围,将其作为手动轴范围应用到3D曲面,并触发高效重建:
// When user zooms the 2-D contour, sync the 3-D surface view
private void Chart2DContour_OnPeZoomIn(object sender, EventArgs e)
{
// Enable pixel shader culling — only render triangles in view
Chart3DSurface.PeGrid.Configure.DxPsManualCullXZ = true;
// Transfer 2-D zoom extents → 3-D manual axis range
Chart3DSurface.PeGrid.Configure.ManualScaleControlX = ManualScaleControl.MinMax;
Chart3DSurface.PeGrid.Configure.ManualMinX = Chart2DContour.PeGrid.Zoom.MinX;
Chart3DSurface.PeGrid.Configure.ManualMaxX = Chart2DContour.PeGrid.Zoom.MaxX;
Chart3DSurface.PeGrid.Configure.ManualScaleControlZ = ManualScaleControl.MinMax;
Chart3DSurface.PeGrid.Configure.ManualMinZ = Chart2DContour.PeGrid.Zoom.MinY;
Chart3DSurface.PeGrid.Configure.ManualMaxZ = Chart2DContour.PeGrid.Zoom.MaxY;
// Efficient rebuild — skip ranging, rebuild only vertices
Chart3DSurface.PeFunction.Force3dxVerticeRebuild = true;
Chart3DSurface.PeData.SkipRanging = true;
Chart3DSurface.PeFunction.Reinitialize();
Chart3DSurface.Invalidate();
}DxPsManualCullXZ是这里的关键性能属性——它启用像素着色器剔除,使缩放区域外的三角形被GPU丢弃而不是不可见地渲染。没有它,缩放3600万点曲面仍然会处理每个三角形,即使大多数在视图外。SkipRanging告诉引擎跳过CPU端的最小/最大数据扫描(因为轴限制是手动设置的,所以不必要),Reinitialize()在不清除缓存图像的情况下重建轴刻度。结果:缩放6000 × 6000曲面感觉是即时的。
上面的代码演示了ProEssentials在架构上最重要的功能:UseDataAtLocation()存储指向您现有数据数组的指针——它从不分配、从不复制、从不复制。Pe3do 3D曲面和Pesgo 2D等高线图表控件都持有对同一sMyYData数组的引用。数据在内存中只存在一次。
在GigaPrime3D演示中,6000 × 6000表面扫描包含3600万个float值——约150MB。每个图表将数据复制到内部存储的传统架构将消耗450MB:源数组150MB,3D曲面内部副本150MB,2D等高线内部副本150MB。ProEssentials总共消耗150MB——源数组,仅此而已。
这扩展到任意数量的视图。显示截面线轮廓的第三个图表将从相同的数组读取,没有额外的内存成本。显示表面值统计直方图的第四个图表可以引用相同的指针。内存消耗随数据大小而非可视化控件数量扩展。
每个竞争对手都需要每个图表单独的数据对象。SciChart需要3D曲面的新XyzDataSeries3D和2D热力图的单独UniformHeatmapDataSeries——两个完整副本。LightningChart需要每个图表实例的单独数据对象。在3600万点时,每个额外副本增加150MB分配、150MB GC跟踪内存和数据加载期间数秒的复制操作。
ProEssentials将您的数据视为单一事实来源。图表控件是数据的视图,而不是数据副本的所有者。这消除了一整类问题:同步错误、过时数据、内存膨胀以及维护重复托管数组的GC压力。
| Memory Factor | ProEssentials | Typical Competitor |
|---|---|---|
| Source data (6000 × 6000) | Your array (shared) | Your array (original) |
| 3-D surface copy | 0 MB — pointer | ~150 MB internal copy |
| 2-D contour copy | 0 MB — same pointer | ~150 MB second copy |
| Total for dual view | ~150 MB (data only) | ~450 MB (data + 2 copies) |
| Memory saved | ~300 MB | — |
3D曲面(Pe3do)和2D等高线(Pesgo)都使用相同的GPU Compute Shader管线——通过相同的PeData.ComputeShader = true属性激活。不是两个不同的GPU实现,而是一个统一的着色器管线应用于数据的两种不同视觉表示。
如上面的代码片段所示,相同的PeData.ComputeShader = true属性在Pe3do 3D曲面和Pesgo 2D等高线上都激活GPU加速渲染。底层Compute Shader管线相同:您的数据数组一次性上传到GPU内存,着色器在数千个GPU核心上并行处理网格——无论输出是带光照的3D曲面网格还是平面2D颜色映射等高线。
ProEssentials还提供Filter2D3D——专门为2D等高线数据设计的两级Compute Shader优化。在Pesgo上对250,000+点的数据集启用时,第一个着色器通道无损预过滤顺序数据,第二个通道构建等高线图像。这在不损失视觉保真度的情况下极大加速了大规模等高线渲染。
对于实时3D,ProEssentials提供StagingBuffers来维护数据数组的GPU端副本以实现高效的CPU到GPU传输,还有ReuseDataX和ReuseDataZ标志告诉着色器'只有高程变了——跳过重新处理网格坐标'。当以每秒10-30次更新的速度流式传输3D曲面数据时,这些优化很重要,因为它们消除了未更改轴上的冗余GPU工作。
| GPU Rendering | ProEssentials | SciChart | LightningChart | Syncfusion | DevExpress |
|---|---|---|---|---|---|
| 3-D surface GPU? | ✅ Compute shader | ✅ Game-engine pipeline | ✅ DirectX | ❌ No 3-D | ❌ No 3-D surface |
| 2-D contour GPU? | ✅ Same compute shader pipeline | ✅ Heatmap texture | ✅ DirectX | ❌ CPU only | ❌ CPU only |
| Same GPU code path for 2-D + 3-D? | ✅ Unified compute shader | ❌ Different renderers | ❌ Different renderers | — | — |
| Shared data pointer across views? | ✅ Zero-copy shared memory | ❌ Separate DataSeries per chart | ❌ Separate data objects | — | — |
| Filter2D3D optimization? | ✅ Two-tier shader for 250K+ contours | ❌ | ❌ | — | — |
ProEssentials的Pe3do图表对象使用两级调度系统:PolyMode选择图表类别(曲面、柱状图、散点、多边形数据),PlottingMethod选择该类别内的渲染变体(线框、阴影、等高线、面积)。这种设计意味着一个图表控件处理所有3D图表类型——更改可视化时无需在不同图表组件之间切换。
3D曲面是ProEssentials的旗舰3D图表类型——也是上面GigaPrime3D代码中演示的。它接受X × Z网格的Y高程值,渲染具有可配置线框、阴影、光照和等高线颜色条带的连续网格。将PlottingMethod设置为Four(曲面+等高线)将等高线颜色渐变直接叠加到曲面网格上。
GigaPrime3D演示使用Compute Shader、256条带等高线着色、通过SetLight()可调光照位置和交互式鼠标拖拽旋转渲染最大6000 × 6000(3600万顶点)的网格。DuplicateData优化(DuplicateDataX = PointIncrement,DuplicateDataZ = SubsetIncrement)避免传递冗余网格坐标——均匀网格只需要一行X值和一列Z值。
多个光源可以在3D空间中定位,缩放代码中演示的像素着色器剔除(DxPsManualCullXZ)确保缩放视图仅处理可见三角形。GridAspect属性控制X:Y:Z轴比例——演示从扫描材料样品的物理尺寸动态计算纵横比。
ProEssentials的2D等高线渲染使用与3D曲面相同的GPU Compute Shader管线——如GigaPrime3D代码中所示,两个图表都设置ComputeShader = true。Pesgo图表对象从X × Y网格的Z高程值渲染等高线色彩填充(热力图)、等高线线条或两者兼有。
GigaPrime3D演示使用256条带的手动SubsetColors来定义等高线可视化的精确蓝-青-绿-黄-红渐变——应用于3D曲面和2D等高线的相同颜色映射。等高线着色还支持预定义的ContourColorSet调色板和通过ContourColorBlends进行插值的自定义ContourColors数组。
SciChart提供热力图渲染但没有等高线线条。LightningChart支持等高线线条和填充。Syncfusion通过SfSurfaceChart提供基于曲面的等高线和线框等高线渲染。DevExpress提供单独的热力图控件但没有等高线线条渲染。ProEssentials、LightningChart和Syncfusion都提供等高线线条渲染——但只有ProEssentials在GPU Compute Shader上通过共享指针的零拷贝数据访问来完成。
瀑布图可视化频谱数据、振动分析以及每个切片代表不同时间或位置测量的任何时间演变信号。ProEssentials使用PolyMode.Scatter与PlottingMethod.Area渲染瀑布,将每个子集绘制为3D空间中的填充面积切片。通过WaterfallContours对每个切片应用等高线着色,生成与高程值匹配的颜色条带切片。
瀑布边框、等高线颜色混合和每子集线条类型提供对视觉外观的精细控制。SciChart和LightningChart都提供瀑布图,但没有竞争对手提供ProEssentials原生提供的等高线着色切片渲染。
ProEssentials支持三种使其区别于所有竞争对手的高级图表类型。4D W-数据系统(PeData.W)添加了一个独立的第四数据维度,独立于Y轴高程控制曲面等高线着色——SciChart和LightningChart提供类似功能,但ProEssentials通过用于曲面和等高线的同一GPU Compute Shader管线渲染。内置Delaunay三角剖分是ProEssentials独有的——没有其他WPF图表库提供此功能。参见示例415。
内置Delaunay三角剖分(PePlot.Option.Delaunay3D = true)自动将非结构化点云转换为三角化曲面。向引擎提供XYZ点的平面列表——无需预网格化——它使用Y作为高度对XZ平面进行三角剖分,生成带等高线着色的正确曲面网格。没有其他WPF图表库提供内置Delaunay。参见示例414。
自定义多边形数据(PolyMode.PolygonData)通过定义原始顶点位置和每多边形颜色实现任意3D几何体。这用于自定义3D形状——球体、导入对象、工程模型——在同一Pe3do图表控件内渲染。图形注释也支持多边形数据,用于在数据空间中放置3D形状注释。参见示例406(球体)和示例416(复杂注释形状)。
ProEssentials提供专用实时3D示例(410、411、412、413),演示流式曲面、散点、柱状和大型Compute Shader曲面。实时3D管线将ComputeShader与StagingBuffers结合用于高效GPU数据传输,ReuseDataX/ReuseDataZ跳过未更改网格轴的重新处理,SkipRanging在手动缩放时绕过CPU密集的最小/最大扫描。
示例413是最具挑战性的:具有Compute Shader渲染、循环缓冲区和实时数据流的大型3D曲面。它演示了完整的优化堆栈——DuplicateData共享网格坐标,StagingBuffers进行GPU端数据缓存,Force3dxVerticeRebuild进行高效顶点更新而无需完全重建场景。
SciChart和LightningChart都支持实时3D更新,但都不提供ReuseData优化(跳过未更改轴的重新处理)或SkipRanging(手动缩放时绕过范围计算)。这些优化很重要,因为它们消除了未更改数据部分的冗余CPU和GPU工作——在流式场景中,这通常是三个轴中的两个。
| Real-Time 3-D | ProEssentials | SciChart |
|---|---|---|
| 3-D circular buffers | ✅ Built-in | Manual management |
| GPU compute on update | ✅ ComputeShader + StagingBuffers | GPU vertex buffer rebuild |
| Partial axis reuse | ✅ ReuseDataX / ReuseDataZ | ❌ Full rebuild |
| Skip ranging | ✅ SkipRanging when manual-scaled | N/A |
| Included examples | 6 real-time 3-D examples (410–413) | Several |
GigaPrime3D演示展示了ProEssentials的完整3D交互模型:流畅的鼠标拖拽旋转、可配置平滑度的鼠标滚轮缩放、Shift-拖拽视口平移、中键光照定位和触摸捏合缩放——所有都具有可调平滑度参数。
相机控制包括ViewingHeight(仰角0-36)、DegreeOfRotation(0-359)、具有可配置最小/最大限制的DxZoom,以及控制透视投影的DxFOV。演示将这些作为滑块暴露在图表旁边,为用户提供对观看角度、缩放距离、垂直和水平偏移以及Z轴夸大的精确控制——全部通过按需渲染实时更新3D视图。
DegreePrompting在交互期间在屏幕上显示当前旋转角度、缩放距离和光照位置。结合按需渲染(GPU仅在活跃交互时渲染,用户释放时停止),这提供了零空闲功耗的响应式交互——对笔记本和信息亭部署来说,相比游戏引擎循环的关键优势。
GigaPrime3D演示使用256条带的手动SubsetColors——遍历自定义蓝到红渐变数组,将每种颜色分配给SubsetColors条目。这提供了对等高线颜色斜坡的像素级控制,并确保3D曲面和2D等高线使用相同的着色。
为了更快的设置,预定义的ContourColorSet枚举(BlueCyanGreenYellowBrownWhite、Grayscale等)提供即时调色板,具有可配置的ContourColorBlends用于平滑插值。自定义ContourColors数组允许在特定渐变位置定义精确的颜色停止点。
锚点插值技术——在值阈值处定义锚定颜色并计算它们之间的线性RGB插值——产生出版质量的颜色斜坡,在关键数据边界处具有精确控制。在Direct3D模式下设置SubsetColors后,Force3dxNewColors和Force3dxVerticeRebuild确保GPU更新颜色映射和几何体。
GigaPrime3D材料表面扫描演示用真实生产代码证明了这些功能——不是营销宣传。3600万数据点,一个共享数组,两个GPU渲染视图,节省150MB,带像素着色器剔除的联动缩放,工业级交互。ProEssentials覆盖本比较中的全部13种图表类型——包括没有竞争对手提供的点云Delaunay三角剖分。3D曲面和2D等高线都通过相同的统一GPU Compute Shader管线渲染。
SciChart和LightningChart是强大的3D竞争者,各覆盖13种图表类型中的12种。Syncfusion覆盖7种,具有曲面、线框、等高线、散点、柱状、热力图和等高线线支持。DevExpress覆盖5种。但这些竞争对手都不提供图表视图间的共享数据指针、跨2D和3D的统一Compute Shader渲染,或点云内置Delaunay三角剖分。对于科学、工程、地理空间、医学成像、计量和半导体可视化,ProEssentials的3D和2D功能在WPF图表市场中仍然最为全面。
ProEssentials支持免费、无限制,由构建3D渲染引擎的开发者直接提供。关于曲面渲染、等高线着色、共享内存、Delaunay三角剖分或其他任何问题,请随时咨询。
联系ProEssentials团队 →我们的首要目标是通过为您的机构和终端用户提供最简单、最专业的服务,达成您的成功。
ProEssentials是由需要自定义图表组件的专业电气工程师创立的。加入使用ProEssentials的顶级工程公司名单。
感谢您成为ProEssentials的客户,也感谢您研究ProEssentials图表引擎。