I want to colour the six sides of a cube with the right colours, for example like this:
How could I do this?
I have the following XAML code:
<Grid>
<Viewport3D Name="viewport3D1">
<Viewport3D.Camera>
<PerspectiveCamera x:Name="camMain" Position="6 5 4"
LookDirection="-6 -5 -4">
</PerspectiveCamera>
</Viewport3D.Camera>
<ModelVisual3D>
<ModelVisual3D.Content>
<DirectionalLight x:Name="dirLightMain" Direction="-1,-1,-1">
</DirectionalLight>
</ModelVisual3D.Content>
</ModelVisual3D>
<ModelVisual3D x:Name="MyModel">
<ModelVisual3D.Content>
<GeometryModel3D>
<GeometryModel3D.Geometry>
<MeshGeometry3D x:Name="meshMain"
Positions="0 0 0 1 0 0 0 1 0 1 1 0 0 0 1 1 0 1 0 1 1 1 1 1"
TriangleIndices="2 3 1 2 1 0 7 1 3 7 5 1 6 5 7 6 4 5 6 2 0 2 0 4 2 7 3 2 6 7 0 1 5 0 5 4">
</MeshGeometry3D>
</GeometryModel3D.Geometry>
<GeometryModel3D.Material>
<DiffuseMaterial x:Name="matDiffuseMain">
<DiffuseMaterial.Brush>
<LinearGradientBrush StartPoint="0,0.5"
EndPoint="1,0.5">
<GradientStop Color="Red" Offset="0.0"/>
</LinearGradientBrush>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</GeometryModel3D.Material>
</GeometryModel3D>
</ModelVisual3D.Content>
<ModelVisual3D.Transform>
<RotateTransform3D CenterX="0.5" CenterY="0.5" CenterZ="0.5">
<RotateTransform3D.Rotation>
<AxisAngleRotation3D x:Name="rotate" Axis="1 0 0"/>
</RotateTransform3D.Rotation>
</RotateTransform3D>
</ModelVisual3D.Transform>
</ModelVisual3D>
</Viewport3D>
<Slider Height="23" HorizontalAlignment="Left"
Margin="12,12,0,0" Name="slider1"
VerticalAlignment="Top" Width="187"
Maximum="360"
Value="{Binding ElementName=rotate, Path=Angle}"
ValueChanged="slider1_ValueChanged" />
</Grid>
This can be done in XAML alone but you're going to need to split the cube out into its 6 faces and apply a different texture to each one.
The textures themselves will need to be VisualBrushes containing two linear gradient brushes, one for each axis. My answer to this question should be enough to get you going.
Secondly, if you want to apply a VisualBrush to a mesh geometry then you'll also need to specify texture coordinates, this page contains some details on how to do that.
If you still can't get this to work then post back here and I'll have a crack at it myself.
There are 2 possible solutions:
- replace geometryModel of cube on 6 geometries of planks with colorized materials
- apply image texture for cube
Related
I'm looking to create the following shape in XAML with System.Windows.Shapes.Path
(The image is a bit rough but demonstrates the curved corners in the top left and right and the curved bottom image).
So far I have the bottom curve with the following:
<Path Data="M0,0 L300,0 L300,40.768158 L296.83832,41.189522 C253.5976,46.794456 203.45944,50.000004 150,50.000004 C96.540565,50.000004 46.402409,46.794456 3.1617098,41.189522 L0,40.768158" ... />
But I am unsure how to get the top corners to be rounded with this.
You can use elliptical arcs (class ArcSegment) in your Path geometry:
<Path Fill="Black"
Data="M0,20 A20,20 0 0 1 20,0 L280,0 A20,20 0 0 1 300,20 L300,150 A150,75 0 0 1 0,150 Z"/>
Alternatively you could use a CombinedGeometry like this:
<Path Fill="Black">
<Path.Data>
<CombinedGeometry GeometryCombineMode="Union">
<CombinedGeometry.Geometry1>
<RectangleGeometry Rect="0,0,300,170" RadiusX="20" RadiusY="20"/>
</CombinedGeometry.Geometry1>
<CombinedGeometry.Geometry2>
<EllipseGeometry Center="150,150" RadiusX="150" RadiusY="75"/>
</CombinedGeometry.Geometry2>
</CombinedGeometry>
</Path.Data>
</Path>
I'm new to 'wpf' and I've come over the following problem: In my project I try to use small resolution .png as texture for a model. When I disable mipmapping in Blender (where I built the cube) the result is just what I want:
no mipmapping
But in the wpf project the blurred effect never turns off:
wpf result
Here is my code:
<Window x:Class="GCS.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="504" Width="525" ShowInTaskbar="True">
<Grid>
<Viewport3D Name="myViewport"
xmlns="http://schemas.microsoft.com/netfx/2007/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Viewport3D.Resources>
<MaterialGroup x:Key="Material">
<DiffuseMaterial>
<DiffuseMaterial.Brush>
<ImageBrush RenderOptions.BitmapScalingMode="NearestNeighbor" ViewportUnits="Absolute" ImageSource="char.png"/>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</MaterialGroup>
</Viewport3D.Resources>
<Viewport3D.Camera>
<PerspectiveCamera Position="7.8,-11,-0.8" NearPlaneDistance="1" FarPlaneDistance="50" LookDirection="-0.4,0.9,-0.3" UpDirection="0,0,1" FieldOfView="15"/>
</Viewport3D.Camera>
<Viewport3D.Children>
<ModelVisual3D>
<ModelVisual3D.Content>
<Model3DGroup>
<GeometryModel3D Material="{StaticResource Material}">
<GeometryModel3D.Transform>
<Transform3DGroup>
<TranslateTransform3D OffsetZ="0" OffsetX="0" OffsetY="-7"/>
<ScaleTransform3D ScaleZ="1" ScaleY="1" ScaleX="1"/>
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D Axis="1,0,0" Angle="92"/>
</RotateTransform3D.Rotation>
</RotateTransform3D>
<TranslateTransform3D OffsetZ="0" OffsetX="0" OffsetY="7"/>
<TranslateTransform3D OffsetZ="-6.622" OffsetX="0" OffsetY="-0.023"/>
</Transform3DGroup>
</GeometryModel3D.Transform>
<GeometryModel3D.Geometry>
<MeshGeometry3D
Normals="-1,0,0 -1,0,0 -1,0,0 -1,0,0 0,0,-1 0,0,-1 0,0,-1 0,0,-1 1,0,0 1,0,0 1,0,0 1,0,0 0,0,1 0,0,1 0,0,1 0,0,1 0,-1,0 0,-1,0 0,-1,0 0,-1,0 0,1,0 0,1,0 0,1,0 0,1,0"
Positions="-1,6,-1 -1,6,1 -1,8,1 -1,8,-1 -1,8,-1 1,8,-1 1,6,-1 -1,6,-1 1,8,-1 1,8,1 1,6,1 1,6,-1 -1,6,1 1,6,1 1,8,1 -1,8,1 -1,6,1 -1,6,-1 1,6,-1 1,6,1 1,8,1 1,8,-1 -1,8,-1 -1,8,1"
TextureCoordinates="0,0.5 0.125,0.5 0.125,0.25 0,0.25 0.5,0.25 0.375,0.25 0.375,0.5 0.5,0.5 0.375,0.25 0.25,0.25 0.25,0.5 0.375,0.5 0.125,0.5 0.25,0.5 0.25,0.25 0.125,0.25 0.375,0.25 0.375,0 0.25,0 0.25,0.25 0.25,0.25 0.25,0 0.125,0 0.125,0.25"
TriangleIndices="0 1 2 0 2 3 4 5 6 4 6 7 8 9 10 8 10 11 12 13 14 12 14 15 16 17 18 16 18 19 20 21 22 20 22 23"/>
</GeometryModel3D.Geometry>
</GeometryModel3D>
</Model3DGroup>
</ModelVisual3D.Content>
</ModelVisual3D>
<ModelVisual3D>
<ModelVisual3D.Content>
<AmbientLight Color="#ffffff"/>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D.Children>
</Viewport3D>
</Grid>
I've done a lot of search on the Internet and tried many approaches: enforced software rendering, used DrawingBrush instead of ImageBrush but the result is the same. Is there any way to overcome such rendering?
Try the following approach using VisualBrush - it produces clear, aliased texturing:
<DiffuseMaterial x:Key="Material">
<DiffuseMaterial.Brush>
<VisualBrush RenderOptions.CachingHint="Cache">
<VisualBrush.Visual>
<Image Source="char.png" RenderOptions.BitmapScalingMode="NearestNeighbor" />
</VisualBrush.Visual>
</VisualBrush>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</Grid.Resources>
<Viewport3D Name="myViewport">
<Viewport3D.Camera>
<PerspectiveCamera Position="0 0.5 1.5" LookDirection="0 0 -1"
UpDirection="0 1 0" FieldOfView="120" />
</Viewport3D.Camera>
<Viewport3D.Children>
<ModelVisual3D>
<ModelVisual3D.Content>
<GeometryModel3D Material="{StaticResource Material}">
<GeometryModel3D.Geometry>
<MeshGeometry3D
Positions="0 0 0, 0 1 0, 1 0 0, 1 1 0"
TriangleIndices="0 2 3, 0 3 1"
TextureCoordinates="0 1, 0 0, 1 1, 1 0" />
</GeometryModel3D.Geometry>
</GeometryModel3D>
</ModelVisual3D.Content>
</ModelVisual3D>
<ModelVisual3D>
<ModelVisual3D.Content>
<AmbientLight Color="#ffffff"/>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D.Children>
</Viewport3D>
</Grid>
I created a full-screen WPF Canvas, representing a time line. Only the visible part of the time line is composed, so (practically) no UI elements lie outside of the visible range.
I'm trying to add perspective to this time line using a Viewport3D. The result at the moment looks as follows:
You can scroll the time line left and right by dragging. Performance in the 2D version is great. However, once the canvas is placed inside a Viewport3D using Viewport2DVisual3D, performance drops drastically.
It's not like I'm rendering a complex mesh, where is this performance decrease coming from, and can I prevent it?
To give you an idea of how the 3D perspective was realized I'll add the XAML code here, unfortunately it doesn't work on its own.
<Grid Background="{StaticResource BackgroundBrush}">
<Viewport3D ClipToBounds="False">
<Viewport3D.Camera>
<PerspectiveCamera
Position="0 0 5"
LookDirection="0.4 0 -1"
UpDirection="0 1 0" />
</Viewport3D.Camera>
<ContainerUIElement3D>
<ModelUIElement3D>
<AmbientLight Color="White" />
</ModelUIElement3D>
</ContainerUIElement3D>
<Viewport2DVisual3D>
<Viewport2DVisual3D.Geometry>
<MeshGeometry3D
TriangleIndices="0,1,2 2,3,0"
TextureCoordinates="0 0, 0 1, 1 1, 1 0">
<MeshGeometry3D.Positions>
<MultiBinding Converter="{StaticResource AspectRatioToPositions}">
<Binding ElementName="TimeLineContainer" Path="Width" />
<Binding ElementName="TimeLineContainer" Path="Height" />
</MultiBinding>
</MeshGeometry3D.Positions>
</MeshGeometry3D>
</Viewport2DVisual3D.Geometry>
<Viewport2DVisual3D.Material>
<DiffuseMaterial
Viewport2DVisual3D.IsVisualHostMaterial="True"
Brush="White" />
</Viewport2DVisual3D.Material>
<Grid
x:Name="TimeLineContainer"
Width="1650" Height="600"
ClipToBounds="True"
Background="{StaticResource TimeLineBrush}"
Behaviors:MouseBehavior.LeftClickDragCommand="ActivityOverview:ActivityOverviewWindow.MouseDragged"
MouseWheel="OnMouseWheel"
MouseMove="OnMouseMoved">
<ActivityOverview:TimeLineControl x:Name="TimeLine" Focusable="True">
<ActivityOverview:TimeLineControl.CommandBindings>
<CommandBinding
Command="ActivityOverview:ActivityOverviewWindow.MouseDragged"
Executed="MoveTimeLine" />
</ActivityOverview:TimeLineControl.CommandBindings>
</ActivityOverview:TimeLineControl>
</Grid>
</Viewport2DVisual3D>
</Viewport3D>
</Grid>
When using Viewport2DVisual3D performance can be slow when you attempt to display content that is time-consuming to render. This seemed to be the case in my example.
For this reason, you can set the CacheMode of Viewport2DVisual3D.
<Viewport2DVisual3D>
<Viewport2DVisual3D.CacheMode>
<BitmapCache />
</Viewport2DVisual3D.CacheMode>
...
</Viewport2DVisual3D>
Starting from Windows Vista, anti-aliasing is enabled by default. Disabling this also helps in improving performance. It's weird this would have a big impact with such a simple mesh (two triangles), but on my PC, it does!
<Viewport3D ClipToBounds="False" RenderOptions.EdgeMode="Aliased">
Combining these two settings, I got great improvements.
Hi guys you can use <OrthographicCamera Position="0 0 5" LookDirection="0.4 0 -1" UpDirection="0 1 0" /> . Please check my code below
<Grid Background="{StaticResource BackgroundBrush}">
<Viewport3D ClipToBounds="False">
<Viewport3D.Camera>
<OrthographicCamera
Position="0 0 5"
LookDirection="0.4 0 -1"
UpDirection="0 1 0" />
</Viewport3D.Camera>
<ContainerUIElement3D>
<ModelUIElement3D>
<AmbientLight Color="White" />
</ModelUIElement3D>
</ContainerUIElement3D>
<Viewport2DVisual3D>
<Viewport2DVisual3D.Geometry>
<MeshGeometry3D
TriangleIndices="0,1,2 2,3,0"
TextureCoordinates="0 0, 0 1, 1 1, 1 0">
<MeshGeometry3D.Positions>
<MultiBinding Converter="{StaticResource AspectRatioToPositions}">
<Binding ElementName="TimeLineContainer" Path="Width" />
<Binding ElementName="TimeLineContainer" Path="Height" />
</MultiBinding>
</MeshGeometry3D.Positions>
</MeshGeometry3D>
</Viewport2DVisual3D.Geometry>
<Viewport2DVisual3D.Material>
<DiffuseMaterial
Viewport2DVisual3D.IsVisualHostMaterial="True"
Brush="White" />
</Viewport2DVisual3D.Material>
<Grid
x:Name="TimeLineContainer"
Width="1650" Height="600"
ClipToBounds="True"
Background="{StaticResource TimeLineBrush}"
Behaviors:MouseBehavior.LeftClickDragCommand="ActivityOverview:ActivityOverviewWindow.MouseDragged"
MouseWheel="OnMouseWheel"
MouseMove="OnMouseMoved">
<ActivityOverview:TimeLineControl x:Name="TimeLine" Focusable="True">
<ActivityOverview:TimeLineControl.CommandBindings>
<CommandBinding
Command="ActivityOverview:ActivityOverviewWindow.MouseDragged"
Executed="MoveTimeLine" />
</ActivityOverview:TimeLineControl.CommandBindings>
</ActivityOverview:TimeLineControl>
</Grid>
</Viewport2DVisual3D>
</Viewport3D>
<Window x:Class="Viewport2DVisual3DExample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Button on 3D"
WindowStyle="None"
Background="{x:Null}"
Foreground="{x:Null}"
AllowsTransparency="True"
>
<Viewport3D>
<Viewport3D.Camera>
<PerspectiveCamera Position="0, 0, 4"/>
</Viewport3D.Camera>
<!-- Front -->
<Viewport2DVisual3D>
<!-- Give the plane a slight rotation -->
<Viewport2DVisual3D.Transform>
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D x:Name="frontTransform" Angle="0" Axis="0, 1, 0" />
</RotateTransform3D.Rotation>
</RotateTransform3D>
</Viewport2DVisual3D.Transform>
<!-- The Geometry, Material, and Visual for the Viewport2DVisual3D -->
<Viewport2DVisual3D.Geometry>
<MeshGeometry3D Positions="-1,1,0 -1,-1,0 1,-1,0 1,1,0"
TextureCoordinates="0,0 0,1 1,1 1,0" TriangleIndices="0 1 2 0 2 3"/>
</Viewport2DVisual3D.Geometry>
<Viewport2DVisual3D.Material>
<DiffuseMaterial Viewport2DVisual3D.IsVisualHostMaterial="True" Brush="White"/>
</Viewport2DVisual3D.Material>
<!-- Here Here Here Here Here -->
<Image Source="i:\\tempa\\tm.png" Width="534" Height="458" />
</Viewport2DVisual3D>
<!-- Back -->
<Viewport2DVisual3D>
<!-- Give the plane a slight rotation -->
<Viewport2DVisual3D.Transform>
<RotateTransform3D >
<RotateTransform3D.Rotation>
<AxisAngleRotation3D x:Name="backTransform" Angle="180" Axis="0, 1, 0" />
</RotateTransform3D.Rotation>
</RotateTransform3D>
</Viewport2DVisual3D.Transform>
<!-- The Geometry, Material, and Visual for the Viewport2DVisual3D -->
<Viewport2DVisual3D.Geometry>
<MeshGeometry3D Positions="-1,1,0 -1,-1,0 1,-1,0 1,1,0"
TextureCoordinates="0,0 0,1 1,1 1,0" TriangleIndices="0 1 2 0 2 3"/>
</Viewport2DVisual3D.Geometry>
<Viewport2DVisual3D.Material>
<DiffuseMaterial Viewport2DVisual3D.IsVisualHostMaterial="True" Brush="White"/>
</Viewport2DVisual3D.Material>
<Button Name="btnBack">Back</Button>
</Viewport2DVisual3D>
<ModelVisual3D>
<ModelVisual3D.Content>
<DirectionalLight Color="#FFFFFFFF" Direction="0,0,-1"/>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D>
I am trying to build a 2-Side window using Viewport3D. But then I had some trouble about size.
<!-- Here Here Here Here Here -->
<Image Source="i:\\tempa\\tm.png" Width="534" Height="458" />
I want this Image to be the exact same size as its source image.
Neither a specified value or "auto" would work.
How can I get what I want?
My 3d knowledge is limited and someone can probably answer this better, but in a 3d environment, the size of an object is dependent on a lot of things.. camera position,near/far plane, the size/location of the object, transforms applied to that object, viewport size, and probably other stuff I'm forgetting. The 3d engine takes all the stuff into account when rendering stuff. Setting the size of the image is just one piece of it.
Maybe try messing with the camera position or adding a scaletransform to the image.
What you are looking for is the projection matrix of the camera. That matrix transforms a 3D point into a 2D point. So by passing the 3D coordinates of the MeshGeometry3D you can find out the 2D coordinates and sizes.
I am trying to shear an Image in WPF (C#) using pure XAML. I have used transformations such as skew, scale and matrix but I am not getting the result as I want. Following is the code I am using
<Image Source="G:\Demo\virtualization\virtualization\img3.bmp" Stretch="Fill" Height="70" Width="240" Margin="0,170,-312,-29" >
<Image.RenderTransform>
<TransformGroup>
<MatrixTransform Matrix="1,.1,-4.2,1,0,0" />
<!--<ScaleTransform ScaleX=".2" ScaleY=".6"/>-->
</TransformGroup>
</Image.RenderTransform>
</Image>
With the above code, below is the similar effect that I am getting:
/----/
/ /
/ /
/----/
But I want following effect:
/---\
/ \
/ \
/---------\
Due to new user, I am not allowed to post Images right now...
Thanks
EDIT:
I have tried viewport3d to get this effect. Following is the code:
<Grid>
<Image Source="G:\Demo\virtualization\virtualization\2.jpg"/>
<Viewport3D Name="mainViewport" ClipToBounds="True" HorizontalAlignment="Stretch" Height="300">
<Viewport3D.Camera>
<PerspectiveCamera Position="0, 0, 20" />
</Viewport3D.Camera>
<Viewport2DVisual3D>
<Viewport2DVisual3D.Transform>
<MatrixTransform3D Matrix="1,0,0,0
0,1,0,0
0,0,1,0
0,0,0,1" />
</Viewport2DVisual3D.Transform>
<Viewport2DVisual3D.Geometry>
<MeshGeometry3D Positions="-1,1,0 -1,-1,0 1,-1,0 1,1,0"
TextureCoordinates="0,0 0,1 1,1 1,0" TriangleIndices="0 1 2 0 2 3"/>
</Viewport2DVisual3D.Geometry>
<Viewport2DVisual3D.Material>
<DiffuseMaterial Viewport2DVisual3D.IsVisualHostMaterial="True" Brush="White"/>
</Viewport2DVisual3D.Material>
<Grid>
<Image Source="G:\Demo\virtualization\virtualization\img3.bmp"/>
</Grid>
</Viewport2DVisual3D>
<ModelVisual3D>
<ModelVisual3D.Content>
<DirectionalLight Color="#FFFFFFFF" Direction="0,-1,-1"/>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D>
</Grid>
I am using matrix transformation to get the effect.
However I am looking to alternate ways to get this effect May be rotating the camera of viewport.
You cannot achieve this kind of effect with linear transformation (mathematically impossible).
You could get this effect with WPF 3D.
You can achieve this effect with a custom pixel shader.
Download a copy of Shazzam (it's free) and check out the paperfold sample (shazzam-tool.com). While it's not exactly the shear effect you showed in your question, it is close.
Have you worked with shaders before? If you want to use a custom shader I have a prototype shear effect that I worked on a couple months ago. I can clean up the HLSL and post it here.
Edit
Shazzam contains a tutorial section and about 80 sample shaders. That's a good place to start. The hardest part about using custom shaders is that you have to learn a new language (HLSL).
There is a list of shader articles at http://blog.shazzam-tool.com/index.php/shader-articles/