feat(rhi): add NoAccess ops, axis conversion, meshlet color
Added NoAccess to attachment ops for depth/stencil, updated D3D12 and RenderGraph to handle new ops, and improved axis/handedness conversion in mesh loading. Enabled meshlet color hashing in test shader. Changed default rasterizer winding, added format helpers, and updated camera transform for correct mesh orientation. JobScheduler usage commented out for now.
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
using Ghost.Core;
|
||||
using Ghost.Graphics.RHI;
|
||||
using Ghost.Graphics.Utilities;
|
||||
using Ghost.MeshOptimizer;
|
||||
using Ghost.Ufbx;
|
||||
using Misaki.HighPerformance.LowLevel;
|
||||
@@ -8,12 +7,14 @@ using Misaki.HighPerformance.LowLevel.Buffer;
|
||||
using Misaki.HighPerformance.LowLevel.Collections;
|
||||
using Misaki.HighPerformance.LowLevel.Utilities;
|
||||
using Misaki.HighPerformance.Mathematics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Ghost.Graphics.Test.Utilities;
|
||||
|
||||
internal static class MeshUtility
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static float4 ComputeTangent(float3 t, float3 n, float3 b)
|
||||
{
|
||||
var proj = n * math.dot(n, t);
|
||||
@@ -22,6 +23,12 @@ internal static class MeshUtility
|
||||
return new float4(t.xyz, w);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static float3 RightHandToLeft(float3 p)
|
||||
{
|
||||
return new float3(p.x, p.y, -p.z);
|
||||
}
|
||||
|
||||
public static unsafe Result LoadMesh(string filePath, Allocator allocator, out UnsafeList<Vertex> vertices, out UnsafeList<uint> indices)
|
||||
{
|
||||
vertices = default;
|
||||
@@ -38,7 +45,25 @@ internal static class MeshUtility
|
||||
return Result.Failure("Unsupported file format. Only .obj and .fbx are supported.");
|
||||
}
|
||||
|
||||
var load_Opts = new ufbx_load_opts();
|
||||
var load_Opts = new ufbx_load_opts
|
||||
{
|
||||
target_axes = new ufbx_coordinate_axes
|
||||
{
|
||||
right = ufbx_coordinate_axis.UFBX_COORDINATE_AXIS_POSITIVE_X,
|
||||
up = ufbx_coordinate_axis.UFBX_COORDINATE_AXIS_POSITIVE_Y,
|
||||
front = ufbx_coordinate_axis.UFBX_COORDINATE_AXIS_POSITIVE_Z
|
||||
},
|
||||
obj_axes = new ufbx_coordinate_axes
|
||||
{
|
||||
right = ufbx_coordinate_axis.UFBX_COORDINATE_AXIS_POSITIVE_X,
|
||||
up = ufbx_coordinate_axis.UFBX_COORDINATE_AXIS_POSITIVE_Y,
|
||||
front = ufbx_coordinate_axis.UFBX_COORDINATE_AXIS_NEGATIVE_Z
|
||||
},
|
||||
// Force X-axis mirroring to correctly convert handedness to Left-Handed,
|
||||
// while preserving correct left/right orientation when viewed from the front.
|
||||
handedness_conversion_axis = ufbx_mirror_axis.UFBX_MIRROR_AXIS_X,
|
||||
space_conversion = ufbx_space_conversion.UFBX_SPACE_CONVERSION_MODIFY_GEOMETRY,
|
||||
};
|
||||
var error = new ufbx_error();
|
||||
|
||||
using var pool = new MemoryPool<VirtualStack, VirtualStack.CreationOpts>(new VirtualStack.CreationOpts
|
||||
@@ -81,7 +106,7 @@ internal static class MeshUtility
|
||||
}
|
||||
|
||||
var maxScratchIndices = (int)(pMesh->max_face_triangles * 3u);
|
||||
|
||||
|
||||
using var triIndicesArray = new UnsafeArray<uint>(maxScratchIndices, scope1.AllocationHandle);
|
||||
|
||||
for (var j = 0u; j < pMesh->num_faces; j++)
|
||||
@@ -95,12 +120,9 @@ internal static class MeshUtility
|
||||
{
|
||||
var ufbxTopologyIndex = triIndicesArray[k];
|
||||
|
||||
// TODO: Check if normals/UVs exist before accessing .flatIndices.data
|
||||
// If it does not exist, we leave uv as (0,0) and compute normals/tangents later
|
||||
|
||||
var posIdx = pMesh->vertex_position.indices.data[ufbxTopologyIndex];
|
||||
var normIdx = pMesh->vertex_normal.exists ? pMesh->vertex_normal.indices.data[ufbxTopologyIndex] : uint.MaxValue;
|
||||
var tanIdx = pMesh->vertex_tangent.exists ? pMesh->vertex_tangent.indices.data[ufbxTopologyIndex] : uint.MaxValue;
|
||||
var tanIdx = pMesh->vertex_tangent.exists ? pMesh->vertex_tangent.indices.data[ufbxTopologyIndex] : uint.MaxValue;
|
||||
var uvIdx = pMesh->vertex_uv.exists ? pMesh->vertex_uv.indices.data[ufbxTopologyIndex] : uint.MaxValue;
|
||||
var colIdx = pMesh->vertex_color.exists ? pMesh->vertex_color.indices.data[ufbxTopologyIndex] : uint.MaxValue;
|
||||
var btanIdx = pMesh->vertex_bitangent.exists ? pMesh->vertex_bitangent.indices.data[ufbxTopologyIndex] : uint.MaxValue;
|
||||
@@ -124,7 +146,6 @@ internal static class MeshUtility
|
||||
var newIndex = (uint)flatVertices.Count;
|
||||
|
||||
flatVertices.Add(vertex);
|
||||
//flatIndices.Add(newIndex);
|
||||
|
||||
if (!needComputeNormals)
|
||||
{
|
||||
|
||||
@@ -5,12 +5,10 @@ using Ghost.Engine.Utilities;
|
||||
using Ghost.Entities;
|
||||
using Ghost.Graphics.Core;
|
||||
using Ghost.Graphics.RHI;
|
||||
using Ghost.Graphics.Test.Utilities;
|
||||
using Ghost.Graphics.Utilities;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using Misaki.HighPerformance.Jobs;
|
||||
using Misaki.HighPerformance.LowLevel.Buffer;
|
||||
using Misaki.HighPerformance.Mathematics;
|
||||
|
||||
@@ -20,7 +18,7 @@ public sealed partial class GraphicsTestWindow : Window
|
||||
{
|
||||
private RenderSystem? _renderSystem;
|
||||
private ISwapChain? _swapChain;
|
||||
private JobScheduler _jobScheduler;
|
||||
//private JobScheduler _jobScheduler;
|
||||
private World? _world;
|
||||
|
||||
private Handle<Mesh> _meshHandle;
|
||||
@@ -36,7 +34,7 @@ public sealed partial class GraphicsTestWindow : Window
|
||||
|
||||
Panel.SizeChanged += SwapChainPanel_SizeChanged;
|
||||
Panel.CompositionScaleChanged += SwapChainPanel_CompositionScaleChanged;
|
||||
|
||||
|
||||
var opts = new AllocationManagerInitOpts
|
||||
{
|
||||
ArenaCapacity = 1024 * 1024 * 1024, // 1GB
|
||||
@@ -46,7 +44,7 @@ public sealed partial class GraphicsTestWindow : Window
|
||||
|
||||
AllocationManager.Initialize(opts);
|
||||
|
||||
_jobScheduler = new JobScheduler(Environment.ProcessorCount - 1);
|
||||
//_jobScheduler = new JobScheduler(Environment.ProcessorCount - 1);
|
||||
}
|
||||
|
||||
private void GraphicsTestWindow_Activated(object sender, WindowActivatedEventArgs e)
|
||||
@@ -79,7 +77,7 @@ public sealed partial class GraphicsTestWindow : Window
|
||||
_renderSystem.Start();
|
||||
|
||||
// ECS Setup
|
||||
_world = World.Create(_jobScheduler);
|
||||
_world = World.Create();
|
||||
_world.AddService(_renderSystem);
|
||||
|
||||
// Add Systems
|
||||
@@ -109,12 +107,12 @@ public sealed partial class GraphicsTestWindow : Window
|
||||
|
||||
_world.EntityManager.SetComponent(cameraEntity, new LocalToWorld
|
||||
{
|
||||
matrix = float4x4.TRS(new float3(0.0f, 1.0f, -5.0f), quaternion.EulerXYZ(new float3(0, 0, 0)), float3.one)
|
||||
matrix = float4x4.TRS(new float3(0.0f, 1.0f, 5.0f), quaternion.EulerXYZ(new float3(0, math.radians(180.0f), 0)), float3.one)
|
||||
});
|
||||
|
||||
// Create Mesh Entity
|
||||
//MeshBuilder.CreateCube(0.75f, default, Allocator.Persistent, out var vertices, out var indices);
|
||||
MeshUtility.LoadMesh("F:/c/SimpleRayTracer/native/assets/bunny.obj", Allocator.Persistent, out var vertices, out var indices).ThrowIfFailed();
|
||||
Utilities.MeshUtility.LoadMesh("F:/c/SimpleRayTracer/native/assets/bunny.obj", Allocator.Persistent, out var vertices, out var indices).ThrowIfFailed();
|
||||
|
||||
// TODO: Put this to the beginning of the frame without createing another command buffer?
|
||||
using var directCmd = _renderSystem.GraphicsEngine.CreateCommandBuffer(CommandBufferType.Graphics);
|
||||
@@ -141,7 +139,7 @@ public sealed partial class GraphicsTestWindow : Window
|
||||
|
||||
_world.EntityManager.SetComponent(meshEntity, new LocalToWorld
|
||||
{
|
||||
matrix = float4x4.identity
|
||||
matrix = float4x4.TRS(float3.zero, quaternion.EulerXYZ(new float3(0, 0, 0)), float3.one)
|
||||
});
|
||||
|
||||
CompositionTarget.Rendering += OnRendering;
|
||||
@@ -162,7 +160,7 @@ public sealed partial class GraphicsTestWindow : Window
|
||||
_renderSystem?.ResourceManager.ReleaseMesh(_meshHandle);
|
||||
|
||||
_swapChain?.Dispose();
|
||||
_jobScheduler.Dispose();
|
||||
//_jobScheduler.Dispose();
|
||||
_renderSystem?.Dispose();
|
||||
|
||||
AllocationManager.Dispose();
|
||||
|
||||
Reference in New Issue
Block a user