dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.41k stars 4.76k forks source link

Matrix4x4.CreateReflection gives incorrect results in .NET 9 #110050

Open ZingBallyhoo opened 15 hours ago

ZingBallyhoo commented 15 hours ago

Description

In .NET 9, using Matrix4x4.CreateReflection with a plane where D != 0 no longer gives correct results, specifically in the last column of the matrix (M14, M24, M34, M44).

Reproduction Steps

using System;
using System.Numerics;

var plane = new Plane(0, 1, 0, 60);
var mtx = Matrix4x4.CreateReflection(plane);
Console.Out.WriteLine(mtx);

Expected behavior

{ {M11:1 M12:0 M13:0 M14:0} {M21:0 M22:-1 M23:0 M24:0} {M31:0 M32:0 M33:1 M34:0} {M41:-0 M42:-120 M43:-0 M44:1} } (net8)

Actual behavior

{ {M11:1 M12:0 M13:0 M14:0} {M21:0 M22:-1 M23:0 M24:-120} {M31:0 M32:0 M33:1 M34:0} {M41:0 M42:-120 M43:0 M44:-7199} } (net9)

Regression?

Yes, the implementation in .NET 8 gave correct results.

Known Workarounds

a. Take the broken result and reset the values in the last column to (0, 0, 0, 1). b. Copy the previous implementation to a local project and use that instead.

Configuration

.NET 9.0.100

Other information

The implemenation was changed in https://github.com/dotnet/runtime/pull/103527 for .NET 9

Before: https://github.com/dotnet/runtime/blame/ab013a35ac6d76320bb6e28a49d62ad82a88e5d6/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.Impl.cs#L720 After: https://github.com/dotnet/runtime/blame/3b91ac601980f3cc35e1d8687e7235e874ffc8ea/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.Impl.cs#L619

The new implementation accidentally multiples plane.D (W of the vec) by -2 via broadcast whereas the reference implemenation from DirectXMath linked in the code multiplies it by 0

dotnet-policy-service[bot] commented 15 hours ago

Tagging subscribers to this area: @dotnet/area-system-numerics See info in area-owners.md if you want to be subscribed.