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
.gitignore
vendored
1
.gitignore
vendored
@@ -13,6 +13,7 @@
|
|||||||
AGENTS.md
|
AGENTS.md
|
||||||
ref/
|
ref/
|
||||||
docfx/
|
docfx/
|
||||||
|
.opencode/
|
||||||
NUL
|
NUL
|
||||||
|
|
||||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||||
|
|||||||
@@ -509,6 +509,7 @@ internal unsafe class D3D12CommandBuffer : D3D12Object<ID3D12GraphicsCommandList
|
|||||||
AttachmentLoadOp.Load => D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE,
|
AttachmentLoadOp.Load => D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE,
|
||||||
AttachmentLoadOp.Clear => D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR,
|
AttachmentLoadOp.Clear => D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR,
|
||||||
AttachmentLoadOp.DontCare => D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_DISCARD,
|
AttachmentLoadOp.DontCare => D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_DISCARD,
|
||||||
|
AttachmentLoadOp.NoAccess => D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS,
|
||||||
_ => D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE
|
_ => D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -517,7 +518,8 @@ internal unsafe class D3D12CommandBuffer : D3D12Object<ID3D12GraphicsCommandList
|
|||||||
{
|
{
|
||||||
AttachmentStoreOp.Store => D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE,
|
AttachmentStoreOp.Store => D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE,
|
||||||
AttachmentStoreOp.DontCare => D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_DISCARD,
|
AttachmentStoreOp.DontCare => D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_DISCARD,
|
||||||
_ => D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE
|
AttachmentStoreOp.NoAccess => D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
|
||||||
|
_ => D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS
|
||||||
};
|
};
|
||||||
|
|
||||||
// Map stencil load operation
|
// Map stencil load operation
|
||||||
@@ -526,6 +528,7 @@ internal unsafe class D3D12CommandBuffer : D3D12Object<ID3D12GraphicsCommandList
|
|||||||
AttachmentLoadOp.Load => D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE,
|
AttachmentLoadOp.Load => D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE,
|
||||||
AttachmentLoadOp.Clear => D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR,
|
AttachmentLoadOp.Clear => D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR,
|
||||||
AttachmentLoadOp.DontCare => D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_DISCARD,
|
AttachmentLoadOp.DontCare => D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_DISCARD,
|
||||||
|
AttachmentLoadOp.NoAccess => D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS,
|
||||||
_ => D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE
|
_ => D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -534,15 +537,10 @@ internal unsafe class D3D12CommandBuffer : D3D12Object<ID3D12GraphicsCommandList
|
|||||||
{
|
{
|
||||||
AttachmentStoreOp.Store => D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE,
|
AttachmentStoreOp.Store => D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE,
|
||||||
AttachmentStoreOp.DontCare => D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_DISCARD,
|
AttachmentStoreOp.DontCare => D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_DISCARD,
|
||||||
_ => D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE
|
AttachmentStoreOp.NoAccess => D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS,
|
||||||
|
_ => D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!depthDesc.HasStencil)
|
|
||||||
{
|
|
||||||
stencilLoadAccessType = D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS;
|
|
||||||
stencilStoreAccessType = D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
var desc = new D3D12_RENDER_PASS_DEPTH_STENCIL_DESC
|
var desc = new D3D12_RENDER_PASS_DEPTH_STENCIL_DESC
|
||||||
{
|
{
|
||||||
cpuDescriptor = cpuHandle,
|
cpuDescriptor = cpuHandle,
|
||||||
|
|||||||
@@ -504,7 +504,7 @@ internal static unsafe class D3D12Utility
|
|||||||
public static D3D12_RASTERIZER_DESC D3D12_RASTERIZER_DESC_CREATE(
|
public static D3D12_RASTERIZER_DESC D3D12_RASTERIZER_DESC_CREATE(
|
||||||
D3D12_FILL_MODE fillMode,
|
D3D12_FILL_MODE fillMode,
|
||||||
D3D12_CULL_MODE cullMode,
|
D3D12_CULL_MODE cullMode,
|
||||||
bool frontCounterClockwise = true,
|
bool frontCounterClockwise = false,
|
||||||
int depthBias = D3D12_DEFAULT_DEPTH_BIAS,
|
int depthBias = D3D12_DEFAULT_DEPTH_BIAS,
|
||||||
float depthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP,
|
float depthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP,
|
||||||
float slopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS,
|
float slopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS,
|
||||||
|
|||||||
@@ -1359,11 +1359,13 @@ public enum AttachmentLoadOp
|
|||||||
{
|
{
|
||||||
Load,
|
Load,
|
||||||
Clear,
|
Clear,
|
||||||
DontCare
|
DontCare,
|
||||||
|
NoAccess
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum AttachmentStoreOp
|
public enum AttachmentStoreOp
|
||||||
{
|
{
|
||||||
Store,
|
Store,
|
||||||
DontCare
|
DontCare,
|
||||||
|
NoAccess
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using Ghost.Core;
|
|||||||
using Ghost.Core.Graphics;
|
using Ghost.Core.Graphics;
|
||||||
using Ghost.Core.Utilities;
|
using Ghost.Core.Utilities;
|
||||||
using System.IO.Hashing;
|
using System.IO.Hashing;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ghost.Graphics.RHI;
|
namespace Ghost.Graphics.RHI;
|
||||||
@@ -10,6 +11,7 @@ public static class RHIUtility
|
|||||||
{
|
{
|
||||||
public const int MAX_RENDER_TARGETS = 8;
|
public const int MAX_RENDER_TARGETS = 8;
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static uint GetBytesPerPixel(this TextureFormat format)
|
public static uint GetBytesPerPixel(this TextureFormat format)
|
||||||
{
|
{
|
||||||
return format switch
|
return format switch
|
||||||
@@ -24,9 +26,16 @@ public static class RHIUtility
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static uint GetTotalBytes(this TextureDesc desc)
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static bool IsDepthStencilFormat(this TextureFormat format)
|
||||||
{
|
{
|
||||||
return desc.Format.GetBytesPerPixel() * desc.Width * desc.Height * desc.Slice;
|
return format == TextureFormat.D24_UNorm_S8_UInt || format == TextureFormat.D32_Float;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static bool IsStencilFormat(this TextureFormat format)
|
||||||
|
{
|
||||||
|
return format == TextureFormat.D24_UNorm_S8_UInt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void GetSurfaceInfo(this TextureFormat format, uint width, uint height, out uint rowPitch, out uint slicePitch, out uint rowCount)
|
public static void GetSurfaceInfo(this TextureFormat format, uint width, uint height, out uint rowPitch, out uint slicePitch, out uint rowCount)
|
||||||
@@ -136,12 +145,14 @@ public static class RHIUtility
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Key64<ShaderPass> CreateShaderPassKey(string passID)
|
public static Key64<ShaderPass> CreateShaderPassKey(string passID)
|
||||||
{
|
{
|
||||||
var passIdSpan = passID.AsSpan();
|
var passIdSpan = passID.AsSpan();
|
||||||
return new Key64<ShaderPass>(XxHash3.HashToUInt64(MemoryMarshal.AsBytes(passIdSpan)));
|
return new Key64<ShaderPass>(XxHash3.HashToUInt64(MemoryMarshal.AsBytes(passIdSpan)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Key64<ShaderVariant> CreateShaderVariantKey(Key64<ShaderPass> passKey, ref readonly LocalKeywordSet keywords)
|
public static Key64<ShaderVariant> CreateShaderVariantKey(Key64<ShaderPass> passKey, ref readonly LocalKeywordSet keywords)
|
||||||
{
|
{
|
||||||
var passHash = passKey.Value;
|
var passHash = passKey.Value;
|
||||||
@@ -176,6 +187,7 @@ public static class RHIUtility
|
|||||||
return new Key128<GraphicsPipeline>(new UInt128(lo, hi));
|
return new Key128<GraphicsPipeline>(new UInt128(lo, hi));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static bool TryGetString(this Key128<GraphicsPipeline> key, Span<char> destination)
|
public static bool TryGetString(this Key128<GraphicsPipeline> key, Span<char> destination)
|
||||||
{
|
{
|
||||||
return key.Value.TryFormat(destination, out var _, "X16");
|
return key.Value.TryFormat(destination, out var _, "X16");
|
||||||
|
|||||||
@@ -294,7 +294,7 @@ internal class RenderGraphBuilder : IRasterRenderGraphBuilder, IComputeRenderGra
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetDepthAttachment(Identifier<RGTexture> texture, AccessFlags flags = AccessFlags.WriteAll)
|
public void SetDepthAttachment(Identifier<RGTexture> texture, AccessFlags flags = AccessFlags.ReadWrite)
|
||||||
{
|
{
|
||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
|
|
||||||
|
|||||||
@@ -139,18 +139,16 @@ internal sealed class RenderGraphExecutor
|
|||||||
ClearStencil = nativePass.depthAttachment.clearStencil,
|
ClearStencil = nativePass.depthAttachment.clearStencil,
|
||||||
DepthLoadOp = nativePass.hasDepthAttachment
|
DepthLoadOp = nativePass.hasDepthAttachment
|
||||||
? nativePass.depthAttachment.loadOp
|
? nativePass.depthAttachment.loadOp
|
||||||
: AttachmentLoadOp.DontCare,
|
: AttachmentLoadOp.NoAccess,
|
||||||
DepthStoreOp = nativePass.hasDepthAttachment
|
DepthStoreOp = nativePass.hasDepthAttachment
|
||||||
? nativePass.depthAttachment.storeOp
|
? nativePass.depthAttachment.storeOp
|
||||||
: AttachmentStoreOp.DontCare,
|
: AttachmentStoreOp.NoAccess,
|
||||||
StencilLoadOp = nativePass.hasDepthAttachment
|
StencilLoadOp = nativePass.hasDepthAttachment
|
||||||
? nativePass.depthAttachment.stencilLoadOp
|
? nativePass.depthAttachment.stencilLoadOp
|
||||||
: AttachmentLoadOp.DontCare,
|
: AttachmentLoadOp.NoAccess,
|
||||||
StencilStoreOp = nativePass.hasDepthAttachment
|
StencilStoreOp = nativePass.hasDepthAttachment
|
||||||
? nativePass.depthAttachment.stencilStoreOp
|
? nativePass.depthAttachment.stencilStoreOp
|
||||||
: AttachmentStoreOp.DontCare,
|
: AttachmentStoreOp.NoAccess,
|
||||||
HasStencil = nativePass.hasDepthAttachment &&
|
|
||||||
(_resources.GetResource(nativePass.depthAttachment.texture).rgTextureDesc.format == TextureFormat.D24_UNorm_S8_UInt)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
commandBuffer.BeginRenderPass(new Span<PassRenderTargetDesc>(pPassRTDescs, nativePass.colorAttachmentCount), depthDesc);
|
commandBuffer.BeginRenderPass(new Span<PassRenderTargetDesc>(pPassRTDescs, nativePass.colorAttachmentCount), depthDesc);
|
||||||
|
|||||||
@@ -365,18 +365,16 @@ internal sealed class RenderGraphNativePassBuilder
|
|||||||
attachment.storeOp = AttachmentStoreOp.Store;
|
attachment.storeOp = AttachmentStoreOp.Store;
|
||||||
}
|
}
|
||||||
|
|
||||||
var hasStencil = resource.rgTextureDesc.format == TextureFormat.D24_UNorm_S8_UInt;
|
if (resource.rgTextureDesc.format.IsStencilFormat())
|
||||||
if (hasStencil)
|
|
||||||
{
|
{
|
||||||
attachment.stencilLoadOp = attachment.loadOp;
|
attachment.stencilLoadOp = attachment.loadOp;
|
||||||
attachment.stencilStoreOp = attachment.storeOp;
|
attachment.stencilStoreOp = attachment.storeOp;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
attachment.stencilLoadOp = AttachmentLoadOp.DontCare;
|
attachment.stencilLoadOp = AttachmentLoadOp.NoAccess;
|
||||||
attachment.stencilStoreOp = AttachmentStoreOp.DontCare;
|
attachment.stencilStoreOp = AttachmentStoreOp.NoAccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,14 +112,14 @@ shader "MyShader/Standard"
|
|||||||
// float4 blendedColor = (color1 + color2 + color3 + color4) * 0.25f;
|
// float4 blendedColor = (color1 + color2 + color3 + color4) * 0.25f;
|
||||||
// return perMaterialData.color * blendedColor + input.color;
|
// return perMaterialData.color * blendedColor + input.color;
|
||||||
|
|
||||||
// uint hash = PCGHash(input.meshletID);
|
uint hash = PCGHash(input.meshletID);
|
||||||
//
|
|
||||||
// float r = float((hash & 0xFF0000u) >> 16) / 255.0;
|
float r = float((hash & 0xFF0000u) >> 16) / 255.0;
|
||||||
// float g = float((hash & 0x00FF00u) >> 8) / 255.0;
|
float g = float((hash & 0x00FF00u) >> 8) / 255.0;
|
||||||
// float b = float((hash & 0x0000FFu)) / 255.0;
|
float b = float((hash & 0x0000FFu)) / 255.0;
|
||||||
//
|
|
||||||
// return float4(r, g, b, 1.0);
|
return float4(r, g, b, 1.0);
|
||||||
return float4(input.normal, 1.0);
|
// return float4(input.normal, 1.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using Ghost.Core;
|
using Ghost.Core;
|
||||||
using Ghost.Graphics.RHI;
|
using Ghost.Graphics.RHI;
|
||||||
using Ghost.Graphics.Utilities;
|
|
||||||
using Ghost.MeshOptimizer;
|
using Ghost.MeshOptimizer;
|
||||||
using Ghost.Ufbx;
|
using Ghost.Ufbx;
|
||||||
using Misaki.HighPerformance.LowLevel;
|
using Misaki.HighPerformance.LowLevel;
|
||||||
@@ -8,12 +7,14 @@ using Misaki.HighPerformance.LowLevel.Buffer;
|
|||||||
using Misaki.HighPerformance.LowLevel.Collections;
|
using Misaki.HighPerformance.LowLevel.Collections;
|
||||||
using Misaki.HighPerformance.LowLevel.Utilities;
|
using Misaki.HighPerformance.LowLevel.Utilities;
|
||||||
using Misaki.HighPerformance.Mathematics;
|
using Misaki.HighPerformance.Mathematics;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Ghost.Graphics.Test.Utilities;
|
namespace Ghost.Graphics.Test.Utilities;
|
||||||
|
|
||||||
internal static class MeshUtility
|
internal static class MeshUtility
|
||||||
{
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private static float4 ComputeTangent(float3 t, float3 n, float3 b)
|
private static float4 ComputeTangent(float3 t, float3 n, float3 b)
|
||||||
{
|
{
|
||||||
var proj = n * math.dot(n, t);
|
var proj = n * math.dot(n, t);
|
||||||
@@ -22,6 +23,12 @@ internal static class MeshUtility
|
|||||||
return new float4(t.xyz, w);
|
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)
|
public static unsafe Result LoadMesh(string filePath, Allocator allocator, out UnsafeList<Vertex> vertices, out UnsafeList<uint> indices)
|
||||||
{
|
{
|
||||||
vertices = default;
|
vertices = default;
|
||||||
@@ -38,7 +45,25 @@ internal static class MeshUtility
|
|||||||
return Result.Failure("Unsupported file format. Only .obj and .fbx are supported.");
|
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();
|
var error = new ufbx_error();
|
||||||
|
|
||||||
using var pool = new MemoryPool<VirtualStack, VirtualStack.CreationOpts>(new VirtualStack.CreationOpts
|
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);
|
var maxScratchIndices = (int)(pMesh->max_face_triangles * 3u);
|
||||||
|
|
||||||
using var triIndicesArray = new UnsafeArray<uint>(maxScratchIndices, scope1.AllocationHandle);
|
using var triIndicesArray = new UnsafeArray<uint>(maxScratchIndices, scope1.AllocationHandle);
|
||||||
|
|
||||||
for (var j = 0u; j < pMesh->num_faces; j++)
|
for (var j = 0u; j < pMesh->num_faces; j++)
|
||||||
@@ -95,12 +120,9 @@ internal static class MeshUtility
|
|||||||
{
|
{
|
||||||
var ufbxTopologyIndex = triIndicesArray[k];
|
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 posIdx = pMesh->vertex_position.indices.data[ufbxTopologyIndex];
|
||||||
var normIdx = pMesh->vertex_normal.exists ? pMesh->vertex_normal.indices.data[ufbxTopologyIndex] : uint.MaxValue;
|
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 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 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;
|
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;
|
var newIndex = (uint)flatVertices.Count;
|
||||||
|
|
||||||
flatVertices.Add(vertex);
|
flatVertices.Add(vertex);
|
||||||
//flatIndices.Add(newIndex);
|
|
||||||
|
|
||||||
if (!needComputeNormals)
|
if (!needComputeNormals)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,12 +5,10 @@ using Ghost.Engine.Utilities;
|
|||||||
using Ghost.Entities;
|
using Ghost.Entities;
|
||||||
using Ghost.Graphics.Core;
|
using Ghost.Graphics.Core;
|
||||||
using Ghost.Graphics.RHI;
|
using Ghost.Graphics.RHI;
|
||||||
using Ghost.Graphics.Test.Utilities;
|
|
||||||
using Ghost.Graphics.Utilities;
|
using Ghost.Graphics.Utilities;
|
||||||
using Microsoft.UI.Xaml;
|
using Microsoft.UI.Xaml;
|
||||||
using Microsoft.UI.Xaml.Controls;
|
using Microsoft.UI.Xaml.Controls;
|
||||||
using Microsoft.UI.Xaml.Media;
|
using Microsoft.UI.Xaml.Media;
|
||||||
using Misaki.HighPerformance.Jobs;
|
|
||||||
using Misaki.HighPerformance.LowLevel.Buffer;
|
using Misaki.HighPerformance.LowLevel.Buffer;
|
||||||
using Misaki.HighPerformance.Mathematics;
|
using Misaki.HighPerformance.Mathematics;
|
||||||
|
|
||||||
@@ -20,7 +18,7 @@ public sealed partial class GraphicsTestWindow : Window
|
|||||||
{
|
{
|
||||||
private RenderSystem? _renderSystem;
|
private RenderSystem? _renderSystem;
|
||||||
private ISwapChain? _swapChain;
|
private ISwapChain? _swapChain;
|
||||||
private JobScheduler _jobScheduler;
|
//private JobScheduler _jobScheduler;
|
||||||
private World? _world;
|
private World? _world;
|
||||||
|
|
||||||
private Handle<Mesh> _meshHandle;
|
private Handle<Mesh> _meshHandle;
|
||||||
@@ -36,7 +34,7 @@ public sealed partial class GraphicsTestWindow : Window
|
|||||||
|
|
||||||
Panel.SizeChanged += SwapChainPanel_SizeChanged;
|
Panel.SizeChanged += SwapChainPanel_SizeChanged;
|
||||||
Panel.CompositionScaleChanged += SwapChainPanel_CompositionScaleChanged;
|
Panel.CompositionScaleChanged += SwapChainPanel_CompositionScaleChanged;
|
||||||
|
|
||||||
var opts = new AllocationManagerInitOpts
|
var opts = new AllocationManagerInitOpts
|
||||||
{
|
{
|
||||||
ArenaCapacity = 1024 * 1024 * 1024, // 1GB
|
ArenaCapacity = 1024 * 1024 * 1024, // 1GB
|
||||||
@@ -46,7 +44,7 @@ public sealed partial class GraphicsTestWindow : Window
|
|||||||
|
|
||||||
AllocationManager.Initialize(opts);
|
AllocationManager.Initialize(opts);
|
||||||
|
|
||||||
_jobScheduler = new JobScheduler(Environment.ProcessorCount - 1);
|
//_jobScheduler = new JobScheduler(Environment.ProcessorCount - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GraphicsTestWindow_Activated(object sender, WindowActivatedEventArgs e)
|
private void GraphicsTestWindow_Activated(object sender, WindowActivatedEventArgs e)
|
||||||
@@ -79,7 +77,7 @@ public sealed partial class GraphicsTestWindow : Window
|
|||||||
_renderSystem.Start();
|
_renderSystem.Start();
|
||||||
|
|
||||||
// ECS Setup
|
// ECS Setup
|
||||||
_world = World.Create(_jobScheduler);
|
_world = World.Create();
|
||||||
_world.AddService(_renderSystem);
|
_world.AddService(_renderSystem);
|
||||||
|
|
||||||
// Add Systems
|
// Add Systems
|
||||||
@@ -109,12 +107,12 @@ public sealed partial class GraphicsTestWindow : Window
|
|||||||
|
|
||||||
_world.EntityManager.SetComponent(cameraEntity, new LocalToWorld
|
_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
|
// Create Mesh Entity
|
||||||
//MeshBuilder.CreateCube(0.75f, default, Allocator.Persistent, out var vertices, out var indices);
|
//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?
|
// TODO: Put this to the beginning of the frame without createing another command buffer?
|
||||||
using var directCmd = _renderSystem.GraphicsEngine.CreateCommandBuffer(CommandBufferType.Graphics);
|
using var directCmd = _renderSystem.GraphicsEngine.CreateCommandBuffer(CommandBufferType.Graphics);
|
||||||
@@ -141,7 +139,7 @@ public sealed partial class GraphicsTestWindow : Window
|
|||||||
|
|
||||||
_world.EntityManager.SetComponent(meshEntity, new LocalToWorld
|
_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;
|
CompositionTarget.Rendering += OnRendering;
|
||||||
@@ -162,7 +160,7 @@ public sealed partial class GraphicsTestWindow : Window
|
|||||||
_renderSystem?.ResourceManager.ReleaseMesh(_meshHandle);
|
_renderSystem?.ResourceManager.ReleaseMesh(_meshHandle);
|
||||||
|
|
||||||
_swapChain?.Dispose();
|
_swapChain?.Dispose();
|
||||||
_jobScheduler.Dispose();
|
//_jobScheduler.Dispose();
|
||||||
_renderSystem?.Dispose();
|
_renderSystem?.Dispose();
|
||||||
|
|
||||||
AllocationManager.Dispose();
|
AllocationManager.Dispose();
|
||||||
|
|||||||
Reference in New Issue
Block a user