diff --git a/binding/Binding/SKMatrix.cs b/binding/Binding/SKMatrix.cs
index 7c6981f5b..915be2560 100644
--- a/binding/Binding/SKMatrix.cs
+++ b/binding/Binding/SKMatrix.cs
@@ -487,7 +487,6 @@ typeMask = Mask.Scale | Mask.RectStaysRect
}
}
- [Obsolete ("Use SKMatrix44 instead.", true)]
public class SK3dView : SKObject
{
protected override void Dispose (bool disposing)
diff --git a/samples/SkiaSharpSample.Shared/Samples/ThreeDSample.cs b/samples/SkiaSharpSample.Shared/Samples/ThreeDSample.cs
index 31140af80..529f43b63 100644
--- a/samples/SkiaSharpSample.Shared/Samples/ThreeDSample.cs
+++ b/samples/SkiaSharpSample.Shared/Samples/ThreeDSample.cs
@@ -16,7 +16,7 @@ namespace SkiaSharpSample.Samples
{
}
- public override string Title => "3D Rotation";
+ public override string Title => "3D Rotation (ortho)";
protected override async Task OnInit()
{
diff --git a/samples/SkiaSharpSample.Shared/Samples/ThreeDSamplePerspective.cs b/samples/SkiaSharpSample.Shared/Samples/ThreeDSamplePerspective.cs
new file mode 100644
index 000000000..3ce356532
--- /dev/null
+++ b/samples/SkiaSharpSample.Shared/Samples/ThreeDSamplePerspective.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using SkiaSharp;
+
+namespace SkiaSharpSample.Samples
+{
+ [Preserve(AllMembers = true)]
+ public class ThreeDSamplePerspective : AnimatedSampleBase
+ {
+ private SK3dView rotationView;
+
+ [Preserve]
+ public ThreeDSamplePerspective()
+ {
+ }
+
+ public override string Title => "3D Rotation (perspective)";
+
+ protected override async Task OnInit()
+ {
+ // create the base and step 3D rotation matrices (around the y-axis)
+ rotationView = new SK3dView();
+ rotationView.RotateYDegrees(30);
+
+ await base.OnInit();
+ }
+
+ protected override async Task OnUpdate(CancellationToken token, TaskScheduler mainScheduler)
+ {
+ await Task.Delay(25, token);
+
+ // step the rotation matrix
+ rotationView.RotateYDegrees(5);
+ }
+
+ protected override void OnDrawSample(SKCanvas canvas, int width, int height)
+ {
+ // get the 2D equivalent of the 3D matrix
+ var rotationMatrix = rotationView.Matrix;
+
+ // get the properties of the rectangle
+ var length = Math.Min(width / 6, height / 6);
+ var rect = new SKRect(-length, -length, length, length);
+ var side = rotationMatrix.MapPoint(new SKPoint(1, 0)).X > 0;
+
+ canvas.Clear(SampleMedia.Colors.XamarinLightBlue);
+
+ // first do 2D translation to the center of the screen
+ canvas.Translate(width / 2, height / 2);
+
+ // then apply the 3D rotation
+ canvas.Concat(ref rotationMatrix);
+
+ var paint = new SKPaint
+ {
+ Color = side ? SampleMedia.Colors.XamarinPurple : SampleMedia.Colors.XamarinGreen,
+ Style = SKPaintStyle.Fill,
+ IsAntialias = true
+ };
+
+ canvas.DrawRoundRect(rect, 30, 30, paint);
+
+ var shadow = SKShader.CreateLinearGradient(
+ new SKPoint(0, 0), new SKPoint(0, length * 2),
+ new[] { paint.Color.WithAlpha(127), paint.Color.WithAlpha(0) },
+ null,
+ SKShaderTileMode.Clamp);
+ paint = new SKPaint
+ {
+ Shader = shadow,
+ Style = SKPaintStyle.Fill,
+ IsAntialias = true
+ };
+
+ rect.Offset(0, length * 2 + 5);
+ canvas.DrawRoundRect(rect, 30, 30, paint);
+ }
+ }
+}
diff --git a/samples/SkiaSharpSample.Shared/SkiaSharpSample.Shared.projitems b/samples/SkiaSharpSample.Shared/SkiaSharpSample.Shared.projitems
index 296d35c46..a8d957acb 100644
--- a/samples/SkiaSharpSample.Shared/SkiaSharpSample.Shared.projitems
+++ b/samples/SkiaSharpSample.Shared/SkiaSharpSample.Shared.projitems
@@ -23,6 +23,7 @@
+