public CustomRenderingStep4() { InitializeComponent(); // Instead of creating new RenderingStep as in the previous sample, // we will use CustomRenderableNode instead. // This type of SceneNode object allows specifying custom rendering action // that is called to render the object. var bounds = CustomRenderingStep1.GetSharpDXBoxBounds(); // CustomRenderableNode also requires bounds so that the camera near and far calculations can account the custom data. var customRenderableNode = new CustomRenderableNode(CustomRenderAction, bounds); // To add CustomRenderableNode to the 3D scene, we need to embed it into a SceneNodeVisual3D var sceneNodeVisual3D = new SceneNodeVisual3D(customRenderableNode); MainViewport.Children.Add(sceneNodeVisual3D); MainDXViewportView.DXSceneInitialized += delegate(object sender, EventArgs args) { if (MainDXViewportView.DXScene == null) // When DXEngine falls back to WPF 3D rendering, the DXScene is null; we could also check for MainDXViewportView.UsedGraphicsProfile.DriverType != GraphicsProfile.DriverTypes.Wpf3D { return; } InitializeSharpDXRendering(MainDXViewportView.DXScene); }; this.Unloaded += delegate { Dispose(); }; }