Advanced 3D Techniques with WPF : Advanced 3D Techniques with WPF David Teitlebaum - Program Manager Jordan Parker - Developer
Microsoft Corporation
Talk Outline : Talk Outline Introduction to WPF3D
What do you need to do to see something?
Interactive 2D on 3D
Make VisualBrush work like you expected it to
Performance Tips
Learn how to avoid common mistakes
Jordan Parker : Jordan Parker basics
The Name Game Warmup Time : The Name Game Warmup Time Pattern: FooBar is a Bar with a Foo
Examples:
ModelVisual3D is a Visual3D with a Model3D
GeometryModel3D is a Model3D with a Geometry3D
MeshGeometry3D is a Geometry3D with a mesh
ScaleTransform3D is a Transform3D with a scale
And so on (generally)
DrawingImage vs. ImageDrawing, anyone?
The Minimal Scene : The Minimal Scene Let’s do a simple 3D video example step-by-step
Our Coordinate System : Our Coordinate System Right-handed
Notice that +Y is up… opposite of 2D! (Image from http://www.willamette.edu/~gorr/)
MeshGeometry3D : MeshGeometry3D Specifies a mesh of triangles
Positions: Triangle vertices
TriangleIndices: Optional indices into collections. Used to avoid duplicating vertices.
Normals: Per-vertex orientation used in lighting. Generated for you if unspecified.
TextureCoordinates: Describes the 2D Brush mapping. NOT generated for you. Not needed for SolidColorBrushes.
Triangle vertices should be given in CCW order
TriangleIndices : TriangleIndices If specified:
positions[indices[0]] positions[indices[1]] positions[indices[2]]…
texcoords[indices[0]] texcoords[indices[1]] texcoords[indices[2]]…
normals[indices[0]] normals[indices[1]] normals[indices[2]]…
If not specified:
positions[0] positions[1] positions[2] …
texcoords[0] texcoords[1] texcoords[2] …
normals[0] normals[1] normals[1] …
TextureCoordinates : TextureCoordinates (image from blogs.msdn.com/danlehen)
Normals : Normals If you don’t specify normals, we generate them by averaging the “true” surface normals of the triangles that share the vertex. This gives a smooth appearance.
If you duplicate a vertex, it will end up with a different normal each time. Triangle specification matters!
If you specify too many, we throw out the extras
If you specify too few, we generate the rest
NormalsCylinder Cap Duplication Example : NormalsCylinder Cap Duplication Example
Positions: Specifying a Plane : Positions: Specifying a Plane (-1,1,0)
0
(0,0) (-1,-1,0)
1
(0,1) (1,-1,0)
2
(1,1) (1,1,0)
3
(1,0) Key:
pos
idx
tc Looking down -Z, making a 2 x 2 plane on Z = 0
Mesh XAML : Mesh XAML We’ll let WPF compute the normals
In general, you’ll be exporting a mesh to XAML from a tool or generating the mesh algorithmically
Materials : Materials Reflection/absorption of light
EmissiveMaterial: Surface appears to give off light
SpecularMaterial: Shine
DiffuseMaterial: Soft scattering
Takes a Brush for the base color
Combine them with MaterialGroup
When in doubt, use DiffuseMaterial
Material Examples : Material Examples
Video DiffuseMaterial XAML : Video DiffuseMaterial XAML
GeometryModel3D : GeometryModel3D Combines the Material and the Geometry3D
Allows you to specify a transform
(the plane mesh)
(the video material)
Lights : Lights Not unlike reality, without light you can’t see anything*
AmbientLight: Equal contribution everywhere
DirectionalLight: The sun
PointLight: Light bulb
SpotLight: Self explanatory ?
Lights are Model3Ds and thus have transforms
We’ll use an AmbientLight in our example for simplicity * Except EmissiveMaterials
Model3DGroup : Model3DGroup
(the ambient light)
(the plane GeometryModel3D) Group multiple Model3Ds together
Is itself a Model3D
Visual3D : Visual3D 3D analog of the 2D Visual class
You need at least one just like you need at least one Visual in 2D (FrameworkElements are Visuals)
To draw a Model3D, use ModelVisual3D
(the Model3DGroup)
Cameras : Cameras Determine what part of the scene you see and project 3D onto a 2D plane
OrthographicCamera: parallel lines stay parallel
PerspectiveCamera: perspective foreshortening
MatrixCamera: Specify your own projection
Viewport3D : Viewport3D The bridge from the 2D -> 3D
It is a FrameworkElement
Takes a Camera and the root of your Visual3D tree
(the PerspectiveCamera)
(the ModelVisual3D)
3D Video : 3D Video demo
Slide 24 : Interactivity
3.0: How Do I Know If I Selected a Mesh? : 3.0: How Do I Know If I Selected a Mesh? Issue a hit test on mouse move/click on the Viewport3D public void HitTest(object sender, System.Windows.Input.MouseButtonEventArgs args)
{
Point mouseposition = args.GetPosition(myViewport);
PointHitTestParameters pointparams = new PointHitTestParameters(mouseposition);
VisualTreeHelper.HitTest(myViewport, null, HTResult, pointparams);
}
public HitTestResultBehavior HTResult(System.Windows.Media.HitTestResult rawresult)
{
RayHitTestResult rayResult = rawresult as RayHitTestResult;
if (rayResult != null)
{
RayMeshGeometry3DHitTestResult rayMeshResult =
rayResult as RayMeshGeometry3DHitTestResult;
if (rayMeshResult != null)
{
// HIT!!!!
}
}
return HitTestResultBehavior.Continue;
}
New in 3.5: UIElement3D : New in 3.5: UIElement3D Has everything you know and love from UIElement
Derives from Visual3D
Temporary concrete implementations:
ContainerUIElement3D: only a collection of Visual3Ds
ModelUIElement3D: only a Model property
3.5: Interactive 2D on 3D : 3.5: Interactive 2D on 3D Viewport2DVisual3D
Bridge from 3D -> 2D
Funny name, we know, but it mostly makes sense
Three important properties:
Visual: The Visual to be interactive on Geometry
Material: The appearance of Geometry
Set “IsVisualHostMaterial” attached property to “true” on the Material you want Visual to appear on. The Brush property will ignored on that Material.
Geometry: The 3D geometry
Note: Geometry and Material are separated (no Model3D)
Perf tip: RenderOptions caching properties work on this
Our Scene Before : Our Scene Before ModelVisual3D DiffuseMaterial MeshGeometry3D GeometryModel3D VisualBrush “Media Panel”
Now with Interactive 2D on 3D : Now with Interactive 2D on 3D Viewport2DVisual3D DiffuseMaterial MeshGeometry3D “Media Panel” IsVisualHostMaterial = “true”
Interactive 2D on 3D Video : Interactive 2D on 3D Video demo
David Teitlebaum : David Teitlebaum performance
WPF3D PerformanceDo more with less : WPF3D PerformanceDo more with less Performance must be a priority throughout app construction
Test early, test often
Do not assume you can easily fix performance problems after your application is functionally complete
Test on the hardware you care about
Old Desktops, New Desktops, Laptops
Most Dev machines are not “Old Desktops”
Potential Bottlenecks : Potential Bottlenecks CPU
Easy to measure with task manager, profilers, etc.
Many potential causes of CPU load
GPU
Hard to measure – there are few public tools to measure GPU load
Can degrade frame rates without taxing CPU
Few potential causes – typically the result of insufficient fill rate on the GPU or background video decode
GPUs are optimized for video games with few state changes
WPF Hardware TiersKnow your limits : WPF Hardware TiersKnow your limits Coarse indicator of maximum machine capabilities
Queryable via:
(RenderCapability.Tier >> 16)
Tier resides in the high word so don’t forget the shift!
Indicates static capabilities
An upper bound on what can be expected
Does not account for dynamically consumed machine resources
Value is read only (unfortunately! ?)
WPF Hardware Tiers Continued : WPF Hardware Tiers Continued
Useful Performance Tools : Useful Performance Tools Performance tools
WPFPerf.exe
Profilers
Microsoft F1
AMD Code Analyst
Intel Vtune
WPFPerf : WPFPerf demo
Best Practices Common Pitfalls : Best Practices Common Pitfalls #1 Brush Selection
Persistence vs. Nonpersistence of realizations
Intermediate Render Targets
Texture memory swizzling
Texture size
Smaller is better
Watch out for automatic texture sizing
RenderTargetBitmap - best of both worlds?
Best Practices Common Pitfalls : Best Practices Common Pitfalls #1 Continued - RenderTargetBitmap
Rectangle r = new Rectangle();
r.Width = 50;
r.Height = 50;
r.Fill = new LinearGradientBrush(Colors.CornflowerBlue, Colors.PeachPuff, 13.37);
r.Measure(new Size(50, 50));
r.Arrange(new Rect(new Size(50, 50)));
r.UpdateLayout();
RenderTargetBitmap rtb = new RenderTargetBitmap((int)r.ActualWidth, (int)r.ActualHeight, 96.0, 96.0, PixelFormats.Pbgra32);
rtb.Render(r);
Best Practices Common Pitfalls : Best Practices Common Pitfalls #1 Continued - Brush Speed on Tier-2 Hardware in 3D ONLY
Best Practices Common Pitfalls : Best Practices Common Pitfalls #2 Disable Viewport3D.ClipToBounds
WPF uses complex antialised clipping
When Viewport3D.ClipToBounds == False, 3D content can exceed 2D region of Viewport3D
Implementation of clipping is slow enough that it should be disabled when it is not needed
Best Practices Common Pitfalls : Best Practices Common Pitfalls #3 Disable Viewport3D.IsHitTestVisible
WPF3D performs mouse-over hit testing on the CPU
Mouse cursor is projected into object space and intersected with GeometryModel3D’s axis-aligned bounding box
If bounding box is intersected, ray of projected mouse cursor must be intersection-tested against every triangle in GeometryModel3D, all on the CPU
If you don’t need hit testing, disable it.
Best Practices Common Pitfalls : Best Practices Common Pitfalls #4 GeometryModel3D Coalescence
Each Model3D requires a change of GPU state
Each requires the projection of its axis-aligned bounding box to device coordinates
A few complex GeometryModel3Ds is vastly preferable to many simple GeometryModel3Ds
Performance Impact of Model Coalescence : Performance Impact of Model Coalescence demo
Best Practices Common Pitfalls : Best Practices Common Pitfalls #5 Minimize Mesh Animations
They do not scale well due to platform architecture
Entire Collections are remarshalled rather than collection deltas
Disconnect meshes from 3D scene before modifying to minimize change notifications
Keep animated meshes small (a few thousand vertices at the most)
Best Practices Common Pitfalls : Best Practices Common Pitfalls #6 Disable 3D Antialiasing
On Vista, WPF3D will try to render with 4 samples/pixel multisampling
On XP, WPF3D will not try to multisample
To prevent WPF3D from attempting to render with multisampling on Vista, add the attached property RenderOptions.EdgeMode=“Aliased” to your Viewport3D
Best Practices Common Pitfalls : Best Practices Common Pitfalls #7 Text in 3D
Text is expensive
Glyphs are abstractly defined by Beziers
Glyphs are generated and cached according to scale
Small glyphs – Bitmaps / Large glyphs - Polygons
scale changes cause glyph cache invalidation, glyph regeneration, and glyph cache repopulation
RenderTargetBitmap / ImageBrush is strongly recommended for static text
Best Practices Common Pitfalls : Best Practices Common Pitfalls #8 Caching of VisualBrush and DrawingBrush
Attached Property - RenderOptions.CachingHint
Use when ImageBrush is not sufficient
Still slower than ImageBrush due to less aggressive texture memory swizzling on D3D’s RenderTargetTextures
Frequency of cache regeneration can be controlled by RenderOptions.CacheInvalidationThresholdMinimum and RenderOptions.CacheInvalidationThresholdMaximum
Best PracticesCommon Pitfalls : Best PracticesCommon Pitfalls #9 BitmapEffects
Should only be used on static 3D content
Implemented on the CPU
Forces affected content to also be rendered on the CPU
Great for static content, otherwise don’t use them
Performance Impact of BitmapEffects : Performance Impact of BitmapEffects demo
Resources : Resources WPF3D
http://blogs.msdn.com/wpf3d
http://blogs.msdn.com/danlehen
http://blogs.msdn.com/wpfsdk/archive/2007/01/15/maximizing-wpf-3d-performance-on-tier-2-hardware.aspx
http://www.codeplex.com/3dtools
WPF Perf
http://blogs.msdn.com/timothyc
http://blogs.msdn.com/kiranku
Ask Questions
http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=119
news://microsoft.public.windows.developer.winfx.avalon
Books
Windows Presentation Foundation Unleashed by Nathan
3D Programming for Windows by Petzold
Slide 52 : © 2007 Microsoft Corporation. All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries.
The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.