public PixelRenderingSample() { InitializeComponent(); PixelSizeComboBox.ItemsSource = new float[] { 0.1f, 0.5f, 1, 2, 4, 8 }; PixelSizeComboBox.SelectedIndex = 3; _disposables = new DisposeList(); MainDXViewportView.DXSceneInitialized += delegate(object sender, EventArgs args) { CreateScene(); }; this.Unloaded += delegate(object sender, RoutedEventArgs args) { _disposables.Dispose(); if (_pixelEffect != null) { _pixelEffect.Dispose(); _pixelEffect = null; } MainDXViewportView.Dispose(); }; }
private void ShowGeometryModel3D(GeometryModel3D model3D, float pixelSize) { MainViewport.Children.Clear(); _disposables.Dispose(); // Dispose previously used resources _disposables = new DisposeList(); // Start with a fresh DisposeList if (_pixelEffect == null) { // Get an instance of PixelEffect (it is used to provide the correct shaders to render specified postions as pixels) _pixelEffect = MainDXViewportView.DXScene.DXDevice.EffectsManager.GetEffect <PixelEffect>(createNewEffectInstanceIfNotFound: true); // Do not forget to dispose the effect when it is not used any more - we will do that in the Unloaded event handler } // We will render the GeometryModel3D with overriding the usage of standard effect // that renders DiffuseMaterial and other standard materials // with custom effect: PixelEffect. // This will use different shaders to render the provided triangles. // // Because the standard material does not provide pixel size, // we need to set the fallback pixel size value to the PixelEffect. _pixelEffect.PixelSize = pixelSize; // To override the used material, we first need to create a new WpfMaterial from the WPF material. var wpfMaterial = new WpfMaterial(model3D.Material); // then set the Effect to it ... wpfMaterial.Effect = _pixelEffect; // and finally specify the WpfMaterial to be used whenever the model3D.Material is used. model3D.Material.SetUsedDXMaterial(wpfMaterial); _disposables.Add(wpfMaterial); // Now just add the model3D to the MainViewport var modelVisual3D = new ModelVisual3D(); modelVisual3D.Content = model3D; MainViewport.Children.Add(modelVisual3D); // IMPORTANT: // The above method of showing 3D model with pixels is not optimal. // The reason for this is that this way the pixles are rendered for each triangle in the model. // But because the same positions are usually used by multiple triangles, those positions will be rendered multiple times. // // A better way to render the models is to extract the positions from MeshGeometry3D // and render the pixels are a list of positions. // This is shown in the commented code below: // // The code above is provided to also show a way to render a 3D model with a different effect. //var meshGeometry3D = (MeshGeometry3D)model3D.Geometry; //var positions = meshGeometry3D.Positions; //var positionsCount = positions.Count; //var positionsArray = new Vector3[positionsCount]; //if (model3D.Transform == null || model3D.Transform.Value.IsIdentity) //{ // for (int i = 0; i < positionsCount; i++) // positionsArray[i] = positions[i].ToVector3(); //} //else //{ // for (int i = 0; i < positionsCount; i++) // positionsArray[i] = model3D.Transform.Transform(positions[i]).ToVector3(); //} //// Extract pixel color from material (use Red as fallback) //Color4 pixelColor = Colors.Red.ToColor4(); //var diffuseMaterial = model3D.Material as DiffuseMaterial; //if (diffuseMaterial != null) //{ // var solidColorBrush = diffuseMaterial.Brush as SolidColorBrush; // if (solidColorBrush != null) // pixelColor = solidColorBrush.Color.ToColor4(); //} //ShowPositionsArray(positionsArray, pixelSize, pixelColor, model3D.Bounds.ToDXEngineBounds()); }
void Start() { asciiEffect = GetComponent<AsciiEffect>(); greenAsciiEffect = GetComponent<GreenAsciiEffect>(); pixelEffect = GetComponent<PixelEffect>(); }