private Model3DGroup Create3DScene(Point3D center, int xCount, int yCount, int zCount, float modelSize)
            {
                var semiTransparentBrush = new SolidColorBrush(Color.FromArgb(64, 200, 200, 200)); // alpha = 1/4
                var diffuseMaterial      = new DiffuseMaterial(semiTransparentBrush);

                diffuseMaterial.Freeze(); // This will significantly speed up the creation of objects

                var modelSizeWithMargin = modelSize * 1.2;
                var size          = new Size3D(xCount * modelSizeWithMargin, yCount * modelSizeWithMargin, zCount * modelSizeWithMargin);
                var instancedData = InstancedMeshGeometry3DTest.CreateInstancesData(center, size, modelSize, xCount, yCount, zCount, false);

                var model3DGroup = new Model3DGroup();
                var boxMesh3D    = new Ab3d.Meshes.BoxMesh3D(new Point3D(0, 0, 0), new Size3D(1, 1, 1), 1, 1, 1).Geometry;

                for (int i = 0; i < instancedData.Length; i++)
                {
                    var geometryModel3D = new GeometryModel3D(boxMesh3D, diffuseMaterial);
                    geometryModel3D.BackMaterial = diffuseMaterial;
                    geometryModel3D.Transform    = new MatrixTransform3D(instancedData[i].World.ToWpfMatrix3D());

                    model3DGroup.Children.Add(geometryModel3D);
                }

                var modelVisual3D = new ModelVisual3D();

                modelVisual3D.Content = model3DGroup;

                MainViewport3D.Children.Add(modelVisual3D);

                return(model3DGroup);
            }
        private void MainDXViewportViewOnDXSceneDeviceCreated(object sender, EventArgs e)
        {
            var instancedData = InstancedMeshGeometry3DTest.CreateInstancesData(center: new Point3D(0, 0, 0),
                                                                                size: new Size3D(4 * XInstancesCount, 4 * YInstancesCount, 4 * ZInstancesCount),
                                                                                modelScaleFactor: 1,
                                                                                xCount: XInstancesCount, yCount: YInstancesCount, zCount: ZInstancesCount,
                                                                                useTransparency: false);

            // Update colors
            int dataCount = instancedData.Length;

            for (int i = 0; i < dataCount; i++)
            {
                float percentage = 1.0f - (float)i / (float)dataCount;
                instancedData[i].DiffuseColor = new Color4(red: percentage, green: 1, blue: percentage, alpha: 1);
            }


            var boxMeshGeometry = new Ab3d.Meshes.BoxMesh3D(centerPosition: new Point3D(0, 0, 0), size: new Size3D(3, 3, 3), xSegments: 1, ySegments: 1, zSegments: 1).Geometry;


            // The first InstancedMeshGeometry3DNode will get the instancedData and
            // will also create the DirectX instance buffer.
            _instancedMeshGeometry3DNode1 = new InstancedMeshGeometry3DNode(boxMeshGeometry);
            _instancedMeshGeometry3DNode1.SetInstanceData(instancedData);

            // Manually call InitializeResources.
            // For this to work, the dxViewportView.DXScene must be set.
            // This is the reason why this method is called inside a DXViewportView.DXSceneDeviceCreated event handler.
            _instancedMeshGeometry3DNode1.InitializeResources(MainDXViewportView.DXScene);

            _disposables.Add(_instancedMeshGeometry3DNode1);


            var instanceBuffer = _instancedMeshGeometry3DNode1.GetInstanceBuffer();

            if (instanceBuffer == null)
            {
                throw new Exception("GetInstanceBuffer returned null"); // Probably DXScene is not initialized
            }
            // Now create another 2 InstancedMeshGeometry3DNode objects
            // and initialize it with already created instanceBuffer

            // The next InstancedMeshGeometry3DNode will be also initialized so
            // that all instances will be rendered with red color instead of the color defined in the instances data.
            _instancedMeshGeometry3DNode2 = new InstancedMeshGeometry3DNode(boxMeshGeometry);
            _instancedMeshGeometry3DNode2.SetInstanceBuffer(instanceBuffer, InstanceData.SizeInBytes, instancedData.Length, instancedData);
            _instancedMeshGeometry3DNode2.UseSingleObjectColor(Colors.Red.ToColor4());
            _disposables.Add(_instancedMeshGeometry3DNode2);

            // The last InstancedMeshGeometry3DNode will render last part of the instances with the color defined in the instance data.
            _instancedMeshGeometry3DNode3 = new InstancedMeshGeometry3DNode(boxMeshGeometry);
            _instancedMeshGeometry3DNode3.SetInstanceBuffer(instanceBuffer, InstanceData.SizeInBytes, instancedData.Length, instancedData);
            _disposables.Add(_instancedMeshGeometry3DNode3);


            // Set StartInstanceIndex and InstancesCount
            _startTime         = DateTime.Now;
            _lastStartRowIndex = int.MinValue;
            UpdateHiddenInstancesPositions();


            var rootSceneNode = new SceneNode();

            rootSceneNode.AddChild(_instancedMeshGeometry3DNode1);
            rootSceneNode.AddChild(_instancedMeshGeometry3DNode2);
            rootSceneNode.AddChild(_instancedMeshGeometry3DNode3);

            var sceneNodeVisual3D = new SceneNodeVisual3D(rootSceneNode);

            MainViewport.Children.Add(sceneNodeVisual3D);
        }