Skip to content

Commit d3cbef8

Browse files
committed
Engine: More PBR shader and loading support, working on asset system with ReferenceCount support (WIP)
1 parent 93f764b commit d3cbef8

File tree

17 files changed

+191
-46
lines changed

17 files changed

+191
-46
lines changed

assets/Shaders/PBR.slang

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,13 @@ struct SurfaceInfo
2828
// Material (space 0)
2929
ConstantBuffer<PBRMaterialData> material : register(b0);
3030
Texture2D<float4> baseColorTexture : register(t0);
31-
SamplerState baseColorSampler : register(s0);
31+
Texture2D<float4> normalTexture : register(t1);
32+
SamplerState pbrSampler : register(s0);
3233

3334
[shader("pixel")]
3435
float4 fragmentMain(in VertexOutput input, in bool isFrontFace: SV_IsFrontFace) : SV_TARGET
3536
{
36-
const float4 baseColorMap = baseColorTexture.Sample(baseColorSampler, input.TexCoord0);
37+
const float4 baseColorMap = baseColorTexture.Sample(pbrSampler, input.TexCoord0);
3738

3839
// float4 baseColor = material.baseColorFactor * baseColorTexture.Sample(SamplerLinearClamp, input.TexCoord0);
3940
float4 baseColor = material.baseColorFactor * baseColorMap;
@@ -46,6 +47,18 @@ float4 fragmentMain(in VertexOutput input, in bool isFrontFace: SV_IsFrontFace)
4647

4748
// Should we normalize here?
4849
float3x3 TBN = float3x3(input.Tangent, input.Bitangent, input.Normal);
50+
//[branch]
51+
// if (material.textures[NORMALMAP].IsValid())
52+
{
53+
float3 N = float3(normalTexture.Sample(pbrSampler, input.TexCoord0).rg, 1.f);
54+
N = N * 2.f - 1.f;
55+
//N.rg *= material.GetNormalMapStrength();
56+
surface.N = normalize(mul(N, TBN));
57+
if (!isFrontFace) // MATERIAL_DOUBLE_SIDED?
58+
{
59+
surface.N = -surface.N;
60+
}
61+
}
4962

5063
return baseColor;
5164
}

samples/Alimer.Samples/Engine/ScenePBRRendererSample.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public ScenePBRRendererSample(IServiceRegistry services)
2828
// Camera
2929
_cameraEntity = new();
3030
CameraComponent camera = _cameraEntity.AddComponent<CameraComponent>();
31-
camera.Entity!.Transform.Position = new Vector3(0.0f, 0.0f, 25.0f);
31+
camera.Entity!.Transform.Position = new Vector3(0.0f, 0.0f, 5.0f);
3232
root.Children.Add(_cameraEntity);
3333

3434
// GLTF mesh
@@ -83,7 +83,7 @@ public ScenePBRRendererSample(IServiceRegistry services)
8383
public override void Update(GameTime time)
8484
{
8585
float deltaTime = (float)time.Elapsed.TotalSeconds;
86-
_damagedHelmetEntity.Transform.Rotate(10 * deltaTime, 20 * deltaTime, 30 * deltaTime);
86+
//_damagedHelmetEntity.Transform.Rotate(10 * deltaTime, 20 * deltaTime, 30 * deltaTime);
8787
}
8888

8989
public override void Draw(CommandBuffer context, Texture swapChainTexture)

src/Alimer/Assets/Asset.cs

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,63 @@ namespace Alimer.Assets;
66
/// <summary>
77
/// Base class for Asset.
88
/// </summary>
9-
public abstract class Asset
9+
public abstract class Asset : IAsset
1010
{
11-
/// <summary>
12-
/// Gets or sets the name of the asset.
13-
/// </summary>
14-
public string? Name { get;set; }
11+
private volatile uint _refCount =1;
1512

13+
/// <inheritdoc />
1614
public Guid Id { get; set; } = Guid.NewGuid();
1715

16+
/// <inheritdoc />
17+
public string Name { get; set; } = string.Empty;
18+
19+
/// <inheritdoc/>
20+
public uint ReferenceCount { get { return _refCount; } }
21+
22+
protected Asset()
23+
{
24+
}
25+
26+
/// <inheritdoc cref="IReferencable.AddReference()" />
27+
public virtual uint AddReference()
28+
{
29+
uint newRefCount = Interlocked.Increment(ref _refCount);
30+
if (newRefCount <= 1)
31+
throw new InvalidOperationException("Cannot add a reference for an object already released. AddReference/Release pair must match.");
32+
return newRefCount;
33+
}
34+
35+
/// <inheritdoc cref="IReferencable.Release()" />
36+
public virtual uint Release()
37+
{
38+
uint newRefCount = Interlocked.Decrement(ref _refCount);
39+
if (newRefCount == 0)
40+
{
41+
try
42+
{
43+
Destroy();
44+
}
45+
finally
46+
{
47+
// Reverse back the counter if there are any exceptions in the destroy method
48+
Interlocked.Exchange(ref _refCount, newRefCount + 1);
49+
}
50+
}
51+
else if (newRefCount < 0)
52+
{
53+
throw new InvalidOperationException("Cannot release an object that doesn't have active reference. AddReference/Release pair must match.");
54+
}
55+
56+
return newRefCount;
57+
}
58+
1859
public override string ToString()
1960
{
2061
return $"{GetType().Name}: {Id}";
2162
}
63+
64+
/// <summary>
65+
/// Releases unmanaged and - optionally - managed resources
66+
/// </summary>
67+
protected abstract void Destroy();
2268
}

src/Alimer/Assets/IAsset.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright (c) Amer Koleci and Contributors.
2+
// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information.
3+
4+
namespace Alimer.Assets;
5+
6+
/// <summary>
7+
/// Base intefface for Asset.
8+
/// </summary>
9+
public interface IAsset : IReferencable
10+
{
11+
/// <summary>
12+
/// Gets the unique identifier for this asset.
13+
/// </summary>
14+
Guid Id { get; }
15+
16+
/// <summary>
17+
/// Gets the asset name.
18+
/// </summary>
19+
string Name { get; }
20+
}

src/Alimer/Assets/Image.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,8 @@ private Image(in ImageDescription description, ReadOnlySpan<byte> source)
125125
/// <inheritdoc/>
126126
public void Dispose()
127127
{
128-
if (_data != null)
129-
{
130-
NativeMemory.Free(_data);
131-
}
128+
Destroy();
129+
GC.SuppressFinalize(this);
132130
}
133131

134132
/// <summary>
@@ -287,6 +285,15 @@ public static unsafe Image FromMemory(Span<byte> data, int channels = 4, bool sr
287285
}
288286
}
289287

288+
/// <inheritdoc/>
289+
protected override void Destroy()
290+
{
291+
if (_data != null)
292+
{
293+
NativeMemory.Free(_data);
294+
}
295+
}
296+
290297
private static void SetupImageArray(byte* pixels, nuint memorySize, in ImageDescription description, ImageData[] levels)
291298
{
292299
Debug.Assert(pixels != null);

src/Alimer/DisposableObject.cs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,6 @@
66

77
namespace Alimer;
88

9-
/// <summary>
10-
/// Base interface for a <see cref="IDisposable"/> interface.
11-
/// </summary>
12-
public interface IDisposableObject : IDisposable
13-
{
14-
/// <summary>
15-
/// Gets <c>true</c> if the object has been disposed; otherwise, <c>false</c>.
16-
/// </summary>
17-
bool IsDisposed { get; }
18-
}
19-
209
/// <summary>
2110
/// Base class for a <see cref="IDisposable"/> interface.
2211
/// </summary>

src/Alimer/IDisposableObject.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright (c) Amer Koleci and Contributors.
2+
// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information.
3+
4+
namespace Alimer;
5+
6+
/// <summary>
7+
/// Base interface for a <see cref="IDisposable"/> interface.
8+
/// </summary>
9+
public interface IDisposableObject : IDisposable
10+
{
11+
/// <summary>
12+
/// Gets <c>true</c> if the object has been disposed; otherwise, <c>false</c>.
13+
/// </summary>
14+
bool IsDisposed { get; }
15+
}

src/Alimer/IReferencable.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright (c) Amer Koleci and Contributors.
2+
// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information.
3+
4+
namespace Alimer;
5+
6+
/// <summary>
7+
/// Base interface for all objects that use reference-counting lifetime management.
8+
/// </summary>
9+
public interface IReferencable
10+
{
11+
/// <summary>
12+
/// Gets the reference count of this instance.
13+
/// </summary>
14+
/// <value>The reference count.</value>
15+
uint ReferenceCount { get; }
16+
17+
/// <summary>
18+
/// Increments the reference count of this instance.
19+
/// </summary>
20+
/// <returns>The new reference count.</returns>
21+
uint AddReference();
22+
23+
/// <summary>
24+
/// Decrements the reference count of this instance.
25+
/// </summary>
26+
/// <returns>The new reference count.</returns>
27+
/// <remarks>
28+
/// When the reference count reaches 0, the component should release / dispose dependent objects.
29+
/// </remarks>
30+
uint Release();
31+
}

src/Alimer/Rendering/Material.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,6 @@ public void Dispose()
4343
/// <param name="disposing"><c>true</c> if the method was called from <see cref="Dispose()" />; otherwise, <c>false</c>.</param>
4444
protected virtual void Dispose(bool disposing)
4545
{
46+
Destroy();
4647
}
4748
}

src/Alimer/Rendering/Materials/PhysicallyBasedMaterialFactory.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ protected override BindGroupLayout CreateBindGroupLayout()
2323
new BindGroupLayoutEntry(new BufferBindingLayout(BufferBindingType.Constant), 0, ShaderStages.Fragment),
2424
new BindGroupLayoutEntry(new TextureBindingLayout(), 0, ShaderStages.Fragment), // baseColorTexture
2525
new BindGroupLayoutEntry(new SamplerBindingLayout(SamplerBindingType.Filtering), 0), // baseColorSampler
26+
new BindGroupLayoutEntry(new TextureBindingLayout(), 1, ShaderStages.Fragment), // normalTexture
2627
// Static samplers
2728
new BindGroupLayoutEntry(SamplerDescriptor.PointClamp, 100, ShaderStages.All), // SamplerPointClamp
2829
new BindGroupLayoutEntry(SamplerDescriptor.PointWrap, 101, ShaderStages.All), // SamplerPointWrap
@@ -62,7 +63,8 @@ protected override BindGroup CreateBindGroup(Material material)
6263

6364
BindGroup bindGroup = _bindGroupLayout.CreateBindGroup(
6465
new BindGroupEntry(0, _materialBuffer),
65-
new BindGroupEntry(0, pbrMaterial.BaseColorTexture ?? System.CheckerTexture),
66+
new BindGroupEntry(0, pbrMaterial.BaseColorTexture ?? System.OpaqueWhiteTexture),
67+
new BindGroupEntry(0, pbrMaterial.NormalTexture ?? System.DefaultNormalTexture),
6668
new BindGroupEntry(0, System.DefaultSampler)
6769
);
6870

0 commit comments

Comments
 (0)